import { useEffect, useRef, useState } from 'react'
import { useForm, useWatch } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { useMutation } from '@tanstack/react-query'
import {
  ArrowLeft,
  ImagePlus,
  Loader2,
  Plus,
  X,
} from 'lucide-react'
import { toast } from 'sonner'
import { apiOrigin } from '@/lib/api/client'
import type { AdminCategoryRecord } from '@/lib/api/types'
import { uploadImage } from '@/lib/api/upload'
import { handleServerError } from '@/lib/handle-server-error'
import { Button } from '@/components/ui/button'
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from '@/components/ui/card'
import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '@/components/ui/form'
import { Input } from '@/components/ui/input'
import { Switch } from '@/components/ui/switch'
import { Textarea } from '@/components/ui/textarea'
import { RichTextEditor } from '@/components/rich-text-editor'
import {
  categoryFormSchema,
  categoryPreviewHeight,
  categoryPreviewWidth,
  composeCategoryDescription,
  getCategoryFormDefaults,
  getSeoCounter,
  metaDescriptionMaxLength,
  metaDescriptionMinLength,
  metaTitleMaxLength,
  metaTitleMinLength,
  slugifyCategoryName,
} from '../helpers'
import type { CategoryFormInput, CategoryFormValues } from '../helpers'

function SeoCharacterHint({
  length,
  min,
  max,
}: {
  length: number
  min: number
  max: number
}) {
  const counter = getSeoCounter(length, min, max)

  return (
    <div className='mt-2 flex items-center justify-between gap-3 text-xs'>
      <span
        className={
          counter.tone === 'good'
            ? 'font-medium text-emerald-700'
            : counter.tone === 'danger'
              ? 'font-medium text-rose-700'
              : 'font-medium text-amber-700'
        }
      >
        {counter.text}
      </span>
      <span
        className={
          counter.tone === 'good'
            ? 'rounded-full bg-emerald-100 px-2 py-1 font-semibold text-emerald-800'
            : counter.tone === 'danger'
              ? 'rounded-full bg-rose-100 px-2 py-1 font-semibold text-rose-800'
              : 'rounded-full bg-amber-100 px-2 py-1 font-semibold text-amber-800'
        }
      >
        {length} karakter
      </span>
    </div>
  )
}

