import { startTransition, useEffect, useState } from 'react'
import { z } from 'zod'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import {
  ArrowLeft,
  ChevronLeft,
  ChevronRight,
  FilterX,
  Loader2,
  PencilLine,
  Plus,
  RefreshCw,
  Trash2,
} from 'lucide-react'
import { toast } from 'sonner'
import { createMenu, deleteMenu, fetchMenus, updateMenu } from '@/lib/api/menus'
import type { AdminMenuRecord } from '@/lib/api/types'
import { handleServerError } from '@/lib/handle-server-error'
import { getPageNumbers } from '@/lib/utils'
import { Badge } from '@/components/ui/badge'
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 {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import { Switch } from '@/components/ui/switch'
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table'
import { ConfirmDialog } from '@/components/confirm-dialog'
import { Main } from '@/components/layout/main'
import { MenusHeader } from './components/menus-header'

const perPage = 20

const locationLabels: Record<string, string> = {
  header_main: 'Header Ana Menü',
  footer_corporate: 'Footer Kurumsal',
  footer_education: 'Footer Eğitim',
  footer_quicklinks: 'Footer Hızlı Linkler',
}

const typeLabels: Record<string, string> = {
  link: 'Normal Link',
  mega_menu_education: 'Mega Menü (Eğitim)',
  mega_menu_calendar: 'Mega Menü (Takvim)',
}

const menuFormSchema = z.object({
  label: z.string().min(1, 'Etiket zorunludur'),
  url: z.string().min(1, 'URL zorunludur'),
  location: z.string().min(1, 'Lokasyon seçiniz'),
  type: z.string().default('link'),
  parentId: z.string().optional(),
  orderIndex: z.coerce.number().min(0).default(0),
  isActive: z.boolean().default(true),
})

type MenuFormInput = z.input<typeof menuFormSchema>
type MenuFormValues = z.output<typeof menuFormSchema>

function MenuEditorPage({
  menu,
  allMenus,
  isPending,
  onCancel,
  onSubmit,
}: {
  menu: AdminMenuRecord | null
  allMenus: AdminMenuRecord[]
  isPending: boolean
  onCancel: () => void
  onSubmit: (values: MenuFormValues) => Promise<void>
}) {
  const form = useForm<MenuFormInput, undefined, MenuFormValues>({
    resolver: zodResolver(menuFormSchema),
    defaultValues: {
      label: menu?.label ?? '',
      url: menu?.url ?? '',
      location: menu?.location ?? 'header_main',
      type: menu?.type ?? 'link',
      parentId: menu?.parentId ? String(menu.parentId) : '',
      orderIndex: menu?.orderIndex ?? 0,
      isActive: menu?.isActive ?? true,
    } satisfies MenuFormInput,
  })

  useEffect(() => {
    form.reset({
      label: menu?.label ?? '',
      url: menu?.url ?? '',
      location: menu?.location ?? 'header_main',
      type: menu?.type ?? 'link',
      parentId: menu?.parentId ? String(menu.parentId) : '',
      orderIndex: menu?.orderIndex ?? 0,
      isActive: menu?.isActive ?? true,
    })
  }, [form, menu])

  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>
              {menu ? 'Menüyü düzenle' : 'Yeni menü oluştur'}
            </CardTitle>
            <CardDescription>
              Header ve footer navigasyon öğeleri.
            </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) => {
              await onSubmit(values)
            })}
            className='space-y-4'
          >
            <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'>Temel bilgiler</p>
                <p className='text-sm text-muted-foreground'>
                  Menü etiketi, URL ve lokasyon ayarları
                </p>
              </div>
              <div className='space-y-3'>
                <div className='grid gap-3 md:grid-cols-2'>
                  <FormField
                    control={form.control}
                    name='label'
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Etiket</FormLabel>
                        <FormControl>
                          <Input
                            {...field}
                            placeholder='Menüde gözükecek metin'
                          />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                  <FormField
                    control={form.control}
                    name='url'
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>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='location'
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Lokasyon</FormLabel>
                        <Select
                          value={field.value}
                          onValueChange={field.onChange}
                        >
                          <FormControl>
                            <SelectTrigger className='w-full'>
                              <SelectValue />
                            </SelectTrigger>
                          </FormControl>
                          <SelectContent>
                            {Object.entries(locationLabels).map(
                              ([value, label]) => (
                                <SelectItem key={value} value={value}>
                                  {label}
                                </SelectItem>
                              )
                            )}
                          </SelectContent>
                        </Select>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                  <FormField
                    control={form.control}
                    name='type'
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Tip</FormLabel>
                        <Select
                          value={field.value}
                          onValueChange={field.onChange}
                        >
                          <FormControl>
                            <SelectTrigger className='w-full'>
                              <SelectValue />
                            </SelectTrigger>
                          </FormControl>
                          <SelectContent>
                            {Object.entries(typeLabels).map(
                              ([value, label]) => (
                                <SelectItem key={value} value={value}>
                                  {label}
                                </SelectItem>
                              )
                            )}
                          </SelectContent>
                        </Select>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                </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'>Hiyerarşi & Görünürlük</p>
                <p className='text-sm text-muted-foreground'>
                  Üst menü, sıralama ve aktiflik durumu
                </p>
              </div>
              <div className='space-y-3'>
                <div className='grid gap-3 md:grid-cols-2'>
                  <FormField
                    control={form.control}
                    name='parentId'
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Üst menü (opsiyonel)</FormLabel>
                        <Select
                          value={field.value || 'none'}
                          onValueChange={(value) =>
                            field.onChange(value === 'none' ? '' : value)
                          }
                        >
                          <FormControl>
                            <SelectTrigger className='w-full'>
                              <SelectValue placeholder='Üst menü yok' />
                            </SelectTrigger>
                          </FormControl>
                          <SelectContent>
                            <SelectItem value='none'>Üst menü yok</SelectItem>
                            {allMenus
                              .filter((m) => m.id !== menu?.id)
                              .map((m) => (
                                <SelectItem key={m.id} value={String(m.id)}>
                                  {m.label}
                                </SelectItem>
                              ))}
                          </SelectContent>
                        </Select>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                  <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>
                    )}
                  />
                </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'>
                          Menü öğesi sitede görünür olur.
                        </p>
                      </div>
                      <FormControl>
                        <Switch
                          checked={field.value}
                          onCheckedChange={field.onChange}
                        />
                      </FormControl>
                    </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}>
                {isPending && <Loader2 className='animate-spin' />}
                {menu ? 'Kaydet' : 'Menü oluştur'}
              </Button>
            </div>
          </form>
        </Form>
      </CardContent>
    </Card>
  )
}

