import { zodResolver } from '@hookform/resolvers/zod'
import { type ColumnDef } from '@tanstack/react-table'
import { Pencil, Plus, Trash2 } from 'lucide-react'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { useForm } from 'react-hook-form'
import { z } from 'zod'

import { DataTable } from '@/components/data-table/data-table'
import { DataTableToolbar } from '@/components/data-table/data-table-toolbar'
import { Button } from '@/components/ui/button'
import { Form, FormControl, FormDescription, 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 { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from '@/components/ui/sheet'
import { useToast } from '@/components/ui/use-toast'
import { useContactsQuery, useCreateContactMutation, useDeleteContactMutation, useUpdateContactMutation } from '@/features/contacts/hooks'
import { useDebounce } from '@/hooks/use-debounce'
import { formatDate } from '@/lib/utils'
import type { Contact } from '@/types/crm'

const contactFormSchema = z.object({
  name: z.string().min(2, 'Имя не короче двух символов'),
  email: z.string().email('Некорректный email').or(z.literal('')).optional(),
  phone: z.string().min(6, 'Телефон слишком короткий').or(z.literal('')).optional(),
  ownerId: z.string().optional(),
})

interface ContactFormValues extends z.infer<typeof contactFormSchema> {}

const defaultValues: ContactFormValues = {
  name: '',
  email: '',
  phone: '',
  ownerId: '',
}

const ContactsPage = () => {
  const [search, setSearch] = useState('')
  const [ownerFilter, setOwnerFilter] = useState('all')
  const [drawerOpen, setDrawerOpen] = useState(false)
  const [editingContact, setEditingContact] = useState<Contact | null>(null)
  const debouncedSearch = useDebounce(search, 400)
  const ownerIdFilter = ownerFilter === 'all' ? undefined : Number(ownerFilter)
  const { data: contacts = [], isLoading } = useContactsQuery({
    search: debouncedSearch.trim() || undefined,
    ownerId: Number.isFinite(ownerIdFilter) ? ownerIdFilter : undefined,
  })
  const createContact = useCreateContactMutation()
  const updateContact = useUpdateContactMutation()
  const deleteContact = useDeleteContactMutation()
  const { toast } = useToast()

  const ownerIds = useMemo(() => {
    const ids = new Set<number>()
    contacts.forEach((contact) => {
      if (contact.owner_id) ids.add(contact.owner_id)
    })
    return Array.from(ids).sort((a, b) => a - b)
  }, [contacts])

  const ownerSelectOptions = useMemo(() => ownerIds.map((ownerId) => ({ value: String(ownerId), label: `Сотрудник #${ownerId}` })), [ownerIds])

  const openCreateDrawer = () => {
    setEditingContact(null)
    setDrawerOpen(true)
  }

  const openEditDrawer = (contact: Contact) => {
    setEditingContact(contact)
    setDrawerOpen(true)
  }

  const handleDelete = useCallback(
    async (contact: Contact) => {
      const confirmed = window.confirm(`Удалить контакт «${contact.name}»?`)
      if (!confirmed) return
      try {
        await deleteContact.mutateAsync(contact.id)
        toast({ title: 'Контакт удалён', description: 'Запись больше не отображается в списке.' })
      } catch (error) {
        toast({ title: 'Ошибка удаления', description: error instanceof Error ? error.message : 'Попробуйте позже', variant: 'destructive' })
      }
    },
    [deleteContact, toast],
  )

  const columns = useMemo<ColumnDef<Contact>[]>(
    () => [
      {
        accessorKey: 'name',
        header: 'Контакт',
        cell: ({ row }) => (
          <div>
            <p className="font-medium">{row.original.name}</p>
            <p className="text-xs text-muted-foreground">{row.original.email ?? '—'}</p>
          </div>
        ),
      },
      {
        accessorKey: 'phone',
        header: 'Телефон',
        cell: ({ row }) => row.original.phone ?? '—',
      },
      {
        accessorKey: 'owner_id',
        header: 'Владелец',
        cell: ({ row }) => <span className="text-sm text-muted-foreground">Сотрудник #{row.original.owner_id}</span>,
      },
      {
        accessorKey: 'created_at',
        header: 'Создан',
        cell: ({ row }) => <span className="text-sm text-muted-foreground">{formatDate(row.original.created_at)}</span>,
      },
      {
        id: 'actions',
        header: '',
        cell: ({ row }) => (
          <div className="flex items-center justify-end gap-2">
            <Button variant="ghost" size="icon" onClick={() => openEditDrawer(row.original)}>
              <Pencil className="h-4 w-4" />
              <span className="sr-only">Редактировать</span>
            </Button>
            <Button variant="ghost" size="icon" className="text-destructive" onClick={() => handleDelete(row.original)}>
              <Trash2 className="h-4 w-4" />
              <span className="sr-only">Удалить</span>
            </Button>
          </div>
        ),
      },
    ],
    [handleDelete],
  )

  return (
    <div className="space-y-6">
      <header>
        <h1 className="text-2xl font-semibold text-foreground">Контакты</h1>
        <p className="text-sm text-muted-foreground">Управляйте базой контактов и быстро создавайте новые записи.</p>
      </header>
      <DataTable
        columns={columns}
        data={contacts}
        isLoading={isLoading}
        renderToolbar={
          <DataTableToolbar
            searchPlaceholder="Поиск по имени или email"
            searchValue={search}
            onSearchChange={setSearch}
            actions={
              <Button onClick={openCreateDrawer} className="gap-2">
                <Plus className="h-4 w-4" />
                Новый контакт
              </Button>
            }
          >
            {ownerIds.length ? (
              <Select value={ownerFilter} onValueChange={setOwnerFilter}>
                <SelectTrigger className="w-[200px] bg-background">
                  <SelectValue placeholder="Все владельцы" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="all">Все владельцы</SelectItem>
                  {ownerIds.map((ownerId) => (
                    <SelectItem key={ownerId} value={String(ownerId)}>
                      Сотрудник #{ownerId}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            ) : null}
          </DataTableToolbar>
        }
      />
      <ContactFormDrawer
        open={drawerOpen}
        onOpenChange={setDrawerOpen}
        contact={editingContact}
        isSubmitting={createContact.isPending || updateContact.isPending}
        ownerOptions={ownerSelectOptions}
        onSubmit={async (values) => {
          const payload = {
            name: values.name,
            email: values.email ? values.email : null,
            phone: values.phone ? values.phone : null,
            owner_id: values.ownerId ? Number(values.ownerId) : undefined,
          }
          try {
            if (editingContact) {
              await updateContact.mutateAsync({ contactId: editingContact.id, payload })
              toast({ title: 'Контакт обновлён', description: 'Изменения сохранены.' })
            } else {
              await createContact.mutateAsync(payload)
              toast({ title: 'Контакт создан', description: 'Добавлен новый контакт.' })
            }
            setDrawerOpen(false)
          } catch (error) {
            toast({ title: 'Ошибка сохранения', description: error instanceof Error ? error.message : 'Попробуйте ещё раз', variant: 'destructive' })
          }
        }}
        key={editingContact?.id ?? 'create'}
      />
    </div>
  )
}

interface ContactFormDrawerProps {
  open: boolean
  onOpenChange: (open: boolean) => void
  contact: Contact | null
  onSubmit: (values: ContactFormValues) => Promise<void>
  isSubmitting: boolean
  ownerOptions: Array<{ value: string; label: string }>
}

const ContactFormDrawer = ({ open, onOpenChange, contact, onSubmit, isSubmitting, ownerOptions }: ContactFormDrawerProps) => {
  const form = useForm<ContactFormValues>({
    resolver: zodResolver(contactFormSchema),
    defaultValues,
  })

  useEffect(() => {
    if (contact) {
      form.reset({
        name: contact.name,
        email: contact.email ?? '',
        phone: contact.phone ?? '',
        ownerId: contact.owner_id ? String(contact.owner_id) : '',
      })
    } else {
      form.reset(defaultValues)
    }
  }, [contact, form])

  const handleSubmit = async (values: ContactFormValues) => {
    await onSubmit(values)
    form.reset(defaultValues)
  }

  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      <SheetContent className="w-full max-w-md sm:max-w-lg">
        <SheetHeader>
          <SheetTitle>{contact ? 'Редактирование контакта' : 'Новый контакт'}</SheetTitle>
          <SheetDescription>Укажите основные данные и при необходимости закрепите владельца.</SheetDescription>
        </SheetHeader>
        <Form {...form}>
          <form onSubmit={form.handleSubmit(handleSubmit)} className="mt-6 space-y-4">
            <FormField
              control={form.control}
              name="name"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Имя</FormLabel>
                  <FormControl>
                    <Input placeholder="Мария Иванова" autoFocus {...field} />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              control={form.control}
              name="email"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>E-mail</FormLabel>
                  <FormControl>
                    <Input type="email" placeholder="maria@example.com" {...field} />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              control={form.control}
              name="phone"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Телефон</FormLabel>
                  <FormControl>
                    <Input placeholder="+7 999 000-00-00" {...field} />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              control={form.control}
              name="ownerId"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Владелец</FormLabel>
                  <Select value={field.value} onValueChange={field.onChange} disabled={!ownerOptions.length}>
                    <FormControl>
                      <SelectTrigger>
                        <SelectValue placeholder={ownerOptions.length ? 'Выберите владельца' : 'Назначение недоступно'} />
                      </SelectTrigger>
                    </FormControl>
                    <SelectContent>
                      <SelectItem value="">Назначить меня</SelectItem>
                      {ownerOptions.map((option) => (
                        <SelectItem key={option.value} value={option.value}>
                          {option.label}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                  <FormDescription>Выберите руководителя из списка или оставьте поле пустым, чтобы назначить себя.</FormDescription>
                  <FormMessage />
                </FormItem>
              )}
            />
            <div className="flex justify-end gap-2 pt-4">
              <Button type="button" variant="outline" onClick={() => onOpenChange(false)}>
                Отмена
              </Button>
              <Button type="submit" disabled={isSubmitting}>
                {isSubmitting ? 'Сохраняем…' : contact ? 'Сохранить' : 'Создать'}
              </Button>
            </div>
          </form>
        </Form>
      </SheetContent>
    </Sheet>
  )
}

export default ContactsPage
