import { zodResolver } from '@hookform/resolvers/zod'
import { type ColumnDef } from '@tanstack/react-table'
import { 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 { TaskStatusPill } from '@/components/crm/task-status-pill'
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 { Switch } from '@/components/ui/switch'
import { Textarea } from '@/components/ui/textarea'
import { useToast } from '@/components/ui/use-toast'
import { useCreateTaskMutation, useTasksQuery } from '@/features/tasks/hooks'
import { useDealsQuery } from '@/features/deals/hooks'
import { useDebounce } from '@/hooks/use-debounce'
import { formatDate, formatRelativeDate } from '@/lib/utils'
import type { Deal, Task } from '@/types/crm'

const taskFormSchema = z
  .object({
    title: z.string().min(3, 'Минимум 3 символа'),
    dealId: z.string().min(1, 'Укажите ID сделки'),
    description: z.string().max(500, 'Описание до 500 символов').optional(),
    dueDate: z.string().optional(),
  })
  .refine((values) => {
    if (!values.dueDate) return true
    const selected = new Date(values.dueDate)
    const today = new Date()
    selected.setHours(0, 0, 0, 0)
    today.setHours(0, 0, 0, 0)
    return selected >= today
  }, { message: 'Дата не может быть в прошлом', path: ['dueDate'] })

type TaskFormValues = z.infer<typeof taskFormSchema>

const defaultTaskValues: TaskFormValues = { title: '', dealId: '', description: '', dueDate: '' }

const TasksPage = () => {
  const [search, setSearch] = useState('')
  const [dealFilter, setDealFilter] = useState('')
  const [onlyOpen, setOnlyOpen] = useState(true)
  const [dueAfter, setDueAfter] = useState('')
  const [dueBefore, setDueBefore] = useState('')
  const [drawerOpen, setDrawerOpen] = useState(false)
  const debouncedDealId = useDebounce(dealFilter, 300)
  const { toast } = useToast()

  const { data: tasks = [], isLoading } = useTasksQuery({
    dealId: debouncedDealId ? Number(debouncedDealId) : undefined,
    onlyOpen,
    dueAfter: dueAfter || undefined,
    dueBefore: dueBefore || undefined,
  })

  const filteredTasks = useMemo(() => {
    const query = search.trim().toLowerCase()
    if (!query) return tasks
    return tasks.filter((task) => task.title.toLowerCase().includes(query))
  }, [tasks, search])

  const createTask = useCreateTaskMutation()
  const { data: deals = [], isLoading: dealsLoading } = useDealsQuery({ pageSize: 100, orderBy: 'updated_at', order: 'desc' })

  const columns = useMemo<ColumnDef<Task>[]>(
    () => [
      {
        accessorKey: 'title',
        header: 'Задача',
        cell: ({ row }) => (
          <div>
            <p className="font-medium">{row.original.title}</p>
            <p className="text-xs text-muted-foreground">Сделка #{row.original.deal_id}</p>
          </div>
        ),
      },
      {
        accessorKey: 'due_date',
        header: 'Срок',
        cell: ({ row }) => (
          <div>
            <p>{row.original.due_date ? formatDate(row.original.due_date) : '—'}</p>
            <p className="text-xs text-muted-foreground">{row.original.due_date ? formatRelativeDate(row.original.due_date) : ''}</p>
          </div>
        ),
      },
      {
        accessorKey: 'is_done',
        header: 'Статус',
        cell: ({ row }) => <TaskStatusPill done={row.original.is_done} />,
      },
      {
        accessorKey: 'created_at',
        header: 'Создана',
        cell: ({ row }) => <span className="text-sm text-muted-foreground">{formatDate(row.original.created_at)}</span>,
      },
    ],
    [],
  )

  return (
    <div className="space-y-6">
      <header>
        <h1 className="text-2xl font-semibold text-foreground">Задачи</h1>
        <p className="text-sm text-muted-foreground">Контролируйте follow-up по сделкам и создавайте напоминания.</p>
      </header>
      <DataTable
        columns={columns}
        data={filteredTasks}
        isLoading={isLoading}
        renderToolbar={
          <DataTableToolbar
            searchPlaceholder="Поиск по названию"
            searchValue={search}
            onSearchChange={setSearch}
            actions={
              <Button className="gap-2" onClick={() => setDrawerOpen(true)}>
                + Новая задача
              </Button>
            }
          >
            <Input
              type="number"
              placeholder="ID сделки"
              value={dealFilter}
              onChange={(event) => setDealFilter(event.target.value)}
              className="w-[140px]"
            />
            <div className="flex items-center gap-2 rounded-lg border bg-background px-3 py-1.5 text-sm">
              <Switch checked={onlyOpen} onCheckedChange={(value) => setOnlyOpen(value === true)} id="only-open" />
              <label htmlFor="only-open" className="cursor-pointer">
                Только открытые
              </label>
            </div>
            <Input type="date" value={dueAfter} onChange={(event) => setDueAfter(event.target.value)} className="w-[170px]" />
            <Input type="date" value={dueBefore} onChange={(event) => setDueBefore(event.target.value)} className="w-[170px]" />
          </DataTableToolbar>
        }
      />
      <TaskDrawer
        open={drawerOpen}
        onOpenChange={setDrawerOpen}
        isSubmitting={createTask.isPending}
        deals={deals}
        dealsLoading={dealsLoading}
        onSubmit={async (values) => {
          const payload = {
            deal_id: Number(values.dealId),
            title: values.title,
            description: values.description ? values.description : undefined,
            due_date: values.dueDate || undefined,
          }
          try {
            await createTask.mutateAsync(payload)
            toast({ title: 'Задача создана', description: 'Добавлено напоминание для сделки.' })
            setDrawerOpen(false)
          } catch (error) {
            toast({ title: 'Ошибка создания', description: error instanceof Error ? error.message : 'Попробуйте позже', variant: 'destructive' })
          }
        }}
      />
    </div>
  )
}

interface TaskDrawerProps {
  open: boolean
  onOpenChange: (open: boolean) => void
  onSubmit: (values: TaskFormValues) => Promise<void>
  isSubmitting: boolean
  deals: Deal[]
  dealsLoading: boolean
}

const TaskDrawer = ({ open, onOpenChange, onSubmit, isSubmitting, deals, dealsLoading }: TaskDrawerProps) => {
  const form = useForm<TaskFormValues>({
    resolver: zodResolver(taskFormSchema),
    defaultValues: defaultTaskValues,
  })

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

  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      <SheetContent className="w-full max-w-lg">
        <SheetHeader>
          <SheetTitle>Новая задача</SheetTitle>
          <SheetDescription>Запланируйте следующий шаг для сделки.</SheetDescription>
        </SheetHeader>
        <Form {...form}>
          <form onSubmit={form.handleSubmit(handleSubmit)} className="mt-6 space-y-4">
            <FormField
              control={form.control}
              name="title"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Название</FormLabel>
                  <FormControl>
                    <Input placeholder="Позвонить клиенту" {...field} />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              control={form.control}
              name="dealId"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Сделка</FormLabel>
                  <Select value={field.value} onValueChange={field.onChange} disabled={dealsLoading || !deals.length}>
                    <FormControl>
                      <SelectTrigger>
                        <SelectValue placeholder={dealsLoading ? 'Загружаем сделки…' : 'Выберите сделку'} />
                      </SelectTrigger>
                    </FormControl>
                    <SelectContent>
                      {deals.map((deal) => (
                        <SelectItem key={deal.id} value={String(deal.id)}>
                          {deal.title} · #{deal.id}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                  <FormDescription>
                    {deals.length ? 'Задача появится в таймлайне выбранной сделки.' : 'Сначала создайте сделку в разделе «Сделки».'}
                  </FormDescription>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              control={form.control}
              name="dueDate"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Срок выполнения</FormLabel>
                  <FormControl>
                    <Input type="date" {...field} />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              control={form.control}
              name="description"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Описание</FormLabel>
                  <FormControl>
                    <Textarea rows={4} placeholder="Кратко опишите следующий шаг" {...field} />
                  </FormControl>
                  <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 ? 'Сохраняем…' : 'Создать'}
              </Button>
            </div>
          </form>
        </Form>
      </SheetContent>
    </Sheet>
  )
}

export default TasksPage