export function MenusPage() {
  const queryClient = useQueryClient()
  const [page, setPage] = useState(1)
  const [locationFilter, setLocationFilter] = useState('all')
  const [editorOpen, setEditorOpen] = useState(false)
  const [activeMenu, setActiveMenu] = useState<AdminMenuRecord | null>(null)
  const [menuToDelete, setMenuToDelete] = useState<AdminMenuRecord | null>(null)

  const menusQuery = useQuery({
    queryKey: ['menus', page, locationFilter],
    queryFn: () =>
      fetchMenus({
        page,
        perPage,
        location: locationFilter === 'all' ? undefined : locationFilter,
      }),
  })

  const upsertMutation = useMutation({
    mutationFn: async (values: MenuFormValues) => {
      const payload = {
        label: values.label,
        url: values.url,
        location: values.location,
        type: values.type,
        parent_id: values.parentId ? Number(values.parentId) : null,
        order_index: values.orderIndex,
        is_active: values.isActive,
      }

      if (activeMenu) {
        return updateMenu(activeMenu.id, payload)
      }
      return createMenu(payload)
    },
    onSuccess: async () => {
      toast.success('Menü öğesi kaydedildi')
      await queryClient.invalidateQueries({ queryKey: ['menus'] })
      setEditorOpen(false)
      setActiveMenu(null)
    },
    onError: handleServerError,
  })

  const deleteMutation = useMutation({
    mutationFn: async (id: number | string) => deleteMenu(id),
    onSuccess: async () => {
      toast.success('Menü öğesi silindi')
      await queryClient.invalidateQueries({ queryKey: ['menus'] })
      setMenuToDelete(null)
    },
    onError: handleServerError,
  })

  const pageNumbers = getPageNumbers(page, menusQuery.data?.meta.lastPage ?? 1)

  return (
    <>
      <MenusHeader />

      <Main className='space-y-6'>
        {editorOpen ? (
          <MenuEditorPage
            menu={activeMenu}
            allMenus={menusQuery.data?.items ?? []}
            isPending={upsertMutation.isPending}
            onCancel={() => {
              setEditorOpen(false)
              setActiveMenu(null)
            }}
            onSubmit={async (values) => {
              await upsertMutation.mutateAsync(values)
            }}
          />
        ) : (
          <Card>
            <CardHeader className='gap-4'>
              <div className='flex flex-col gap-4 xl:flex-row xl:items-start xl:justify-between'>
                <div>
                  <CardTitle>Menüler</CardTitle>
                  <CardDescription>
                    Header ve footer navigasyon yönetimi.
                  </CardDescription>
                </div>
                <div className='flex flex-wrap gap-2'>
                  <Button
                    variant='outline'
                    className='rounded-xl'
                    onClick={() => menusQuery.refetch()}
                  >
                    <RefreshCw
                      className={menusQuery.isFetching ? 'animate-spin' : ''}
                    />
                    Yenile
                  </Button>
                  <Button
                    className='rounded-xl'
                    onClick={() => {
                      setActiveMenu(null)
                      setEditorOpen(true)
                    }}
                  >
                    <Plus />
                    Ekle
                  </Button>
                </div>
              </div>

              <div className='rounded-2xl border border-dashed border-border/70 bg-muted/20 p-4'>
                <div className='grid gap-3 md:grid-cols-[220px_auto]'>
                  <Select
                    value={locationFilter}
                    onValueChange={(value) =>
                      startTransition(() => {
                        setLocationFilter(value)
                        setPage(1)
                      })
                    }
                  >
                    <SelectTrigger className='w-full'>
                      <SelectValue placeholder='Tüm lokasyonlar' />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value='all'>Tüm lokasyonlar</SelectItem>
                      {Object.entries(locationLabels).map(([value, label]) => (
                        <SelectItem key={value} value={value}>
                          {label}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                  <div className='flex items-end justify-end'>
                    <Button
                      variant='outline'
                      className='rounded-xl'
                      onClick={() => {
                        setLocationFilter('all')
                        setPage(1)
                      }}
                      disabled={locationFilter === 'all'}
                    >
                      <FilterX />
                      Temizle
                    </Button>
                  </div>
                </div>
              </div>
            </CardHeader>
            <CardContent className='space-y-4'>
              <div className='rounded-2xl border border-border/70'>
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead className='px-4'>Etiket</TableHead>
                      <TableHead>URL</TableHead>
                      <TableHead>Lokasyon</TableHead>
                      <TableHead>Tip</TableHead>
                      <TableHead>Sıra</TableHead>
                      <TableHead>Durum</TableHead>
                      <TableHead className='w-[180px] text-right'>
                        İşlemler
                      </TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {menusQuery.isLoading ? (
                      <TableRow>
                        <TableCell
                          colSpan={7}
                          className='h-28 text-center text-muted-foreground'
                        >
                          <Loader2 className='mx-auto mb-2 size-5 animate-spin' />
                          Yükleniyor...
                        </TableCell>
                      </TableRow>
                    ) : menusQuery.data?.items.length ? (
                      menusQuery.data.items.map((item) => (
                        <TableRow key={item.id}>
                          <TableCell className='px-4 py-4 font-medium'>
                            {item.parentId ? '\u2514 ' : ''}
                            {item.label}
                          </TableCell>
                          <TableCell className='text-sm text-muted-foreground'>
                            {item.url}
                          </TableCell>
                          <TableCell>
                            <Badge variant='outline' className='rounded-full'>
                              {locationLabels[item.location] ?? item.location}
                            </Badge>
                          </TableCell>
                          <TableCell className='text-sm'>
                            {typeLabels[item.type] ?? item.type}
                          </TableCell>
                          <TableCell>{item.orderIndex}</TableCell>
                          <TableCell>
                            <Badge
                              variant={item.isActive ? 'default' : 'secondary'}
                              className='rounded-full'
                            >
                              {item.isActive ? 'Aktif' : 'Pasif'}
                            </Badge>
                          </TableCell>
                          <TableCell>
                            <div className='flex justify-end gap-2'>
                              <Button
                                variant='outline'
                                size='sm'
                                className='rounded-xl'
                                onClick={() => {
                                  setActiveMenu(item)
                                  setEditorOpen(true)
                                }}
                              >
                                <PencilLine />
                                Düzenle
                              </Button>
                              <Button
                                variant='destructive'
                                size='sm'
                                className='rounded-xl'
                                onClick={() => setMenuToDelete(item)}
                              >
                                <Trash2 />
                                Sil
                              </Button>
                            </div>
                          </TableCell>
                        </TableRow>
                      ))
                    ) : (
                      <TableRow>
                        <TableCell
                          colSpan={7}
                          className='h-28 text-center text-muted-foreground'
                        >
                          Menü bulunamadı.
                        </TableCell>
                      </TableRow>
                    )}
                  </TableBody>
                </Table>
              </div>

              <div className='flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between'>
                <p className='text-sm text-muted-foreground'>
                  Toplam {menusQuery.data?.meta.total ?? 0} kayıt. Sayfa {page}{' '}
                  / {menusQuery.data?.meta.lastPage ?? 1}
                </p>
                <div className='flex flex-wrap items-center gap-2'>
                  <Button
                    variant='outline'
                    size='sm'
                    onClick={() =>
                      startTransition(() => setPage((c) => Math.max(1, c - 1)))
                    }
                    disabled={page === 1}
                  >
                    <ChevronLeft />
                  </Button>
                  {pageNumbers.map((item, index) =>
                    item === '...' ? (
                      <span
                        key={`${item}-${index}`}
                        className='px-2 text-sm text-muted-foreground'
                      >
                        ...
                      </span>
                    ) : (
                      <Button
                        key={item}
                        size='sm'
                        variant={item === page ? 'default' : 'outline'}
                        onClick={() =>
                          startTransition(() => setPage(Number(item)))
                        }
                      >
                        {item}
                      </Button>
                    )
                  )}
                  <Button
                    variant='outline'
                    size='sm'
                    onClick={() =>
                      startTransition(() =>
                        setPage((c) =>
                          Math.min(menusQuery.data?.meta.lastPage ?? 1, c + 1)
                        )
                      )
                    }
                    disabled={page === (menusQuery.data?.meta.lastPage ?? 1)}
                  >
                    <ChevronRight />
                  </Button>
                </div>
              </div>
            </CardContent>
          </Card>
        )}
      </Main>

      <ConfirmDialog
        open={!!menuToDelete}
        onOpenChange={(open) => {
          if (!open) setMenuToDelete(null)
        }}
        title='Menüyü silmek istediğinize emin misiniz?'
        desc={`"${menuToDelete?.label ?? ''}" kalıcı olarak silinecek.`}
        confirmText='Evet, sil'
        cancelBtnText='İptal'
        destructive
        isLoading={deleteMutation.isPending}
        handleConfirm={() => {
          if (menuToDelete) {
            deleteMutation.mutate(menuToDelete.id)
          }
        }}
      />
    </>
  )
}
