import React, { useCallback, PropsWithChildren } from 'react';
import { XIcon, Circle, LucideCheckCircle, FileTextIcon } from 'lucide-react';
import Image from 'next/image';
import { useFormContext, useFieldArray } from 'react-hook-form';
import { useFormGroupName } from 'react-compose-form';
import { InputField } from '@/components/form/field/input.field';
import { PostPicker } from '@/components/dashboard/post/post-picker';
import { Button } from '@/components/ui/button';
import { api } from '@/lib/trpc/client';
import { PostType } from "@/config/enums/topic";

type PostCollectionProps = PropsWithChildren<{
  label?: string;
  name: string;
  type?: PostType;
  field?: 'postId' | 'projectId';
  preview?: string;
}>;

export const PostCollection: React.FC<PostCollectionProps> = (props) => {
  const {
    label,
    preview: previewName,
    type,
    name,
    field: fieldName = 'postId'
  } = props;

  const { watch, setValue } = useFormContext();

  const previewId = previewName ? watch(previewName) : '';
  const fullName = useFormGroupName(name);

  const { append, remove, fields } = useFieldArray<{
    [key: typeof fullName]: { postId?: string; projectId?: string }[];
  }>({
    name: fullName
  });

  const ids: string[] = fields
    .map((field) => field[fieldName])
    .filter((id): id is string => !!id);

  const { data: posts = [] } = api.posts.list.useQuery(
    {
      access: 'dashboard',
      ids
    },
    {
      enabled: ids.length > 0
    }
  );

  const handleSelect = useCallback(
    (ids: string[]) => {
      for (const id of ids) {
        const field = fields.find((field) => field[fieldName] === id);

        if (!field) {
          append({
            [fieldName]: id
          });
        }
      }
    },
    [fields, fieldName, append]
  );

  const handlePrimary = useCallback(
    (id: string) => {
      if (!previewName) {
        return;
      }

      setValue(previewName, id);
    },
    [previewName, setValue]
  );

  return (
    <React.Fragment>
      {label && (
        <label className='mb-2 block text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70'>
          {label}
        </label>
      )}

      <div className='flex flex-wrap gap-4'>
        {fields.map((field, index) => {
          const post = posts.find((post) => post.id === field[fieldName]);

          return (
            <div
              key={field.id}
              className='relative flex h-[125px] w-[125px] flex-col items-center justify-center overflow-hidden rounded-md border p-2'
            >
              <InputField type='hidden' name={fieldName} />

              {post && (
                <React.Fragment>
                  <div className='bg-muted relative mb-1 size-16 overflow-hidden rounded'>
                    {post.preview?.url ? (
                      <Image
                        className='object-cover'
                        fill
                        alt={post.title}
                        src={post.preview.url}
                      />
                    ) : (
                      <div className='flex size-full items-center justify-center'>
                        <FileTextIcon className='text-muted-foreground size-8' />
                      </div>
                    )}
                  </div>

                  <div className='label-text line-clamp-2 px-1 text-center font-medium'>
                    {post.title}
                  </div>
                </React.Fragment>
              )}

              {!post && (
                <div className='text-muted-foreground label-text'>
                  Loading...
                </div>
              )}

              {previewName && (
                <Button
                  type='button'
                  className='absolute top-1 left-1 size-6'
                  size='icon'
                  variant={
                    field[fieldName] === previewId ? 'default' : 'outline'
                  }
                  onClick={() => handlePrimary(field[fieldName]!)}
                >
                  {field[fieldName] === previewId && (
                    <LucideCheckCircle className='size-4' />
                  )}
                  {field[fieldName] !== previewId && (
                    <Circle className='size-4' />
                  )}
                </Button>
              )}

              <Button
                type='button'
                className='absolute top-1 right-1 size-6'
                size='icon'
                variant='destructive'
                onClick={() => remove(index)}
              >
                <XIcon className='size-4' />
              </Button>
            </div>
          );
        })}

        <div className='flex h-[125px] w-[125px] items-center justify-center overflow-hidden rounded-md border border-dashed border-black'>
          <PostPicker
            multiple
            type={type}
            selected={ids}
            onSelect={handleSelect} />
        </div>
      </div>

      {previewName && <InputField type='hidden' name={previewName} />}
    </React.Fragment>
  );
};
