import { startTransition, useEffect, useState } from 'react'
import { z } from 'zod'
import { useForm, useWatch } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { useMutation } from '@tanstack/react-query'
import { ArrowLeft, Loader2 } from 'lucide-react'
import { toast } from 'sonner'
import { apiOrigin } from '@/lib/api/client'
import type { AdminHeroSlideRecord } from '@/lib/api/types'
import { uploadImage, uploadVideo } 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,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '@/components/ui/form'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import { Switch } from '@/components/ui/switch'
import { Textarea } from '@/components/ui/textarea'
import { ImageUploadField } from '@/components/image-upload-field'
import { VideoUploadField } from '@/components/video-upload-field'

export const heroSlideFormSchema = z.object({
  title: z.string().min(2, 'Başlık en az 2 karakter olmalıdır'),
  subtitle: z.string().optional(),
  label: z.string().optional(),
  description: z.string().optional(),
  buttonText: z.string().optional(),
  buttonUrl: z.string().optional(),
  mediaType: z.enum(['image', 'video']).default('image'),
  image: z.string().optional(),
  mobileImage: z.string().optional(),
  videoUrl: z.string().optional(),
  mobileVideoUrl: z.string().optional(),
  orderIndex: z.coerce.number().min(0).default(0),
  isActive: z.boolean().default(true),
})

export type HeroSlideFormInput = z.input<typeof heroSlideFormSchema>
export type HeroSlideFormValues = z.output<typeof heroSlideFormSchema>