function ImageUploadField({
  value,
  onChange,
  previewUrl,
  pendingFileName,
  isSaving,
  onFileSelect,
  onClearSelection,
}: {
  value: string
  onChange: (value: string) => void
  previewUrl: string | null
  pendingFileName: string | null
  isSaving: boolean
  onFileSelect: (file: File) => void
  onClearSelection: () => void
}) {
  const inputRef = useRef<HTMLInputElement | null>(null)

  return (
    <div className='space-y-4 rounded-3xl border border-border/70 bg-card p-5 shadow-sm'>
      <div className='space-y-1'>
        <p className='text-sm font-semibold'>Kapak görseli</p>
        <p className='text-sm text-muted-foreground'>
          JPG, PNG, GIF, SVG veya WEBP
        </p>
      </div>

      <input
        ref={inputRef}
        type='file'
        accept='image/png,image/jpeg,image/jpg,image/gif,image/svg+xml,image/webp'
        className='hidden'
        onChange={(event) => {
          const file = event.target.files?.[0]

          if (file) {
            onFileSelect(file)
          }

          event.currentTarget.value = ''
        }}
      />

      <div className='space-y-3'>
        <div className='relative mx-auto w-fit'>
          <button
            type='button'
            onClick={() => inputRef.current?.click()}
            disabled={isSaving}
            className='group relative block overflow-hidden rounded-3xl border border-dashed border-border/70 bg-muted/20 transition hover:border-primary/40 disabled:pointer-events-none disabled:opacity-60'
          >
            {previewUrl ? (
              <>
                <img
                  src={previewUrl}
                  alt='Kategori görsel önizleme'
                  className='h-[260px] w-[300px] bg-background object-contain transition group-hover:scale-[1.02]'
                />
                <div className='absolute inset-0 bg-black/0 transition group-hover:bg-black/10' />
              </>
            ) : (
              <div className='flex h-[260px] w-[300px] flex-col items-center justify-center gap-3 text-muted-foreground transition group-hover:text-foreground'>
                <div className='rounded-full border border-border/70 bg-background p-3'>
                  <ImagePlus className='size-5' />
                </div>
                <div className='space-y-1 text-center'>
                  <p className='text-sm font-medium'>Görsel seç</p>
                  <p className='text-xs text-muted-foreground'>
                    {categoryPreviewWidth} x {categoryPreviewHeight} onizleme
                  </p>
                </div>
              </div>
            )}
          </button>

          <div className='absolute top-3 right-3 flex gap-2'>
            <Button
              type='button'
              size='icon'
              className='size-9 rounded-full bg-background/95 text-foreground shadow-sm backdrop-blur hover:bg-background'
              onClick={() => inputRef.current?.click()}
              disabled={isSaving}
            >
              <ImagePlus className='size-4' />
            </Button>
            <Button
              type='button'
              variant='outline'
              size='icon'
              className='size-9 rounded-full bg-background/95 shadow-sm backdrop-blur'
              onClick={() => {
                onChange('')
                onClearSelection()
              }}
              disabled={(!value && !pendingFileName) || isSaving}
            >
              <X className='size-4' />
            </Button>
          </div>
        </div>

        {pendingFileName ? (
          <div className='rounded-2xl border border-sky-200 bg-sky-50 px-3 py-2 text-center text-sm text-sky-900'>
            <span className='font-medium'>{pendingFileName}</span> secildi.
          </div>
        ) : (
          <p className='text-center text-xs text-muted-foreground'>
            Onizleme uzerine tiklayarak gorsel secebilirsiniz.
          </p>
        )}
      </div>
    </div>
  )
}

function BulletListField({
  label,
  description,
  value,
  onChange,
  placeholder,
}: {
  label: string
  description: string
  value: string[]
  onChange: (value: string[]) => void
  placeholder: string
}) {
  const [draft, setDraft] = useState('')

  const addItem = () => {
    const nextValue = draft.trim()

    if (!nextValue) {
      return
    }

    onChange([...value, nextValue])
    setDraft('')
  }

  return (
    <div className='space-y-3 rounded-3xl border border-border/70 bg-card p-4 shadow-sm'>
      <div className='space-y-1'>
        <p className='text-sm font-medium'>{label}</p>
        <p className='text-sm text-muted-foreground'>{description}</p>
      </div>

      <div className='flex gap-2'>
        <Input
          value={draft}
          onChange={(event) => setDraft(event.target.value)}
          onKeyDown={(event) => {
            if (event.key === 'Enter') {
              event.preventDefault()
              addItem()
            }
          }}
          placeholder={placeholder}
        />
        <Button type='button' onClick={addItem} className='rounded-xl'>
          <Plus />
          Ekle
        </Button>
      </div>

      <div className='rounded-2xl border border-dashed border-border/70 bg-muted/10 p-4'>
        {value.length ? (
          <ul className='space-y-2'>
            {value.map((item, index) => (
              <li
                key={`${label}-${index}-${item}`}
                className='flex items-start justify-between gap-3 rounded-2xl border border-border/60 bg-muted/20 px-3 py-2 text-sm'
              >
                <div className='flex items-start gap-2'>
                  <span className='mt-1 size-2 rounded-full bg-primary' />
                  <span>{item}</span>
                </div>
                <Button
                  type='button'
                  variant='ghost'
                  size='icon'
                  className='size-8 rounded-lg text-muted-foreground'
                  onClick={() =>
                    onChange(
                      value.filter((_, currentIndex) => currentIndex !== index)
                    )
                  }
                >
                  <X className='size-4' />
                </Button>
              </li>
            ))}
          </ul>
        ) : (
          <p className='text-sm text-muted-foreground'>
            Eklenen maddeler burada madde işaretli liste olarak görünecek.
          </p>
        )}
      </div>
    </div>
  )
}

