import { useEffect, useMemo, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import {
  ArrowLeft,
  ChevronLeft,
  ChevronRight,
  ClipboardCheck,
  Download,
  LayoutDashboard,
  ListChecks,
  Play,
  RefreshCw,
  Search,
  Settings,
  Sparkles,
  Upload,
  X,
} from 'lucide-react';
import { toast } from 'sonner';
import {
  Badge,
  Button,
  Card,
  CardContent,
  Checkbox,
  Input,
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
  Table,
  TableBody,
  TableHead,
  TableHeader,
  TableRow,
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
  cn,
  detailFromApiError,
  useAuth,
  getDataset,
  listDatasetStages,
  listMembers,
  listTasks,
  generateTasks,
  assignTask,
  VISIBILITY_LABEL,
  type DatasetTask,
} from '@ump/shared';
import { UploadDataDialog } from '../../data-import/presentation/components/UploadDataDialog';
import {
  SCOPE_OPTIONS,
  GROUP_OPTIONS,
  matchesScope,
  matchesAssignee,
  searchTasks,
  groupTasks,
  paginate,
  type TaskScope,
  type GroupBy,
  type AssigneeFilter,
} from '../domain/taskView';
import { ProductivitySidebar } from './ProductivitySidebar';
import { TaskRow } from './TaskRow';

const PAGE_SIZES = [10, 20, 50, 100];

/** Build a CSV of the (filtered) task list and trigger a download. */
function downloadCsv(filename: string, tasks: DatasetTask[]) {
  const header = ['Datapoint', 'Giai đoạn', 'Task Id', 'Phụ trách', 'Trạng thái'];
  const esc = (v: string) => `"${v.replace(/"/g, '""')}"`;
  const lines = tasks.map((t) =>
    [t.name || t.fileLogicalPath, t.currentStageName ?? '', t.id, t.assigneeName ?? '', t.pipelineState]
      .map((c) => esc(String(c)))
      .join(','),
  );
  const csv = [header.map(esc).join(','), ...lines].join('\n');
  const url = URL.createObjectURL(new Blob(['﻿' + csv], { type: 'text/csv;charset=utf-8' }));
  const a = document.createElement('a');
  a.href = url;
  a.download = `${filename || 'cong-viec'}.csv`;
  a.click();
  URL.revokeObjectURL(url);
}

/** The Data Page — a project's task list (project-workflow §12.3) in the RedBrick-style layout. */
export function DataPage() {
  const { id = '' } = useParams();
  const navigate = useNavigate();
  const qc = useQueryClient();
  const { user } = useAuth();
  const userId = user?.id ?? null;

  const [scope, setScope] = useState<TaskScope>('all');
  const [groupBy, setGroupBy] = useState<GroupBy>('none');
  const [assigneeFilter, setAssigneeFilter] = useState<AssigneeFilter>('all');
  const [query, setQuery] = useState('');
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(20);
  const [selected, setSelected] = useState<Set<string>>(new Set());
  const [uploadOpen, setUploadOpen] = useState(false);

  const dsQ = useQuery({ queryKey: ['imagehub', 'dataset', id], queryFn: () => getDataset(id), enabled: !!id });
  const stagesQ = useQuery({
    queryKey: ['imagehub', 'dataset', id, 'stages'],
    queryFn: () => listDatasetStages(id),
    enabled: !!id,
  });
  const membersQ = useQuery({
    queryKey: ['imagehub', 'dataset', id, 'members'],
    queryFn: () => listMembers(id),
    enabled: !!id,
  });
  // The whole task array — all filtering / grouping / paging is derived on the client.
  const tasksQ = useQuery({
    queryKey: ['imagehub', 'dataset', id, 'tasks'],
    queryFn: () => listTasks(id),
    enabled: !!id,
  });

  const ds = dsQ.data;
  const stages = useMemo(() => stagesQ.data ?? [], [stagesQ.data]);
  const members = useMemo(() => membersQ.data ?? [], [membersQ.data]);
  const tasks = useMemo(() => tasksQ.data ?? [], [tasksQ.data]);
  const noStages = stagesQ.isSuccess && stages.length === 0;

  const generateMut = useMutation({
    mutationFn: () => generateTasks(id),
    onSuccess: (r) => {
      toast.success(r.created > 0 ? `Đã tạo ${r.created} công việc` : 'Tất cả tệp đã có công việc');
      qc.invalidateQueries({ queryKey: ['imagehub', 'dataset', id, 'tasks'] });
    },
    onError: (e: unknown) => toast.error(detailFromApiError(e, 'Không tạo được công việc')),
  });

  const bulkAssignMut = useMutation({
    mutationFn: (assignee: string) => Promise.all([...selected].map((tid) => assignTask(id, tid, assignee))),
    onSuccess: (_r, assignee) => {
      const who = members.find((m) => m.userId === assignee);
      toast.success(`Đã giao ${selected.size} công việc cho ${who?.fullName || who?.email || 'thành viên'}`);
      setSelected(new Set());
      qc.invalidateQueries({ queryKey: ['imagehub', 'dataset', id, 'tasks'] });
    },
    onError: (e: unknown) => toast.error(detailFromApiError(e, 'Giao việc hàng loạt thất bại')),
  });

  // Region 2/3 — scope → assignee → search, then region 7 paginate the flat list, then group the page.
  const filtered = useMemo(() => {
    const scoped = tasks.filter((t) => matchesScope(t, scope, userId) && matchesAssignee(t, assigneeFilter));
    return searchTasks(scoped, query);
  }, [tasks, scope, assigneeFilter, query, userId]);

  const pageData = useMemo(() => paginate(filtered, page, pageSize), [filtered, page, pageSize]);
  const groups = useMemo(() => groupTasks(pageData.items, groupBy), [pageData.items, groupBy]);

  // Reset to page 1 whenever the result set changes shape.
  useEffect(() => setPage(1), [scope, assigneeFilter, query, pageSize]);

  const pageIds = pageData.items.map((t) => t.id);
  const allSelected = pageIds.length > 0 && pageIds.every((i) => selected.has(i));
  const someSelected = pageIds.some((i) => selected.has(i)) && !allSelected;
  const toggleAll = (checked: boolean) =>
    setSelected((prev) => {
      const next = new Set(prev);
      pageIds.forEach((i) => (checked ? next.add(i) : next.delete(i)));
      return next;
    });
  const toggleOne = (taskId: string, checked: boolean) =>
    setSelected((prev) => {
      const next = new Set(prev);
      if (checked) next.add(taskId);
      else next.delete(taskId);
      return next;
    });

  const openFirst = (predicate: (t: DatasetTask) => boolean, emptyMsg: string) => {
    const t = tasks.find(predicate);
    if (!t) return toast.info(emptyMsg);
    navigate(`/dashboard/datasets/${id}/tasks/${t.id}`);
  };
  const startLabeling = () =>
    openFirst(
      (t) => t.pipelineState === 'inLabel' && (t.assigneeUserId === userId || !t.assigneeUserId),
      'Không có công việc cần gán nhãn.',
    );
  const startReview = () =>
    openFirst(
      (t) => t.pipelineState === 'inReview' && (t.assigneeUserId === userId || !t.assigneeUserId),
      'Không có công việc cần rà soát.',
    );

  const colSpan = 8;

  return (
    <TooltipProvider delayDuration={200}>
      <div className="mx-auto max-w-[1400px] space-y-5">
        <Button variant="ghost" size="sm" onClick={() => navigate(`/dashboard/datasets/${id}`)}>
          <ArrowLeft className="mr-2 h-4 w-4" /> {ds?.name ?? 'Bộ dữ liệu'}
        </Button>

        {/* Header: title + tab nav (left) · toolbar (right) — region 4 */}
        <div className="flex flex-wrap items-start justify-between gap-4">
          <div className="space-y-2">
            <div className="flex items-center gap-2">
              <h1 className="font-serif text-2xl font-semibold text-foreground">{ds?.name ?? 'Công việc'}</h1>
              {ds && <Badge variant="outline">{VISIBILITY_LABEL[ds.visibility]}</Badge>}
            </div>
            <nav className="flex items-center gap-1 text-sm">
              {[
                { label: 'Tổng quan', to: `/dashboard/datasets/${id}`, active: false },
                { label: 'Dữ liệu', to: `/dashboard/datasets/${id}/tasks`, active: true },
                { label: 'Cài đặt', to: `/dashboard/datasets/${id}/settings`, active: false },
              ].map((t) => (
                <button
                  key={t.label}
                  type="button"
                  onClick={() => !t.active && navigate(t.to)}
                  className={cn(
                    'rounded-md px-3 py-1 font-medium transition-colors',
                    t.active
                      ? 'bg-foreground text-background'
                      : 'text-muted-foreground hover:bg-muted hover:text-foreground',
                  )}
                >
                  {t.label}
                </button>
              ))}
            </nav>
          </div>

          <div className="flex items-center gap-2">
            <div className="flex items-center gap-1 rounded-full border border-border px-1">
              {[
                { icon: RefreshCw, label: 'Tải lại', onClick: () => tasksQ.refetch(), spin: tasksQ.isFetching },
                {
                  icon: LayoutDashboard,
                  label: 'Tổng quan',
                  onClick: () => navigate(`/dashboard/datasets/${id}`),
                },
                {
                  icon: Settings,
                  label: 'Cài đặt',
                  onClick: () => navigate(`/dashboard/datasets/${id}/settings`),
                },
              ].map((b) => (
                <Tooltip key={b.label}>
                  <TooltipTrigger asChild>
                    <Button size="icon" variant="ghost" className="h-8 w-8 rounded-full" onClick={b.onClick}>
                      <b.icon className={cn('h-4 w-4', b.spin && 'animate-spin')} />
                    </Button>
                  </TooltipTrigger>
                  <TooltipContent>{b.label}</TooltipContent>
                </Tooltip>
              ))}
            </div>
            <Button variant="outline" onClick={() => setUploadOpen(true)}>
              <Upload className="mr-2 h-4 w-4" /> Tải dữ liệu
            </Button>
            <Button variant="outline" onClick={startReview}>
              <ClipboardCheck className="mr-2 h-4 w-4" /> Rà soát
            </Button>
            <Button onClick={startLabeling}>
              <Play className="mr-2 h-4 w-4" /> Bắt đầu gán nhãn
            </Button>
          </div>
        </div>

        {dsQ.isError && <p className="text-sm text-destructive">Không tải được bộ dữ liệu.</p>}

        <div className="flex flex-col gap-5 lg:flex-row">
          <ProductivitySidebar
            datasetId={id}
            tasks={tasks}
            members={members}
            currentUser={user ? { id: user.id, name: user.name || user.email, role: 'Tôi' } : null}
          />

          <div className="min-w-0 flex-1 space-y-4">
            {noStages ? (
              <Card>
                <CardContent className="space-y-3 py-12 text-center">
                  <ListChecks className="mx-auto h-10 w-10 text-muted-foreground" />
                  <p className="mx-auto max-w-md text-sm text-muted-foreground">
                    Bộ dữ liệu chưa có giai đoạn quy trình. Hãy thêm giai đoạn gán nhãn / kiểm duyệt trong Cài đặt
                    trước khi tạo công việc.
                  </p>
                  <Button onClick={() => navigate(`/dashboard/datasets/${id}/settings`)}>
                    <Settings className="mr-2 h-4 w-4" /> Mở Cài đặt
                  </Button>
                </CardContent>
              </Card>
            ) : (
              <>
                {/* Filter bar (region 2) + search (region 3) */}
                <div className="flex flex-wrap items-center gap-2">
                  <Select value={scope} onValueChange={(v) => setScope(v as TaskScope)}>
                    <SelectTrigger className="h-9 w-44">
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      {SCOPE_OPTIONS.map((o) => (
                        <SelectItem key={o.value} value={o.value}>
                          {o.label}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                  <Select value={groupBy} onValueChange={(v) => setGroupBy(v as GroupBy)}>
                    <SelectTrigger className="h-9 w-40">
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      {GROUP_OPTIONS.map((o) => (
                        <SelectItem key={o.value} value={o.value}>
                          {o.label}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                  <Select value={assigneeFilter} onValueChange={(v) => setAssigneeFilter(v)}>
                    <SelectTrigger className="h-9 w-44">
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="all">Tất cả người dùng</SelectItem>
                      <SelectItem value="unassigned">Chưa giao</SelectItem>
                      {members.map((m) => (
                        <SelectItem key={m.userId} value={m.userId}>
                          {m.fullName || m.email}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>

                  <div className="relative ml-auto">
                    <Search className="absolute left-2.5 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
                    <Input
                      value={query}
                      onChange={(e) => setQuery(e.target.value)}
                      placeholder="Tìm theo Task Id hoặc tên"
                      className="h-9 w-64 pl-8"
                    />
                  </div>
                  <Tooltip>
                    <TooltipTrigger asChild>
                      <Button
                        variant="ghost"
                        size="icon"
                        className="h-9 w-9"
                        disabled={filtered.length === 0}
                        onClick={() => downloadCsv(ds?.name ?? 'cong-viec', filtered)}
                      >
                        <Download className="h-4 w-4" />
                      </Button>
                    </TooltipTrigger>
                    <TooltipContent>Xuất CSV</TooltipContent>
                  </Tooltip>
                  <Button onClick={() => generateMut.mutate()} disabled={generateMut.isPending}>
                    <Sparkles className="mr-2 h-4 w-4" />
                    {generateMut.isPending ? 'Đang tạo…' : 'Tạo công việc'}
                  </Button>
                </div>

                {/* Bulk-selection bar (region 6) */}
                {selected.size > 0 && (
                  <div className="flex flex-wrap items-center gap-3 rounded-lg border border-primary/30 bg-primary/5 px-3 py-2 text-sm">
                    <span className="font-medium text-foreground">Đã chọn {selected.size}</span>
                    <Select onValueChange={(v) => bulkAssignMut.mutate(v)} disabled={bulkAssignMut.isPending}>
                      <SelectTrigger className="h-8 w-48">
                        <SelectValue placeholder="Giao cho…" />
                      </SelectTrigger>
                      <SelectContent>
                        {members.map((m) => (
                          <SelectItem key={m.userId} value={m.userId}>
                            {m.fullName || m.email}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                    <Button variant="ghost" size="sm" className="h-8" onClick={() => setSelected(new Set())}>
                      <X className="mr-1 h-4 w-4" /> Bỏ chọn
                    </Button>
                  </div>
                )}

                {tasksQ.isLoading ? (
                  <p className="text-sm text-muted-foreground">Đang tải…</p>
                ) : filtered.length === 0 ? (
                  <Card>
                    <CardContent className="space-y-3 py-12 text-center">
                      <ListChecks className="mx-auto h-10 w-10 text-muted-foreground" />
                      <p className="text-sm text-muted-foreground">
                        {tasks.length === 0
                          ? 'Chưa có công việc nào. Nhấn “Tạo công việc” để tạo từ các tệp ảnh trong bộ dữ liệu.'
                          : 'Không có công việc nào khớp bộ lọc.'}
                      </p>
                    </CardContent>
                  </Card>
                ) : (
                  <Card>
                    <CardContent className="p-0">
                      <Table>
                        <TableHeader>
                          <TableRow>
                            <TableHead className="w-10">
                              <Checkbox
                                checked={allSelected ? true : someSelected ? 'indeterminate' : false}
                                onCheckedChange={(v) => toggleAll(v === true)}
                                aria-label="Chọn tất cả trên trang"
                              />
                            </TableHead>
                            <TableHead>Datapoint</TableHead>
                            <TableHead>Giai đoạn</TableHead>
                            <TableHead className="w-16">Tệp</TableHead>
                            <TableHead>Task Id</TableHead>
                            <TableHead>Phụ trách</TableHead>
                            <TableHead className="w-16">Điểm</TableHead>
                            <TableHead className="text-right">Thao tác</TableHead>
                          </TableRow>
                        </TableHeader>
                        <TableBody>
                          {groups.map((g) => (
                            <GroupRows
                              key={g.key}
                              label={groupBy === 'none' ? null : `${g.label} (${g.tasks.length})`}
                              colSpan={colSpan}
                            >
                              {g.tasks.map((t) => (
                                <TaskRow
                                  key={t.id}
                                  datasetId={id}
                                  task={t}
                                  members={members}
                                  stages={stages}
                                  selected={selected.has(t.id)}
                                  onSelectedChange={(c) => toggleOne(t.id, c)}
                                />
                              ))}
                            </GroupRows>
                          ))}
                        </TableBody>
                      </Table>
                    </CardContent>
                  </Card>
                )}

                {/* Pagination footer (region 7) */}
                {filtered.length > 0 && (
                  <div className="flex flex-wrap items-center justify-between gap-3 text-sm text-muted-foreground">
                    <div className="flex items-center gap-2">
                      <Button
                        variant="outline"
                        size="icon"
                        className="h-8 w-8"
                        disabled={pageData.page <= 1}
                        onClick={() => setPage((p) => p - 1)}
                      >
                        <ChevronLeft className="h-4 w-4" />
                      </Button>
                      <span>
                        Trang {pageData.page} / {pageData.pageCount}
                      </span>
                      <Button
                        variant="outline"
                        size="icon"
                        className="h-8 w-8"
                        disabled={pageData.page >= pageData.pageCount}
                        onClick={() => setPage((p) => p + 1)}
                      >
                        <ChevronRight className="h-4 w-4" />
                      </Button>
                      <span className="ml-2">
                        Hiển thị
                        <Select value={String(pageSize)} onValueChange={(v) => setPageSize(Number(v))}>
                          <SelectTrigger className="mx-2 inline-flex h-8 w-20">
                            <SelectValue />
                          </SelectTrigger>
                          <SelectContent>
                            {PAGE_SIZES.map((s) => (
                              <SelectItem key={s} value={String(s)}>
                                {s}
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                        / trang
                      </span>
                    </div>
                    <span>Tổng {filtered.length} mục</span>
                  </div>
                )}
              </>
            )}
          </div>
        </div>
      </div>

      {uploadOpen && (
        <UploadDataDialog
          open
          onOpenChange={setUploadOpen}
          datasetId={id}
          onCompleted={() => qc.invalidateQueries({ queryKey: ['imagehub', 'dataset', id] })}
        />
      )}
    </TooltipProvider>
  );
}

/** Renders an optional group-header row followed by its task rows (region 2 grouping). */
function GroupRows({
  label,
  colSpan,
  children,
}: {
  label: string | null;
  colSpan: number;
  children: React.ReactNode;
}) {
  return (
    <>
      {label && (
        <TableRow className="bg-muted/40 hover:bg-muted/40">
          <td colSpan={colSpan} className="px-4 py-1.5 text-xs font-semibold uppercase tracking-wide text-muted-foreground">
            {label}
          </td>
        </TableRow>
      )}
      {children}
    </>
  );
}

export default DataPage;