function buildPreviewUrl(value: string | undefined | null) {
  if (!value) return null
  if (value.startsWith('http')) return value
  const cleanPath = value.replace(/^\/+/, '').replace(/^storage\//, '')
  return `${apiOrigin}/${cleanPath}`
}

export function HeroSlideForm({
  slide,
  isPending,
  onCancel,
  onSubmit,
}: {
  slide: AdminHeroSlideRecord | null
  isPending: boolean
  onCancel: () => void
  onSubmit: (values: HeroSlideFormValues) => Promise<void>
}) {
  const form = useForm<HeroSlideFormInput, undefined, HeroSlideFormValues>({
    resolver: zodResolver(heroSlideFormSchema),
    defaultValues: {
      title: slide?.title ?? '',
      subtitle: slide?.subtitle ?? '',
      label: slide?.label ?? '',
      description: slide?.description ?? '',
      buttonText: slide?.buttonText ?? '',
      buttonUrl: slide?.buttonUrl ?? '',
      mediaType: slide?.mediaType ?? 'image',
      image: slide?.image ?? '',
      mobileImage: slide?.mobileImage ?? '',
      videoUrl: slide?.videoUrl ?? '',
      mobileVideoUrl: slide?.mobileVideoUrl ?? '',
      orderIndex: slide?.orderIndex ?? 0,
      isActive: slide?.isActive ?? true,
    } satisfies HeroSlideFormInput,
  })

  const [selectedImage, setSelectedImage] = useState<{
    file: File | null
    previewUrl: string | null
  }>({ file: null, previewUrl: null })

  const [selectedMobileImage, setSelectedMobileImage] = useState<{
    file: File | null
    previewUrl: string | null
  }>({ file: null, previewUrl: null })

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

  const [selectedVideo, setSelectedVideo] = useState<{
    file: File | null
  }>({ file: null })
  const [selectedMobileVideo, setSelectedMobileVideo] = useState<{
    file: File | null
  }>({ file: null })
  const [videoUploadProgress, setVideoUploadProgress] = useState(0)
  const [mobileVideoUploadProgress, setMobileVideoUploadProgress] = useState(0)

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

  const videoUploadMutation = useMutation({
    mutationFn: (file: File) => uploadVideo(file, setVideoUploadProgress),
    onError: handleServerError,
  })

  const mobileVideoUploadMutation = useMutation({
    mutationFn: (file: File) => uploadVideo(file, setMobileVideoUploadProgress),
    onError: handleServerError,
  })

  useEffect(() => {
    form.reset({
      title: slide?.title ?? '',
      subtitle: slide?.subtitle ?? '',
      label: slide?.label ?? '',
      description: slide?.description ?? '',
      buttonText: slide?.buttonText ?? '',
      buttonUrl: slide?.buttonUrl ?? '',
      mediaType: slide?.mediaType ?? 'image',
      image: slide?.image ?? '',
      mobileImage: slide?.mobileImage ?? '',
      videoUrl: slide?.videoUrl ?? '',
      mobileVideoUrl: slide?.mobileVideoUrl ?? '',
      orderIndex: slide?.orderIndex ?? 0,
      isActive: slide?.isActive ?? true,
    })
    startTransition(() => {
      setSelectedImage({ file: null, previewUrl: null })
      setSelectedMobileImage({ file: null, previewUrl: null })
      setSelectedVideo({ file: null })
      setSelectedMobileVideo({ file: null })
      setVideoUploadProgress(0)
      setMobileVideoUploadProgress(0)
    })
  }, [form, slide])

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

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

  const previewUrl = selectedImage.previewUrl
    ? selectedImage.previewUrl
    : buildPreviewUrl(imageValue)

  const mobilePreviewUrl = selectedMobileImage.previewUrl
    ? selectedMobileImage.previewUrl
    : buildPreviewUrl(mobileImageValue)

  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>
              {slide ? 'Slaytı düzenle' : 'Yeni slayt oluştur'}
            </CardTitle>
            <CardDescription>
              Ana sayfa hero slider içeriklerini yönetin.
            </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 ?? ''
              let nextMobileImage = values.mobileImage ?? ''
              let nextVideoUrl = values.videoUrl ?? ''
              let nextMobileVideoUrl = values.mobileVideoUrl ?? ''

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

              if (selectedMobileImage.file) {
                const uploadResult = await imageUploadMutation.mutateAsync(
                  selectedMobileImage.file
                )
                nextMobileImage = uploadResult.path
                form.setValue('mobileImage', nextMobileImage, {
                  shouldDirty: true,
                  shouldTouch: true,
                })
              }

              if (selectedVideo.file) {
                setVideoUploadProgress(0)
                const uploadResult = await videoUploadMutation.mutateAsync(
                  selectedVideo.file
                )
                nextVideoUrl = uploadResult.path
                form.setValue('videoUrl', nextVideoUrl, {
                  shouldDirty: true,
                  shouldTouch: true,
                })
              }

              if (selectedMobileVideo.file) {
                setMobileVideoUploadProgress(0)
                const uploadResult = await mobileVideoUploadMutation.mutateAsync(
                  selectedMobileVideo.file
                )
                nextMobileVideoUrl = uploadResult.path
                form.setValue('mobileVideoUrl', nextMobileVideoUrl, {
                  shouldDirty: true,
                  shouldTouch: true,
                })
              }

              await onSubmit({
                ...values,
                image: nextImage,
                mobileImage: nextMobileImage,
                videoUrl: nextVideoUrl,
                mobileVideoUrl: nextMobileVideoUrl,
              })

              const anyFileUploaded = selectedImage.file || selectedMobileImage.file || selectedVideo.file || selectedMobileVideo.file
              if (anyFileUploaded) {
                toast.success('Dosyalar ve slayt başarıyla kaydedildi.')
                setSelectedImage({ file: null, previewUrl: null })
                setSelectedMobileImage({ file: null, previewUrl: null })
                setSelectedVideo({ file: null })
                setSelectedMobileVideo({ file: null })
                setVideoUploadProgress(0)
                setMobileVideoUploadProgress(0)
              }
            })}
            className='space-y-4'
          >
            <div className='grid gap-4 xl:grid-cols-[340px_minmax(0,1fr)]'>
              <div className='space-y-4'>
                {mediaType === 'image' ? (
                  <>
                    <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}
                              label='Kapak görseli'
                              onFileSelect={(file) => {
                                setSelectedImage((current) => {
                                  if (current.previewUrl)
                                    URL.revokeObjectURL(current.previewUrl)
                                  return {
                                    file,
                                    previewUrl: URL.createObjectURL(file),
                                  }
                                })
                              }}
                              onClearSelection={() => {
                                setSelectedImage((current) => {
                                  if (current.previewUrl)
                                    URL.revokeObjectURL(current.previewUrl)
                                  return { file: null, previewUrl: null }
                                })
                              }}
                            />
                          </FormControl>
                          <FormMessage />
                        </FormItem>
                      )}
                    />

                    <FormField
                      control={form.control}
                      name='mobileImage'
                      render={({ field }) => (
                        <FormItem>
                          <FormControl>
                            <ImageUploadField
                              value={field.value ?? ''}
                              onChange={field.onChange}
                              previewUrl={mobilePreviewUrl}
                              pendingFileName={
                                selectedMobileImage.file?.name ?? null
                              }
                              isSaving={isPending || imageUploadMutation.isPending}
                              label='Mobil görsel'
                              onFileSelect={(file) => {
                                setSelectedMobileImage((current) => {
                                  if (current.previewUrl)
                                    URL.revokeObjectURL(current.previewUrl)
                                  return {
                                    file,
                                    previewUrl: URL.createObjectURL(file),
                                  }
                                })
                              }}
                              onClearSelection={() => {
                                setSelectedMobileImage((current) => {
                                  if (current.previewUrl)
                                    URL.revokeObjectURL(current.previewUrl)
                                  return { file: null, previewUrl: null }
                                })
                              }}
                            />
                          </FormControl>
                          <FormMessage />
                        </FormItem>
                      )}
                    />
                  </>
                ) : (
                  <>
                    <FormField
                      control={form.control}
                      name='videoUrl'
                      render={({ field }) => (
                        <FormItem>
                          <FormControl>
                            <VideoUploadField
                              value={field.value ?? ''}
                              onChange={field.onChange}
                              pendingFileName={selectedVideo.file?.name ?? null}
                              isSaving={isPending || videoUploadMutation.isPending}
                              uploadProgress={videoUploadProgress}
                              label='Masaüstü video'
                              onFileSelect={(file) => {
                                setSelectedVideo({ file })
                              }}
                              onClearSelection={() => {
                                setSelectedVideo({ file: null })
                                setVideoUploadProgress(0)
                              }}
                            />
                          </FormControl>
                          <FormMessage />
                        </FormItem>
                      )}
                    />

                    <FormField
                      control={form.control}
                      name='mobileVideoUrl'
                      render={({ field }) => (
                        <FormItem>
                          <FormControl>
                            <VideoUploadField
                              value={field.value ?? ''}
                              onChange={field.onChange}
                              pendingFileName={selectedMobileVideo.file?.name ?? null}
                              isSaving={isPending || mobileVideoUploadMutation.isPending}
                              uploadProgress={mobileVideoUploadProgress}
                              label='Mobil video'
                              onFileSelect={(file) => {
                                setSelectedMobileVideo({ file })
                              }}
                              onClearSelection={() => {
                                setSelectedMobileVideo({ file: null })
                                setMobileVideoUploadProgress(0)
                              }}
                            />
                          </FormControl>
                          <FormMessage />
                        </FormItem>
                      )}
                    />
                  </>
                )}
              </div>

              <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'>
                      Slayt başlığı ve içerik ayarları
                    </p>
                  </div>
                </div>

                <div className='space-y-3'>
                  <FormField
                    control={form.control}
                    name='mediaType'
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Medya tipi</FormLabel>
                        <FormControl>
                          <RadioGroup
                            value={field.value}
                            onValueChange={field.onChange}
                            className='flex gap-4'
                          >
                            <div className='flex items-center gap-2'>
                              <RadioGroupItem value='image' id='media-image' />
                              <Label htmlFor='media-image'>Görsel</Label>
                            </div>
                            <div className='flex items-center gap-2'>
                              <RadioGroupItem value='video' id='media-video' />
                              <Label htmlFor='media-video'>Video</Label>
                            </div>
                          </RadioGroup>
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />

                  <FormField
                    control={form.control}
                    name='label'
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Etiket</FormLabel>
                        <FormControl>
                          <Input
                            {...field}
                            placeholder='Başlık üstü rozet metni'
                          />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />

                  <FormField
                    control={form.control}
                    name='title'
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Başlık</FormLabel>
                        <FormControl>
                          <Input {...field} placeholder='Slider başlığı' />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                  <FormField
                    control={form.control}
                    name='subtitle'
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Alt başlık</FormLabel>
                        <FormControl>
                          <Textarea
                            {...field}
                            rows={3}
                            placeholder='Alt metin'
                          />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                  <FormField
                    control={form.control}
                    name='description'
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Açıklama</FormLabel>
                        <FormControl>
                          <Textarea
                            {...field}
                            rows={3}
                            placeholder='Slayt açıklama metni'
                          />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                  <div className='grid gap-3 md:grid-cols-2'>
                    <FormField
                      control={form.control}
                      name='buttonText'
                      render={({ field }) => (
                        <FormItem>
                          <FormLabel>Buton metni</FormLabel>
                          <FormControl>
                            <Input {...field} placeholder='Detaylı bilgi' />
                          </FormControl>
                          <FormMessage />
                        </FormItem>
                      )}
                    />
                    <FormField
                      control={form.control}
                      name='buttonUrl'
                      render={({ field }) => (
                        <FormItem>
                          <FormLabel>Buton URL</FormLabel>
                          <FormControl>
                            <Input {...field} placeholder='/egitimler' />
                          </FormControl>
                          <FormMessage />
                        </FormItem>
                      )}
                    />
                  </div>
                  <div className='grid gap-3 md:grid-cols-2'>
                    <FormField
                      control={form.control}
                      name='orderIndex'
                      render={({ field }) => (
                        <FormItem>
                          <FormLabel>Sıralama</FormLabel>
                          <FormControl>
                            <Input
                              name={field.name}
                              ref={field.ref}
                              onBlur={field.onBlur}
                              disabled={field.disabled}
                              type='number'
                              min={0}
                              value={String(field.value ?? 0)}
                              onChange={(event) =>
                                field.onChange(event.target.value)
                              }
                            />
                          </FormControl>
                          <FormMessage />
                        </FormItem>
                      )}
                    />
                    <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'>
                              Slayt sitede görünür olur.
                            </p>
                          </div>
                          <FormControl>
                            <Switch
                              checked={field.value}
                              onCheckedChange={field.onChange}
                            />
                          </FormControl>
                        </FormItem>
                      )}
                    />
                  </div>
                </div>
              </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 || videoUploadMutation.isPending || mobileVideoUploadMutation.isPending}
              >
                {(isPending || imageUploadMutation.isPending || videoUploadMutation.isPending || mobileVideoUploadMutation.isPending) && (
                  <Loader2 className='animate-spin' />
                )}
                {slide ? 'Kaydet' : 'Slayt oluştur'}
              </Button>
            </div>
          </form>
        </Form>
      </CardContent>
    </Card>
  )
}
