import { useNavigate } from 'react-router-dom';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { Ban, Check, Copy, FileImage, Maximize2, MoreHorizontal, Star } from 'lucide-react';
import { toast } from 'sonner';
import {
  Badge,
  Button,
  Checkbox,
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuRadioGroup,
  DropdownMenuRadioItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
  TableCell,
  TableRow,
  Tooltip,
  TooltipContent,
  TooltipTrigger,
  cn,
  detailFromApiError,
  assignTask,
  unassignTask,
  finalizeTask,
  reviewTask,
  skipTask,
  setTaskPriority,
  setTaskReference,
  type DatasetMember,
  type DatasetStage,
  type DatasetTask,
} from '@ump/shared';
import { PIPELINE_STATE_META, allowedActions, shortId, stageTone, type BadgeTone } from '../domain/taskView';
import { InitialsAvatar } from './InitialsAvatar';

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',
};

const NONE = '__none__';

/** Map a free priority float onto the three presets offered in the overflow menu. */
function priorityBucket(p: number): 'high' | 'normal' | 'low' {
  if (p >= 0.75) return 'high';
  if (p <= 0.25) return 'low';
  return 'normal';
}
const PRESET_VALUE: Record<'high' | 'normal' | 'low', number> = { high: 1, normal: 0.5, low: 0 };

