import { useEffect, useState, type ReactNode } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useQuery } from '@tanstack/react-query';
import {
  ArrowLeft,
  MousePointer2,
  Square,
  Circle,
  PenLine,
  Brush,
  Hexagon,
  Trash2,
  Save,
  CheckCircle2,
  Check,
  X,
  SkipForward,
  Star,
  Loader2,
} from 'lucide-react';
import { toast } from 'sonner';
import { UnifiedQuadViewRenderer } from '@ump/shared/viewer';
import type { Annotation, AnnotationTool as AnnTool } from '@ump/shared/viewer';
import {
  Badge,
  Button,
  TooltipProvider,
  cn,
  fileDownloadUrl,
  fetchAsFile,
  getTask,
  saveTask,
  finalizeTask,
  reviewTask,
  skipTask,
  setTaskReference,
} from '@ump/shared';
import {
  PIPELINE_STATE_META,
  QUEUE_STATUS_META,
  allowedActions,
  type BadgeTone,
} from '../domain/taskView';

const DEFAULTS = { windowWidth: 400, windowLevel: 40 };

const TONE_CLASS: Record<BadgeTone, string> = {
  label: 'border-primary/30 bg-primary/10 text-primary',
  review: 'border-accent/30 bg-accent/10 text-accent',
  done: 'border-emerald-500/30 bg-emerald-500/10 text-emerald-600',
  issue: 'border-destructive/30 bg-destructive/10 text-destructive',
  warn: 'border-amber-500/30 bg-amber-500/10 text-amber-600',
  muted: 'border-border bg-muted text-muted-foreground',
};
function ToneBadge({ tone, children }: { tone: BadgeTone; children: ReactNode }) {
  return (
    <Badge variant="outline" className={cn('font-normal', TONE_CLASS[tone])}>
      {children}
    </Badge>
  );
}

const TOOLS: { id: AnnTool; label: string; Icon: typeof Square }[] = [
  { id: 'none', label: 'Chọn', Icon: MousePointer2 },
  { id: 'bbox', label: 'Khung', Icon: Square },
  { id: 'points', label: 'Điểm', Icon: Circle },
  { id: 'pen', label: 'Bút', Icon: PenLine },
  { id: 'brush', label: 'Cọ', Icon: Brush },
  { id: 'polygon', label: 'Đa giác', Icon: Hexagon },
];
const TOOL_LABEL: Record<string, string> = {
  bbox: 'Khung', points: 'Điểm', pen: 'Bút', brush: 'Cọ', polygon: 'Đa giác',
};
const VIEW_LABEL: Record<string, string> = { axial: 'Axial', coronal: 'Coronal', sagittal: 'Sagittal' };

/**
 * AnnotationTool — work a single task in the 3D viewer (project-workflow §12.3).
 *
 * Loads the task + its image, renders the shared VTK quad-view + the 5-tool annotation overlay,
 * and drives the queue/pipeline from here: Save (Q3) / Hoàn tất (TP1 finalize) / Chấp nhận (TP2) /
 * Từ chối (TP3) / Bỏ qua (Q2). Annotations persist as JSON (load on open, save on Save/transition).
 * Ground-Truth tasks open read-only. Statically imports `@ump/shared/viewer` (VTK), so it is
 * lazy-loaded as a route in App.tsx.
 */
