import { useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Plus, Search, List, LayoutGrid, ClipboardCheck } from 'lucide-react';
import { trpc } from '@/lib/trpc';
import { useNotify } from '@/hooks/useNotify';
import { Button } from '@/components/ui/button';
import { InputGroup, InputGroupAddon, InputGroupInput } from '@/components/ui/input-group';
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group';
import { Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription } from '@/components/ui/empty';
import { TaskTable } from './TaskTable';
import { TaskCard } from './TaskCard';
import { TaskPager } from './TaskPager';
import { TaskDetailSheet } from './TaskDetailSheet';
import { NewTaskDialog } from './NewTaskDialog';
import { EditTaskDialog } from './EditTaskDialog';
import { type TaskItem } from './task-types';

type StatusFilter = 'active' | 'todo' | 'in_progress' | 'all' | 'done';
type OrderBy = 'dueDate' | 'priority' | 'createdAt';

const PAGE_SIZE_KEY = 'tasksPageSize';
const VIEW_MODE_KEY = 'tasksViewMode';

function readPageSize(): number {
  const v = Number(localStorage.getItem(PAGE_SIZE_KEY));
  return [10, 25, 50, 100].includes(v) ? v : 25;
}

function readViewMode(): 'list' | 'grid' {
  return (localStorage.getItem(VIEW_MODE_KEY) as 'list' | 'grid') ?? 'list';
}