/** One task row — region 5 columns + region 6 inline assignee, score, expand and overflow actions. */
export function TaskRow({
  datasetId,
  task,
  members,
  stages,
  selected,
  onSelectedChange,
}: {
  datasetId: string;
  task: DatasetTask;
  members: DatasetMember[];
  stages: DatasetStage[];
  selected: boolean;
  onSelectedChange: (checked: boolean) => void;
}) {
  const qc = useQueryClient();
  const navigate = useNavigate();
  const invalidate = () => qc.invalidateQueries({ queryKey: ['imagehub', 'dataset', datasetId, 'tasks'] });

  // One mutation drives every row action; the specific API call is passed in. Server 409 guards
  // surface via the toast.
  const runMut = useMutation({
    mutationFn: (fn: () => Promise<DatasetTask>) => fn(),
    onSuccess: () => invalidate(),
    onError: (e: unknown) => toast.error(detailFromApiError(e, 'Thao tác không thành công')),
  });
  const run = (fn: () => Promise<DatasetTask>) => runMut.mutate(fn);
  const busy = runMut.isPending;

  const a = allowedActions(task);
  const pstate = PIPELINE_STATE_META[task.pipelineState];
  const stageKind = stages.find((s) => s.id === task.currentStageId)?.kind;
  const name = task.name || task.fileLogicalPath;
  const hasMenu = a.canFinalize || a.canReview || a.canSkip || a.canUnassign || a.canSetReference || !a.isTerminal;

  const copyId = () => {
    navigator.clipboard?.writeText(task.id).then(
      () => toast.success('Đã sao chép Task Id'),
      () => toast.error('Không sao chép được'),
    );
  };

  return (
    <TableRow data-state={selected ? 'selected' : undefined}>
      <TableCell className="w-10">
        <Checkbox
          checked={selected}
          onCheckedChange={(v) => onSelectedChange(v === true)}
          aria-label={`Chọn ${name}`}
        />
      </TableCell>

      {/* Datapoint */}
      <TableCell>
        <div className="flex items-center gap-2">
          <FileImage className="h-4 w-4 shrink-0 text-muted-foreground" />
          <span className="max-w-[220px] truncate font-medium" title={name}>
            {name}
          </span>
          {task.isReferenceStandard && (
            <Star className="h-3.5 w-3.5 fill-amber-400 text-amber-500" aria-label="Chuẩn tham chiếu" />
          )}
        </div>
      </TableCell>

      {/* Stage — current stage chip, or a terminal "Hoàn tất" chip at Ground Truth */}
      <TableCell>
        {a.isTerminal || !task.currentStageName ? (
          <Badge variant="outline" className={cn('font-normal', TONE_CLASS[a.isTerminal ? 'done' : pstate.tone])}>
            {a.isTerminal ? 'Hoàn tất' : pstate.label}
          </Badge>
        ) : (
          <Badge variant="outline" className={cn('font-normal', TONE_CLASS[stageTone(stageKind)])}>
            {task.currentStageName}
          </Badge>
        )}
      </TableCell>

      {/* Files — one file per task in this data model */}
      <TableCell className="tabular-nums text-muted-foreground">1</TableCell>

      {/* Task Id — short, copy on click */}
      <TableCell>
        <button
          type="button"
          onClick={copyId}
          title={`${task.id} — bấm để sao chép`}
          className="inline-flex items-center gap-1 font-mono text-xs text-muted-foreground hover:text-foreground"
        >
          {shortId(task.id)}
          <Copy className="h-3 w-3 opacity-0 transition-opacity group-hover/row:opacity-100" />
        </button>
      </TableCell>

      {/* Assignee — inline reassignment (read-only once terminal) */}
      <TableCell>
        {a.isTerminal ? (
          <span className="flex items-center gap-2 text-sm">
            {task.assigneeName ? (
              <>
                <InitialsAvatar name={task.assigneeName} seed={task.assigneeUserId ?? ''} className="h-5 w-5" />
                {task.assigneeName}
              </>
            ) : (
              <span className="text-muted-foreground">—</span>
            )}
          </span>
        ) : (
          <Select
            value={task.assigneeUserId ?? NONE}
            onValueChange={(v) =>
              v === NONE ? run(() => unassignTask(datasetId, task.id)) : run(() => assignTask(datasetId, task.id, v))
            }
          >
            <SelectTrigger className="h-8 w-44 gap-2" disabled={busy}>
              <span className="flex items-center gap-2 truncate">
                {task.assigneeName && (
                  <InitialsAvatar name={task.assigneeName} seed={task.assigneeUserId ?? ''} className="h-5 w-5" />
                )}
                <SelectValue placeholder="Chưa giao" />
              </span>
            </SelectTrigger>
            <SelectContent>
              <SelectItem value={NONE}>Chưa giao</SelectItem>
              {members.map((m) => (
                <SelectItem key={m.userId} value={m.userId}>
                  {m.fullName || m.email}
                </SelectItem>
              ))}
              {task.assigneeUserId && !members.some((m) => m.userId === task.assigneeUserId) && (
                <SelectItem value={task.assigneeUserId}>{task.assigneeName || 'Người khác'}</SelectItem>
              )}
            </SelectContent>
          </Select>
        )}
      </TableCell>

      {/* Score — no scoring backend yet; shows the "not scored" state (matches the reference) */}
      <TableCell>
        <Tooltip>
          <TooltipTrigger asChild>
            <span className="inline-flex">
              <Ban className="h-4 w-4 text-muted-foreground/50" aria-label="Chưa chấm điểm" />
            </span>
          </TooltipTrigger>
          <TooltipContent>Chưa chấm điểm</TooltipContent>
        </Tooltip>
      </TableCell>

      {/* Actions — open in the tool + overflow menu */}
      <TableCell className="text-right">
        <div className="flex items-center justify-end gap-1">
          <Button
            size="icon"
            variant="ghost"
            className="h-8 w-8"
            title="Mở để gán nhãn"
            onClick={() => navigate(`/dashboard/datasets/${datasetId}/tasks/${task.id}`)}
          >
            <Maximize2 className="h-4 w-4" />
          </Button>
          {hasMenu && (
            <DropdownMenu>
              <DropdownMenuTrigger asChild>
                <Button size="icon" variant="ghost" className="h-8 w-8" disabled={busy} title="Thao tác">
                  <MoreHorizontal className="h-4 w-4" />
                </Button>
              </DropdownMenuTrigger>
              <DropdownMenuContent align="end" className="w-52">
                {a.canFinalize && (
                  <DropdownMenuItem onClick={() => run(() => finalizeTask(datasetId, task.id))}>
                    <Check className="mr-2 h-4 w-4" /> Hoàn tất giai đoạn
                  </DropdownMenuItem>
                )}
                {a.canReview && (
                  <>
                    <DropdownMenuItem onClick={() => run(() => reviewTask(datasetId, task.id, 'accept'))}>
                      <Check className="mr-2 h-4 w-4" /> Chấp nhận
                    </DropdownMenuItem>
                    <DropdownMenuItem
                      onClick={() => run(() => reviewTask(datasetId, task.id, 'acceptWithCorrections'))}
                    >
                      Chấp nhận kèm chỉnh sửa
                    </DropdownMenuItem>
                    <DropdownMenuItem
                      className="text-destructive focus:text-destructive"
                      onClick={() => run(() => reviewTask(datasetId, task.id, 'reject'))}
                    >
                      Từ chối — trả lại gán nhãn
                    </DropdownMenuItem>
                  </>
                )}
                {a.canSkip && (
                  <DropdownMenuItem onClick={() => run(() => skipTask(datasetId, task.id))}>
                    Bỏ qua (xuống cuối hàng đợi)
                  </DropdownMenuItem>
                )}
                {a.canUnassign && (
                  <DropdownMenuItem onClick={() => run(() => unassignTask(datasetId, task.id))}>
                    Bỏ phân công
                  </DropdownMenuItem>
                )}
                {a.canSetReference && (
                  <DropdownMenuItem
                    onClick={() => run(() => setTaskReference(datasetId, task.id, !task.isReferenceStandard))}
                  >
                    <Star
                      className={cn('mr-2 h-4 w-4', task.isReferenceStandard && 'fill-amber-400 text-amber-500')}
                    />
                    {task.isReferenceStandard ? 'Bỏ chuẩn tham chiếu' : 'Đặt làm chuẩn tham chiếu'}
                  </DropdownMenuItem>
                )}
                {!a.isTerminal && (
                  <>
                    <DropdownMenuSeparator />
                    <DropdownMenuLabel className="text-xs font-normal text-muted-foreground">
                      Độ ưu tiên
                    </DropdownMenuLabel>
                    <DropdownMenuRadioGroup
                      value={priorityBucket(task.priority ?? 0)}
                      onValueChange={(v) =>
                        run(() => setTaskPriority(datasetId, task.id, PRESET_VALUE[v as 'high' | 'normal' | 'low']))
                      }
                    >
                      <DropdownMenuRadioItem value="high">Cao</DropdownMenuRadioItem>
                      <DropdownMenuRadioItem value="normal">Thường</DropdownMenuRadioItem>
                      <DropdownMenuRadioItem value="low">Thấp</DropdownMenuRadioItem>
                    </DropdownMenuRadioGroup>
                  </>
                )}
                <DropdownMenuSeparator />
                <DropdownMenuItem onClick={copyId}>
                  <Copy className="mr-2 h-4 w-4" /> Sao chép Task Id
                </DropdownMenuItem>
              </DropdownMenuContent>
            </DropdownMenu>
          )}
        </div>
      </TableCell>
    </TableRow>
  );
}

export default TaskRow;
