'use client';

import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
  DialogDescription
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import ImagePicker from '../../components/image-picker';
import { PostMediaData } from '@/lib/database';
import { Controller, useForm, useFieldArray } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import z from 'zod';
import { useEffect } from 'react';
import { toast } from 'sonner';
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectTrigger,
  SelectValue
} from '@/components/ui/select';
import { WidgetPosition } from '@/config/enums/tip-tap';
import Image from 'next/image';
import { Label } from '@/components/ui/label';
import { X } from 'lucide-react';
import type { JSONContent } from '@tiptap/react';
import TiptapEditor from '../../editor/tiptap-editor';

const schema = z.object({
  variant: z.nativeEnum(WidgetPosition),
  media: z.array(z.custom<PostMediaData>()),
  label: z.string(),
  title: z.string(),
  description: z.custom<JSONContent>()
});

type InlineImageForm = z.infer<typeof schema>;

const options = [
  {
    label: 'Default',
    value: WidgetPosition.CENTER
  },
  {
    label: 'Left column',
    value: WidgetPosition.LEFT_COL
  }
];
const defaultValues: InlineImageForm = {
  variant: WidgetPosition.CENTER,
  media: [],
  label: 'Fakta',
  title: '',
  description: {}
};

type Props = {
  open: boolean;
  onOpenChange: (v: boolean) => void;
  initialValues?: InlineImageForm;
  onSubmit: (data: InlineImageForm) => void;
  title: string;
};

export function FactDialog({
  open,
  onOpenChange,
  initialValues,
  onSubmit,
  title
}: Props) {
  const { control, reset, handleSubmit, getValues, register } =
    useForm<InlineImageForm>({
      resolver: zodResolver(schema),
      defaultValues: initialValues ?? defaultValues
    });

  const { fields, replace, remove } = useFieldArray({
    control,
    name: 'media',
    keyName: 'fieldId'
  });

  const handleSelect = (items: PostMediaData[]) => {
    const mediaValues = getValues('media') ?? [];
    const currentMap = new Map(mediaValues.map((m) => [m.id, m]));

    const merged = items.map((item) => {
      const existing = currentMap.get(item.id);
      return {
        ...item,
        alt: existing?.alt ?? item.alt ?? ''
      };
    });

    replace(merged);
  };

  useEffect(() => {
    if (open) {
      reset(initialValues ?? defaultValues);
    }
  }, [open, initialValues, reset]);

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>{title}</DialogTitle>
          <DialogDescription>Configure fact widget</DialogDescription>
        </DialogHeader>

        <div className='flex max-h-[70vh] flex-col gap-4 overflow-y-auto'>
          <Controller
            control={control}
            name='variant'
            render={({ field }) => (
              <Select value={field.value} onValueChange={field.onChange}>
                <SelectTrigger>
                  <SelectValue placeholder='Select variant' />
                </SelectTrigger>
                <SelectContent>
                  <SelectGroup>
                    {options.map((option) => (
                      <SelectItem key={option.value} value={option.value}>
                        {option.label}
                      </SelectItem>
                    ))}
                  </SelectGroup>
                </SelectContent>
              </Select>
            )}
          />

          <Input
            className='shrink-0'
            placeholder='Label'
            {...register('label')}
          />

          <Input
            className='shrink-0'
            placeholder='Title'
            {...register('title')}
          />

          <div className='rounded-lg border p-3'>
            <ImagePicker
              ids={fields.map((m) => m.id)}
              onSelect={handleSelect}
              hiddenExtraUploadFields={{
                scope: true,
                author: true,
                caption: true
              }}
            />
          </div>

          {fields.map((media, index) => {
            const altId = `media-${media.id}-alt`;

            return (
              <div
                key={media.fieldId}
                className='relative flex gap-4 rounded-lg border p-4'
              >
                <button
                  onClick={() => remove(index)}
                  type='button'
                  className='text-client-red absolute top-2 right-3 transition hover:scale-120'
                  title='Settings'
                >
                  <X className='size-4' />
                </button>
                <Image
                  src={media.url}
                  alt={media.alt || 'Selected image'}
                  className='aspect-3/2 size-auto max-w-32 rounded object-cover'
                  width={1000}
                  height={600}
                />

                <div className='flex w-full flex-col gap-2'>
                  <div className='flex flex-col gap-1'>
                    <Label htmlFor={altId}>Alt text</Label>
                    <Controller
                      control={control}
                      name={`media.${index}.alt`}
                      render={({ field }) => (
                        <Input
                          {...field}
                          id={altId}
                          value={field.value ?? ''}
                        />
                      )}
                    />
                  </div>
                </div>
              </div>
            );
          })}
          <Controller
            control={control}
            name='description'
            render={({ field }) => (
              <TiptapEditor
                content={field.value}
                onChange={field.onChange}
                className='min-h-full overflow-auto rounded-md border [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden'
                hideWidgets
              />
            )}
          />
        </div>

        <DialogFooter>
          <Button
            type='button'
            variant='outline'
            onClick={() => {
              onOpenChange(false);
              reset(defaultValues);
            }}
          >
            Cancel
          </Button>

          <Button
            type='button'
            onClick={handleSubmit(onSubmit, () => {
              toast.error('Please choose image(s)');
            })}
          >
            Save
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