export function TaskListView({
  projectId,
  hideProjectColumn,
}: {
  projectId?: string;
  hideProjectColumn?: boolean;
}) {
  const { t } = useTranslation();
  const utils = trpc.useUtils();
  const { notify, notifyError } = useNotify();

  const [search, setSearch] = useState('');
  const [debouncedSearch, setDebouncedSearch] = useState('');
  const [statusFilter, setStatusFilter] = useState<StatusFilter>('active');
  const [orderBy, setOrderBy] = useState<OrderBy>('dueDate');
  const [viewMode, setViewMode] = useState<'list' | 'grid'>(readViewMode);
  const [pageSize, setPageSize] = useState<number>(readPageSize);
  const [pageIndex, setPageIndex] = useState(0);

  const [newOpen, setNewOpen] = useState(false);
  const [editTask, setEditTask] = useState<TaskItem | null>(null);
  const [viewTask, setViewTask] = useState<TaskItem | null>(null);

  useEffect(() => { localStorage.setItem(VIEW_MODE_KEY, viewMode); }, [viewMode]);
  useEffect(() => { localStorage.setItem(PAGE_SIZE_KEY, String(pageSize)); }, [pageSize]);

  // Reset page on any filter change
  useEffect(() => { setPageIndex(0); }, [debouncedSearch, statusFilter, orderBy]);

  // Search debounce
  useEffect(() => {
    const id = setTimeout(() => setDebouncedSearch(search), 300);
    return () => clearTimeout(id);
  }, [search]);

  const backendStatus = statusFilter === 'todo' || statusFilter === 'in_progress' || statusFilter === 'done'
    ? statusFilter : undefined;

  const queryInput = useMemo(() => ({
    ...(backendStatus ? { status: backendStatus } : {}),
    ...(debouncedSearch.trim() ? { search: debouncedSearch.trim() } : {}),
    ...(projectId ? { projectId } : {}),
    orderBy,
  }), [backendStatus, debouncedSearch, orderBy, projectId]);

  const { data: filteredTasks } = trpc.tasks.list.useQuery(queryInput);

  const updateTask = trpc.tasks.update.useMutation({
    onSuccess: () => void utils.tasks.list.invalidate(),
    onError: (err) => notifyError('toast.task.updateError', err),
  });
  const deleteTask = trpc.tasks.delete.useMutation({
    onSuccess: () => {
      notify('warning', 'toast.task.deleted');
      void utils.tasks.list.invalidate();
    },
    onError: (err) => notifyError('toast.task.deleteError', err),
  });

  const tasksAll = (filteredTasks ?? [])
    .filter((task) => statusFilter !== 'active' || task.status === 'todo' || task.status === 'in_progress');

  const total = tasksAll.length;
  const lastPage = Math.max(0, Math.ceil(total / pageSize) - 1);
  const safePageIndex = Math.min(pageIndex, lastPage);
  if (safePageIndex !== pageIndex) setPageIndex(safePageIndex);
  const pageTasks = tasksAll.slice(safePageIndex * pageSize, (safePageIndex + 1) * pageSize);

  return (
    <div className="flex flex-col gap-4">
      {/* Toolbar */}
      <div className="flex flex-wrap items-center justify-between gap-3">
        <Tabs value={statusFilter} onValueChange={(v) => setStatusFilter(v as StatusFilter)}>
          <TabsList>
            <TabsTrigger value="active">{t('tasks.active')}</TabsTrigger>
            <TabsTrigger value="todo">{t('tasks.toDo')}</TabsTrigger>
            <TabsTrigger value="in_progress">{t('tasks.inProgress')}</TabsTrigger>
            <TabsTrigger value="done">{t('tasks.done')}</TabsTrigger>
            <TabsTrigger value="all">{t('tasks.all')}</TabsTrigger>
          </TabsList>
        </Tabs>
        <div className="flex flex-wrap items-center gap-3">
          <InputGroup className="w-56">
            <InputGroupAddon><Search /></InputGroupAddon>
            <InputGroupInput placeholder={t('tasks.searchPlaceholder')} value={search} onChange={(e) => setSearch(e.target.value)} />
          </InputGroup>
          <Select value={orderBy} onValueChange={(v) => setOrderBy(v as OrderBy)}>
            <SelectTrigger className="w-[180px]"><SelectValue /></SelectTrigger>
            <SelectContent>
              <SelectItem value="dueDate">{t('tasks.orderByDue')}</SelectItem>
              <SelectItem value="priority">{t('tasks.orderByPriority')}</SelectItem>
              <SelectItem value="createdAt">{t('tasks.orderByCreated')}</SelectItem>
            </SelectContent>
          </Select>
          <ToggleGroup type="single" value={viewMode} onValueChange={(v) => v && setViewMode(v as 'list' | 'grid')} variant="outline" size="sm">
            <ToggleGroupItem value="list" aria-label={t('tasks.viewList')}><List /></ToggleGroupItem>
            <ToggleGroupItem value="grid" aria-label={t('tasks.viewGrid')}><LayoutGrid /></ToggleGroupItem>
          </ToggleGroup>
          <Button size="sm" onClick={() => setNewOpen(true)}>
            <Plus className="h-4 w-4 mr-1" />{t('tasks.newTask')}
          </Button>
        </div>
      </div>

      {/* Body */}
      {total === 0 ? (
        <Empty>
          <EmptyHeader>
            <EmptyMedia variant="icon"><ClipboardCheck /></EmptyMedia>
            <EmptyTitle>{t('tasks.noTasksFound')}</EmptyTitle>
            <EmptyDescription>{t('tasks.noTasksDescription')}</EmptyDescription>
          </EmptyHeader>
        </Empty>
      ) : viewMode === 'grid' ? (
        <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-3">
          {pageTasks.map((task) => (
            <TaskCard
              key={task.id}
              task={task}
              onStatusChange={(id, status) => updateTask.mutate({ id, status })}
              onEdit={setEditTask}
              onDelete={(id) => deleteTask.mutate({ id })}
              onClick={setViewTask}
            />
          ))}
        </div>
      ) : (
        <TaskTable
          tasks={pageTasks}
          hideProjectColumn={hideProjectColumn}
          onRowClick={setViewTask}
          onEdit={setEditTask}
          onDelete={(id) => deleteTask.mutate({ id })}
          onStatusChange={(id, status) => updateTask.mutate({ id, status })}
        />
      )}

      {/* Pager (always visible when there are tasks) */}
      {total > 0 && (
        <TaskPager
          total={total}
          pageIndex={safePageIndex}
          pageSize={pageSize}
          onPageChange={setPageIndex}
          onPageSizeChange={(s) => { setPageSize(s); setPageIndex(0); }}
        />
      )}

      <NewTaskDialog open={newOpen} onOpenChange={setNewOpen} defaultProjectId={projectId} />
      <EditTaskDialog task={editTask} open={!!editTask} onOpenChange={(o) => { if (!o) setEditTask(null); }} />
      <TaskDetailSheet
        task={viewTask}
        open={!!viewTask}
        onOpenChange={(o) => { if (!o) setViewTask(null); }}
        onEdit={(task) => { setViewTask(null); setEditTask(task); }}
        onDelete={(id) => { deleteTask.mutate({ id }); setViewTask(null); }}
      />
    </div>
  );
}