export function AnnotationTool() {
  const { id = '', taskId = '' } = useParams();
  const navigate = useNavigate();

  const taskQ = useQuery({
    queryKey: ['imagehub', 'dataset', id, 'task', taskId],
    queryFn: () => getTask(id, taskId),
    enabled: !!id && !!taskId,
  });
  const task = taskQ.data;

  const [file, setFile] = useState<File | null>(null);
  const [fileError, setFileError] = useState(false);
  const [tool, setTool] = useState<AnnTool>('none');
  const [annotations, setAnnotations] = useState<Annotation[]>([]);
  const [windowWidth, setWindowWidth] = useState(DEFAULTS.windowWidth);
  const [windowLevel, setWindowLevel] = useState(DEFAULTS.windowLevel);
  const [busy, setBusy] = useState(false);

  // Load the task's saved annotations once per task — keyed on id so a refetch (after Save) doesn't
  // clobber the in-canvas edits.
  useEffect(() => {
    if (task) setAnnotations(Array.isArray(task.annotations) ? (task.annotations as Annotation[]) : []);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [task?.id]);

  // Fetch the task's image file for the viewer.
  useEffect(() => {
    if (!task) return;
    let cancelled = false;
    setFile(null);
    setFileError(false);
    (async () => {
      try {
        const { url, logicalPath } = await fileDownloadUrl(id, task.fileId);
        const f = await fetchAsFile(url, logicalPath);
        if (!cancelled) setFile(f);
      } catch {
        if (!cancelled) setFileError(true);
      }
    })();
    return () => {
      cancelled = true;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [task?.fileId, id]);

  const actions = task ? allowedActions(task) : null;
  const readOnly = actions?.isTerminal ?? false;
  const effectiveTool: AnnTool = readOnly ? 'none' : tool;

  const run = async (label: string, fn: () => Promise<unknown>, opts?: { back?: boolean }) => {
    setBusy(true);
    try {
      await fn();
      toast.success(label);
      if (opts?.back) navigate(`/dashboard/datasets/${id}/tasks`);
      else await taskQ.refetch();
    } catch (e) {
      toast.error((e as { message?: string })?.message || 'Thao tác không thành công');
    } finally {
      setBusy(false);
    }
  };

  return (
    <div className="fixed inset-0 z-50 flex flex-col bg-background">
      {/* Top bar: identity + status, window/level, actions */}
      <div className="flex shrink-0 flex-wrap items-center justify-between gap-x-6 gap-y-2 border-b px-4 py-2.5">
        <div className="flex min-w-0 items-center gap-3">
          <Button variant="ghost" size="sm" onClick={() => navigate(`/dashboard/datasets/${id}/tasks`)}>
            <ArrowLeft className="mr-2 h-4 w-4" /> Công việc
          </Button>
          <span className="truncate font-mono text-sm" title={task?.fileLogicalPath}>
            {task?.name || task?.fileLogicalPath || '…'}
          </span>
          {task && (
            <ToneBadge tone={PIPELINE_STATE_META[task.pipelineState].tone}>
              {PIPELINE_STATE_META[task.pipelineState].label}
            </ToneBadge>
          )}
          {task && !readOnly && (
            <ToneBadge tone={QUEUE_STATUS_META[task.queueStatus].tone}>
              {QUEUE_STATUS_META[task.queueStatus].label}
            </ToneBadge>
          )}
          {task?.currentStageName && (
            <span className="text-xs text-muted-foreground">· {task.currentStageName}</span>
          )}
        </div>

        <div className="flex flex-wrap items-center gap-x-5 gap-y-1 text-xs text-muted-foreground">
          <label className="flex items-center gap-2">
            <span>WW</span>
            <input type="range" min={1} max={4000} value={windowWidth}
              onChange={(e) => setWindowWidth(Number(e.target.value))} className="w-24 accent-primary" />
            <span className="w-10 tabular-nums text-foreground">{windowWidth}</span>
          </label>
          <label className="flex items-center gap-2">
            <span>WL</span>
            <input type="range" min={-1000} max={3000} value={windowLevel}
              onChange={(e) => setWindowLevel(Number(e.target.value))} className="w-24 accent-primary" />
            <span className="w-10 tabular-nums text-foreground">{windowLevel}</span>
          </label>
        </div>

        <div className="flex items-center gap-2">
          {actions && !readOnly && (
            <Button variant="outline" size="sm" disabled={busy}
              onClick={() => run('Đã lưu chú thích', () => saveTask(id, taskId, annotations, false))}>
              <Save className="mr-1 h-4 w-4" /> Lưu
            </Button>
          )}
          {actions?.canFinalize && (
            <Button size="sm" disabled={busy}
              onClick={() => run('Đã hoàn tất', async () => {
                await saveTask(id, taskId, annotations, true);
                await finalizeTask(id, taskId);
              }, { back: true })}>
              <CheckCircle2 className="mr-1 h-4 w-4" /> Hoàn tất
            </Button>
          )}
          {actions?.canReview && (
            <>
              <Button size="sm" disabled={busy}
                onClick={() => run('Đã chấp nhận', async () => {
                  await saveTask(id, taskId, annotations, false);
                  await reviewTask(id, taskId, 'accept');
                }, { back: true })}>
                <Check className="mr-1 h-4 w-4" /> Chấp nhận
              </Button>
              <Button variant="outline" size="sm" disabled={busy}
                onClick={() => run('Đã từ chối', () => reviewTask(id, taskId, 'reject'), { back: true })}>
                <X className="mr-1 h-4 w-4" /> Từ chối
              </Button>
            </>
          )}
          {actions?.canSkip && (
            <Button variant="ghost" size="icon" className="h-9 w-9" title="Bỏ qua" disabled={busy}
              onClick={() => run('Đã bỏ qua', () => skipTask(id, taskId), { back: true })}>
              <SkipForward className="h-4 w-4" />
            </Button>
          )}
          {actions?.canSetReference && (
            <Button variant={task?.isReferenceStandard ? 'secondary' : 'outline'} size="sm" disabled={busy}
              onClick={() => run(task?.isReferenceStandard ? 'Đã bỏ chuẩn' : 'Đã đặt chuẩn',
                () => setTaskReference(id, taskId, !task?.isReferenceStandard))}>
              <Star className={cn('mr-1 h-4 w-4', task?.isReferenceStandard && 'fill-amber-400 text-amber-500')} />
              {task?.isReferenceStandard ? 'Bỏ chuẩn' : 'Đặt chuẩn'}
            </Button>
          )}
        </div>
      </div>

      {/* Body: viewer + annotation side panel */}
      <div className="flex min-h-0 flex-1">
        <TooltipProvider>
          <div className="relative min-w-0 flex-1 bg-black">
            {taskQ.isLoading && (
              <div className="flex h-full items-center justify-center text-muted-foreground">
                <Loader2 className="mr-2 h-5 w-5 animate-spin" /> Đang tải công việc…
              </div>
            )}
            {taskQ.isError && (
              <div className="flex h-full items-center justify-center text-destructive">Không tải được công việc.</div>
            )}
            {fileError && (
              <div className="flex h-full items-center justify-center text-destructive">Không tải được tệp ảnh.</div>
            )}
            {task && file && !fileError && (
              <UnifiedQuadViewRenderer
                files={[file]}
                windowWidth={windowWidth}
                windowLevel={windowLevel}
                opacity={0.8}
                annotationTool={effectiveTool}
                annotations={annotations}
                onAnnotationsChange={setAnnotations}
              />
            )}
            {task && !file && !fileError && (
              <div className="flex h-full items-center justify-center text-muted-foreground">
                <Loader2 className="mr-2 h-5 w-5 animate-spin" /> Đang tải ảnh…
              </div>
            )}
          </div>
        </TooltipProvider>

        <aside className="flex w-72 shrink-0 flex-col border-l bg-background">
          <div className="border-b px-4 py-3">
            <h3 className="text-sm font-semibold text-foreground">Công cụ chú thích</h3>
            <p className="mt-0.5 text-[11px] text-muted-foreground">
              {readOnly
                ? 'Tác vụ đã hoàn tất — chỉ xem.'
                : 'Vẽ trên các lát cắt 2D (axial / coronal / sagittal).'}
            </p>
          </div>

          {!readOnly && (
            <div className="grid grid-cols-3 gap-2 p-3">
              {TOOLS.map(({ id: tid, label, Icon }) => (
                <button key={tid} type="button" onClick={() => setTool(tid)}
                  className={cn(
                    'flex flex-col items-center gap-1 rounded-md border px-2 py-2 text-[11px] transition',
                    tool === tid
                      ? 'border-primary bg-primary/10 text-primary'
                      : 'border-border text-muted-foreground hover:bg-accent',
                  )}>
                  <Icon className="h-4 w-4" />
                  {label}
                </button>
              ))}
            </div>
          )}

          <div className="flex items-center justify-between border-y px-4 py-2">
            <span className="text-xs font-medium text-foreground">Chú thích ({annotations.length})</span>
            {!readOnly && annotations.length > 0 && (
              <Button variant="ghost" size="sm" className="h-7 px-2 text-xs" onClick={() => setAnnotations([])}>
                <Trash2 className="mr-1 h-3.5 w-3.5" /> Xóa hết
              </Button>
            )}
          </div>

          <div className="min-h-0 flex-1 overflow-y-auto p-2">
            {annotations.length === 0 ? (
              <p className="px-2 py-6 text-center text-[11px] leading-relaxed text-muted-foreground">
                {readOnly
                  ? 'Không có chú thích.'
                  : 'Chọn một công cụ rồi vẽ trên lát cắt. (Đa giác: bấm từng đỉnh, nhấn đúp để đóng.)'}
              </p>
            ) : (
              <ul className="space-y-1">
                {annotations.map((an) => (
                  <li key={an.id} className="flex items-center justify-between gap-2 rounded border px-2 py-1 text-[11px]">
                    <span className="flex min-w-0 items-center gap-1.5">
                      <span className="h-2.5 w-2.5 shrink-0 rounded-full" style={{ background: an.color }} />
                      <span className="truncate">
                        {TOOL_LABEL[an.tool]} · {VIEW_LABEL[an.view]} · lát {an.sliceIndex + 1}
                      </span>
                    </span>
                    {!readOnly && (
                      <button type="button" onClick={() => setAnnotations(annotations.filter((x) => x.id !== an.id))}
                        className="shrink-0 text-muted-foreground hover:text-destructive" title="Xóa">
                        <Trash2 className="h-3.5 w-3.5" />
                      </button>
                    )}
                  </li>
                ))}
              </ul>
            )}
          </div>
        </aside>
      </div>
    </div>
  );
}

export default AnnotationTool;