export function CategoryEditorPage({
  category,
  isPending,
  onCancel,
  onSubmit,
}: {
  category: AdminCategoryRecord | null
  isPending: boolean
  onCancel: () => void
  onSubmit: (values: CategoryFormValues) => Promise<void>
}) {
  const form = useForm<CategoryFormInput, undefined, CategoryFormValues>({
    resolver: zodResolver(categoryFormSchema),
    defaultValues: getCategoryFormDefaults(category),
  })
  const [selectedImage, setSelectedImage] = useState<{
    file: File | null
    previewUrl: string | null
  }>({
    file: null,
    previewUrl: null,
  })

  const imageValue = useWatch({
    control: form.control,
    name: 'image',
  })
  const nameValue = useWatch({
    control: form.control,
    name: 'name',
  })

  const imageUploadMutation = useMutation({
    mutationFn: uploadImage,
    onError: handleServerError,
  })

  useEffect(() => {
    return () => {
      if (selectedImage.previewUrl) {
        URL.revokeObjectURL(selectedImage.previewUrl)
      }
    }
  }, [selectedImage.previewUrl])

  useEffect(() => {
    const nextSlug = slugifyCategoryName(nameValue ?? '')

    if (form.getValues('slug') !== nextSlug) {
      form.setValue('slug', nextSlug, {
        shouldDirty: true,
        shouldTouch: true,
      })
    }
  }, [form, nameValue])

  const previewUrl = selectedImage.previewUrl
    ? selectedImage.previewUrl
    : imageValue
      ? imageValue.startsWith('http')
        ? imageValue
        : `${apiOrigin}/${imageValue.replace(/^\/+/, '')}`
      : null

  const handleSelectImage = (file: File) => {
    setSelectedImage((current) => {
      if (current.previewUrl) {
        URL.revokeObjectURL(current.previewUrl)
      }

      return {
        file,
        previewUrl: URL.createObjectURL(file),
      }
    })
  }

  const clearSelectedImage = () => {
    setSelectedImage((current) => {
      if (current.previewUrl) {
        URL.revokeObjectURL(current.previewUrl)
      }

      return {
        file: null,
        previewUrl: null,
      }
    })
  }

  return (
    <Card className='border-border/70 shadow-sm'>
      <CardHeader className='border-b border-border/70 bg-muted/20 px-5 py-4'>
        <div className='flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between'>
          <div className='space-y-1'>
            <CardTitle>
              {category ? 'Kategoriyi düzenle' : 'Yeni kategori oluştur'}
            </CardTitle>
            <CardDescription>
              Eğitim kategori kartları ve üst filtre akışı bu bilgilerle
              beslenir.
            </CardDescription>
          </div>
          <Button
            type='button'
            variant='ghost'
            size='sm'
            className='h-8 rounded-lg px-2 text-muted-foreground sm:shrink-0'
            onClick={onCancel}
          >
            <ArrowLeft />
            Listeye dön
          </Button>
        </div>
      </CardHeader>
      <CardContent className='p-4 md:p-5'>
        <Form {...form}>
          <form
            onSubmit={form.handleSubmit(async (values) => {
              let nextImage = values.image ?? ''

              if (selectedImage.file) {
                const uploadResult = await imageUploadMutation.mutateAsync(
                  selectedImage.file
                )
                nextImage = uploadResult.path
                form.setValue('image', nextImage, {
                  shouldDirty: true,
                  shouldTouch: true,
                })
              }

              await onSubmit({
                ...values,
                image: nextImage,
                description: composeCategoryDescription({
                  overviewHtml: values.description ?? '',
                  includes: values.includes,
                  requirements: values.requirements,
                  scope: values.scope,
                }),
              })

              if (selectedImage.file) {
                toast.success('Görsel ve kategori başarıyla kaydedildi.')
                clearSelectedImage()
              }
            })}
            className='space-y-4'
          >
            <div className='grid gap-4 xl:grid-cols-[340px_minmax(0,1fr)]'>
              <FormField
                control={form.control}
                name='image'
                render={({ field }) => (
                  <FormItem>
                    <FormControl>
                      <ImageUploadField
                        value={field.value ?? ''}
                        onChange={field.onChange}
                        previewUrl={previewUrl}
                        pendingFileName={selectedImage.file?.name ?? null}
                        isSaving={isPending || imageUploadMutation.isPending}
                        onFileSelect={handleSelectImage}
                        onClearSelection={clearSelectedImage}
                      />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />

              <div className='rounded-3xl border border-border/70 bg-card p-4 shadow-sm'>
                <div className='mb-3 flex items-center justify-between gap-3 border-b border-border/70 pb-3'>
                  <div>
                    <p className='text-sm font-semibold'>Temel bilgiler</p>
                    <p className='text-sm text-muted-foreground'>
                      Kategori kimliği ve görünürlük ayarları
                    </p>
                  </div>
                </div>

                <div className='space-y-3'>
                  <FormField
                    control={form.control}
                    name='name'
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Kategori adı</FormLabel>
                        <FormControl>
                          <Input
                            {...field}
                            placeholder='Örnek: Makine Eğitimleri'
                          />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                  <FormField
                    control={form.control}
                    name='slug'
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Slug</FormLabel>
                        <FormControl>
                          <Input
                            {...field}
                            readOnly
                            placeholder='makine-egitimleri'
                            className='bg-muted/30 text-muted-foreground'
                          />
                        </FormControl>
                        <FormDescription>
                          Slug kategori adına göre otomatik oluşturulur.
                        </FormDescription>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                  <div>
                    <FormField
                      control={form.control}
                      name='isActive'
                      render={({ field }) => (
                        <FormItem className='flex min-h-full items-center justify-between rounded-2xl border border-border/70 px-4 py-2.5'>
                          <div>
                            <FormLabel>Aktif</FormLabel>
                            <p className='text-sm text-muted-foreground'>
                              Pasif kategoriler ön yüzde gösterilmez.
                            </p>
                          </div>
                          <FormControl>
                            <Switch
                              checked={field.value}
                              onCheckedChange={field.onChange}
                            />
                          </FormControl>
                        </FormItem>
                      )}
                    />
                  </div>
                </div>
              </div>
            </div>

            <div className='rounded-3xl border border-border/70 bg-card p-4 shadow-sm'>
              <div className='mb-3 border-b border-border/70 pb-3'>
                <p className='text-sm font-semibold'>Detay açıklama editörü</p>
                <p className='text-sm text-muted-foreground'>
                  Kategori sayfasındaki ana içerik alanı
                </p>
              </div>
              <FormField
                control={form.control}
                name='description'
                render={({ field }) => (
                  <FormItem>
                    <FormControl>
                      <RichTextEditor
                        value={field.value ?? ''}
                        onChange={field.onChange}
                        placeholder='Kategori için SEO uyumlu giriş metni, başlıklar ve kısa açıklamalar ekleyin.'
                      />
                    </FormControl>
                    <FormMessage />
                  </FormItem>
                )}
              />
            </div>

            <div className='rounded-3xl border border-border/70 bg-card p-4 shadow-sm'>
              <div className='mb-3 border-b border-border/70 pb-3'>
                <p className='text-sm font-semibold'>Liste alanları</p>
                <p className='text-sm text-muted-foreground'>
                  Kısa maddeler halinde ek içerikler
                </p>
              </div>
              <div className='grid gap-3 xl:grid-cols-3'>
                <FormField
                  control={form.control}
                  name='includes'
                  render={({ field }) => (
                    <FormItem>
                      <FormControl>
                        <BulletListField
                          label='Fiyata dahil olanlar'
                          description='Eklediğiniz her madde alt tarafta otomatik olarak işaretli liste şeklinde görünür.'
                          value={field.value ?? []}
                          onChange={field.onChange}
                          placeholder='Örnek: Basılı eğitim dokümanı'
                        />
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />

                <FormField
                  control={form.control}
                  name='requirements'
                  render={({ field }) => (
                    <FormItem>
                      <FormControl>
                        <BulletListField
                          label='Gereksinimler'
                          description='Katılımcı şartlarını veya ön hazırlıkları madde madde ekleyin.'
                          value={field.value ?? []}
                          onChange={field.onChange}
                          placeholder='Örnek: Temel denizcilik belgesi'
                        />
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />

                <FormField
                  control={form.control}
                  name='scope'
                  render={({ field }) => (
                    <FormItem>
                      <FormControl>
                        <BulletListField
                          label='Kapsam'
                          description='Kategori kapsamındaki ana konu başlıklarını kısa maddeler halinde girin.'
                          value={field.value ?? []}
                          onChange={field.onChange}
                          placeholder='Örnek: Gemide güvenlik prosedürleri'
                        />
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />
              </div>
            </div>

            <div className='rounded-3xl border border-border/70 bg-card p-4 shadow-sm'>
              <div className='mb-3 border-b border-border/70 pb-3'>
                <p className='text-sm font-semibold'>SEO alanları</p>
                <p className='text-sm text-muted-foreground'>
                  Arama sonuçlarında görünecek başlık ve açıklama
                </p>
              </div>
              <div className='space-y-3'>
                <FormField
                  control={form.control}
                  name='metaTitle'
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>Meta title</FormLabel>
                      <FormControl>
                        <Input
                          {...field}
                          value={field.value ?? ''}
                          maxLength={metaTitleMaxLength}
                          placeholder='SEO başlığı'
                        />
                      </FormControl>
                      <FormDescription>
                        Arama sonuçlarında ideal görünüm için{' '}
                        {metaTitleMinLength}-{metaTitleMaxLength} karakter
                        hedefleyin.
                      </FormDescription>
                      <SeoCharacterHint
                        length={(field.value ?? '').trim().length}
                        min={metaTitleMinLength}
                        max={metaTitleMaxLength}
                      />
                      <FormMessage />
                    </FormItem>
                  )}
                />
                <FormField
                  control={form.control}
                  name='metaDescription'
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>Meta description</FormLabel>
                      <FormControl>
                        <Textarea
                          {...field}
                          value={field.value ?? ''}
                          maxLength={metaDescriptionMaxLength}
                          rows={4}
                          placeholder='SEO açıklaması'
                        />
                      </FormControl>
                      <FormDescription>
                        {metaDescriptionMinLength}-{metaDescriptionMaxLength}{' '}
                        karakter aralığı tıklanma oranı için genelde daha
                        uygundur.
                      </FormDescription>
                      <SeoCharacterHint
                        length={(field.value ?? '').trim().length}
                        min={metaDescriptionMinLength}
                        max={metaDescriptionMaxLength}
                      />
                      <FormMessage />
                    </FormItem>
                  )}
                />
              </div>
            </div>

            <div className='flex flex-wrap justify-end gap-3 border-t border-border/70 pt-4'>
              <Button type='button' variant='outline' onClick={onCancel}>
                Vazgeç
              </Button>
              <Button
                type='submit'
                className='rounded-xl'
                disabled={isPending || imageUploadMutation.isPending}
              >
                {(isPending || imageUploadMutation.isPending) && (
                  <Loader2 className='animate-spin' />
                )}
                {category ? 'Kaydet' : 'Kategori oluştur'}
              </Button>
            </div>
          </form>
        </Form>
      </CardContent>
    </Card>
  )
}
