import { useEffect, useState, type ReactNode } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import {
  ArrowLeft,
  Settings2,
  AlertTriangle,
  Copy,
  Check,
  Trash2,
  Plus,
  Save,
  PenLine,
  ShieldCheck,
  UserPlus,
  Users,
} from 'lucide-react';
import { toast } from 'sonner';
import {
  Badge,
  Button,
  Card,
  CardContent,
  CardHeader,
  CardTitle,
  Input,
  Label,
  Textarea,
  Switch,
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
  cn,
  getDataset,
  updateDataset,
  deleteDataset,
  listDatasetStages,
  addDatasetStage,
  updateDatasetStage,
  deleteDatasetStage,
  listMembers,
  addMember,
  removeMember,
  VISIBILITY_LABEL,
  type DatasetMember,
  type DatasetStage,
  type DatasetVisibility,
  type StageKind,
  type StageUpdateInput,
} from '@ump/shared';

/** One row of the stages table — inline-editable name + review %, the auto-assign Switch, delete. */
function StageRow({ datasetId, stage }: { datasetId: string; stage: DatasetStage }) {
  const qc = useQueryClient();
  const invalidate = () => qc.invalidateQueries({ queryKey: ['imagehub', 'dataset', datasetId, 'stages'] });
  const [name, setName] = useState(stage.name);
  const [percent, setPercent] = useState(stage.reviewPercent == null ? '' : String(stage.reviewPercent));
  useEffect(() => setName(stage.name), [stage.name]);
  useEffect(() => setPercent(stage.reviewPercent == null ? '' : String(stage.reviewPercent)), [stage.reviewPercent]);

  const updateMut = useMutation({
    mutationFn: (input: StageUpdateInput) => updateDatasetStage(datasetId, stage.id, input),
    onSuccess: invalidate,
    onError: () => toast.error('Không cập nhật được giai đoạn'),
  });
  const deleteMut = useMutation({
    mutationFn: () => deleteDatasetStage(datasetId, stage.id),
    onSuccess: () => {
      toast.success('Đã xóa giai đoạn');
      invalidate();
    },
    onError: () => toast.error('Không xóa được giai đoạn'),
  });

  const saveName = () => {
    const v = name.trim();
    if (v && v !== stage.name) updateMut.mutate({ name: v });
    else setName(stage.name);
  };
  const savePercent = () => {
    const v = percent.trim() === '' ? null : Math.max(0, Math.min(100, parseInt(percent, 10) || 0));
    if (v !== stage.reviewPercent) updateMut.mutate({ reviewPercent: v });
  };

  const isReview = stage.kind === 'review';
  return (
    <TableRow>
      <TableCell>
        <div className="flex items-center gap-2">
          <span className={isReview ? 'text-accent' : 'text-primary'}>
            {isReview ? <ShieldCheck className="h-4 w-4" /> : <PenLine className="h-4 w-4" />}
          </span>
          <Input
            value={name}
            onChange={(e) => setName(e.target.value)}
            onBlur={saveName}
            onKeyDown={(e) => {
              if (e.key === 'Enter') e.currentTarget.blur();
            }}
            className="h-8 w-44"
            aria-label="Tên giai đoạn"
          />
        </div>
      </TableCell>
      <TableCell>
        <Badge variant="secondary">{isReview ? 'Kiểm duyệt' : 'Gán nhãn'}</Badge>
      </TableCell>
      <TableCell>
        {isReview ? (
          <div className="flex items-center gap-1">
            <Input
              value={percent}
              onChange={(e) => setPercent(e.target.value.replace(/[^0-9]/g, ''))}
              onBlur={savePercent}
              onKeyDown={(e) => {
                if (e.key === 'Enter') e.currentTarget.blur();
              }}
              className="h-8 w-16 text-right"
              aria-label="Phần trăm kiểm duyệt"
            />
            <span className="text-muted-foreground">%</span>
          </div>
        ) : (
          <span className="text-muted-foreground">—</span>
        )}
      </TableCell>
      <TableCell>
        <Switch
          checked={stage.autoAssign}
          onCheckedChange={(c) => updateMut.mutate({ autoAssign: c })}
          aria-label={`Tự động gán việc cho ${stage.name}`}
        />
      </TableCell>
      <TableCell className="text-right">
        <Button
          variant="ghost"
          size="icon"
          className="h-8 w-8"
          onClick={() => deleteMut.mutate()}
          disabled={deleteMut.isPending}
          title="Xóa giai đoạn"
        >
          <Trash2 className="h-4 w-4" />
        </Button>
      </TableCell>
    </TableRow>
  );
}

/** Members management — add labelers by email, list them, remove. Owner/admin only (BE-gated). */
function MembersCard({ datasetId }: { datasetId: string }) {
  const qc = useQueryClient();
  const [email, setEmail] = useState('');
  const [newRole, setNewRole] = useState<'member' | 'project_admin'>('member');
  const membersQ = useQuery({
    queryKey: ['imagehub', 'dataset', datasetId, 'members'],
    queryFn: () => listMembers(datasetId),
    enabled: !!datasetId,
  });
  const invalidate = () =>
    qc.invalidateQueries({ queryKey: ['imagehub', 'dataset', datasetId, 'members'] });
  const addMut = useMutation({
    mutationFn: () => addMember(datasetId, email.trim(), newRole),
    onSuccess: () => {
      toast.success('Đã thêm thành viên');
      setEmail('');
      invalidate();
    },
    onError: (e: unknown) =>
      toast.error((e as { message?: string })?.message || 'Không thêm được thành viên'),
  });
  const removeMut = useMutation({
    mutationFn: (userId: string) => removeMember(datasetId, userId),
    onSuccess: () => {
      toast.success('Đã xóa thành viên');
      invalidate();
    },
    onError: () => toast.error('Không xóa được thành viên'),
  });
  const members: DatasetMember[] = membersQ.data ?? [];

  return (
    <Card>
      <CardHeader>
        <CardTitle className="flex items-center gap-2 text-base">
          <Users className="h-4 w-4" /> Thành viên
        </CardTitle>
        <p className="text-sm text-muted-foreground">
          Mời người gán nhãn vào bộ dữ liệu. Thành viên có thể xem bộ dữ liệu và xử lý công việc được
          giao cho họ; quản lý bộ dữ liệu vẫn thuộc về chủ sở hữu.
        </p>
      </CardHeader>
      <CardContent className="space-y-3">
        <div className="flex gap-2">
          <Input
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            onKeyDown={(e) => {
              if (e.key === 'Enter' && email.trim()) addMut.mutate();
            }}
            placeholder="email@ump.edu.vn"
            type="email"
            aria-label="Email thành viên"
          />
          <Select value={newRole} onValueChange={(v) => setNewRole(v as 'member' | 'project_admin')}>
            <SelectTrigger className="h-10 w-36">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="member">Thành viên</SelectItem>
              <SelectItem value="project_admin">Quản trị</SelectItem>
            </SelectContent>
          </Select>
          <Button onClick={() => addMut.mutate()} disabled={!email.trim() || addMut.isPending}>
            <UserPlus className="mr-1 h-4 w-4" /> Thêm
          </Button>
        </div>
        {members.length === 0 ? (
          <p className="py-2 text-center text-sm text-muted-foreground">Chưa có thành viên nào.</p>
        ) : (
          <ul className="divide-y rounded-md border">
            {members.map((m) => (
              <li key={m.userId} className="flex items-center justify-between gap-2 px-3 py-2">
                <span className="min-w-0">
                  <span className="block truncate text-sm text-foreground">{m.fullName || m.email}</span>
                  {m.fullName && (
                    <span className="block truncate text-xs text-muted-foreground">{m.email}</span>
                  )}
                </span>
                <span className="flex shrink-0 items-center gap-2">
                  <Badge variant="secondary">
                    {m.role === 'project_admin' ? 'Quản trị' : 'Thành viên'}
                  </Badge>
                  <Button
                    variant="ghost"
                    size="icon"
                    className="h-8 w-8"
                    title="Xóa thành viên"
                    onClick={() => removeMut.mutate(m.userId)}
                    disabled={removeMut.isPending}
                  >
                    <Trash2 className="h-4 w-4" />
                  </Button>
                </span>
              </li>
            ))}
          </ul>
        )}
      </CardContent>
    </Card>
  );
}

function SubNavItem({
  icon,
  label,
  active,
  danger,
  onClick,
}: {
  icon: ReactNode;
  label: string;
  active: boolean;
  danger?: boolean;
  onClick: () => void;
}) {
  return (
    <button
      type="button"
      onClick={onClick}
      className={cn(
        'flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm transition-colors',
        active
          ? danger
            ? 'bg-destructive/10 font-medium text-destructive'
            : 'bg-primary/10 font-medium text-primary'
          : 'text-muted-foreground hover:bg-muted',
      )}
    >
      {icon}
      {label}
    </button>
  );
}

function MetaRow({ label, children }: { label: string; children: ReactNode }) {
  return (
    <div>
      <dt className="text-xs text-muted-foreground">{label}</dt>
      <dd className="mt-0.5 text-sm text-foreground">{children}</dd>
    </div>
  );
}

export function DatasetSettingsPage() {
  const { id = '' } = useParams();
  const navigate = useNavigate();
  const qc = useQueryClient();
  const [section, setSection] = useState<'general' | 'danger'>('general');
  const [copied, setCopied] = useState(false);
  const [confirmDelete, setConfirmDelete] = 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 [name, setName] = useState('');
  const [description, setDescription] = useState('');
  const [visibility, setVisibility] = useState<DatasetVisibility>('private');
  const [tags, setTags] = useState('');
  useEffect(() => {
    const d = dsQ.data;
    if (!d) return;
    setName(d.name);
    setDescription(d.description);
    setVisibility(d.visibility);
    setTags(d.modalityTags.join(', '));
  }, [dsQ.data]);

  const saveMut = useMutation({
    mutationFn: () =>
      updateDataset(id, {
        name: name.trim(),
        description: description.trim(),
        visibility,
        modalityTags: tags
          .split(',')
          .map((t) => t.trim())
          .filter(Boolean),
      }),
    onSuccess: () => {
      toast.success('Đã lưu cài đặt');
      qc.invalidateQueries({ queryKey: ['imagehub', 'dataset', id] });
    },
    onError: () => toast.error('Không lưu được cài đặt'),
  });

  const deleteMut = useMutation({
    mutationFn: () => deleteDataset(id),
    onSuccess: () => {
      toast.success('Đã xóa bộ dữ liệu');
      navigate('/dashboard');
    },
    onError: () => toast.error('Không xóa được bộ dữ liệu'),
  });

  const addStageMut = useMutation({
    mutationFn: (kind: StageKind) => {
      const existing = (stagesQ.data ?? []).map((s) => s.name);
      const base = kind === 'label' ? 'Label' : 'Review';
      let nm = base;
      let i = 1;
      while (existing.includes(nm)) {
        i += 1;
        nm = `${base}_${i}`;
      }
      return addDatasetStage(id, { name: nm, kind, reviewPercent: kind === 'review' ? 100 : null });
    },
    onSuccess: () => qc.invalidateQueries({ queryKey: ['imagehub', 'dataset', id, 'stages'] }),
    onError: () => toast.error('Không thêm được giai đoạn'),
  });

  const ds = dsQ.data;
  const stages = stagesQ.data ?? [];
  const dirty =
    !!ds &&
    (name.trim() !== ds.name ||
      description.trim() !== ds.description ||
      visibility !== ds.visibility ||
      tags
        .split(',')
        .map((t) => t.trim())
        .filter(Boolean)
        .join(',') !== ds.modalityTags.join(','));

  const copyId = async () => {
    try {
      await navigator.clipboard.writeText(id);
      setCopied(true);
      setTimeout(() => setCopied(false), 1500);
    } catch {
      toast.error('Không sao chép được');
    }
  };

  return (
    <div className="mx-auto max-w-5xl space-y-6">
      <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>

      <div>
        <h1 className="font-serif text-2xl font-semibold text-foreground">Cài đặt</h1>
        <p className="text-sm text-muted-foreground">Xem và chỉnh sửa cài đặt của bộ dữ liệu.</p>
      </div>

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

      {ds && (
        <div className="grid gap-6 sm:grid-cols-[200px_1fr]">
          <nav className="space-y-1">
            <SubNavItem
              icon={<Settings2 className="h-4 w-4" />}
              label="Cài đặt chung"
              active={section === 'general'}
              onClick={() => setSection('general')}
            />
            <SubNavItem
              icon={<AlertTriangle className="h-4 w-4" />}
              label="Vùng nguy hiểm"
              active={section === 'danger'}
              danger
              onClick={() => setSection('danger')}
            />
          </nav>

          <div className="space-y-6">
            {section === 'general' && (
              <>
                {/* Read-only metadata */}
                <Card>
                  <CardHeader>
                    <CardTitle className="text-base">Thông tin chung</CardTitle>
                  </CardHeader>
                  <CardContent>
                    <dl className="grid grid-cols-2 gap-4">
                      <MetaRow label="Mã bộ dữ liệu">
                        <span className="flex items-center gap-1">
                          <span className="truncate font-mono text-xs">{ds.id}</span>
                          <button
                            type="button"
                            onClick={copyId}
                            className="text-muted-foreground hover:text-foreground"
                            title="Sao chép"
                          >
                            {copied ? <Check className="h-3.5 w-3.5 text-accent" /> : <Copy className="h-3.5 w-3.5" />}
                          </button>
                        </span>
                      </MetaRow>
                      <MetaRow label="Chủ sở hữu">{ds.ownerEmail || ds.ownerUserId}</MetaRow>
                      <MetaRow label="Ngày tạo">
                        {ds.createdAt ? new Date(ds.createdAt).toLocaleString('vi-VN') : '—'}
                      </MetaRow>
                      <MetaRow label="Nhánh mặc định">
                        <span className="font-mono text-xs">{ds.defaultBranch}</span>
                      </MetaRow>
                      <MetaRow label="Số tệp">{ds.fileCount}</MetaRow>
                      <MetaRow label="Số phiên bản">{ds.versionCount}</MetaRow>
                    </dl>
                  </CardContent>
                </Card>

                {/* Editable fields */}
                <Card>
                  <CardHeader>
                    <CardTitle className="text-base">Chỉnh sửa</CardTitle>
                  </CardHeader>
                  <CardContent className="space-y-4">
                    <div className="space-y-1.5">
                      <Label htmlFor="ds-name">Tên bộ dữ liệu</Label>
                      <Input id="ds-name" value={name} onChange={(e) => setName(e.target.value)} />
                    </div>
                    <div className="space-y-1.5">
                      <Label htmlFor="ds-desc">Mô tả</Label>
                      <Textarea
                        id="ds-desc"
                        value={description}
                        onChange={(e) => setDescription(e.target.value)}
                        rows={3}
                      />
                    </div>
                    <div className="grid gap-4 sm:grid-cols-2">
                      <div className="space-y-1.5">
                        <Label>Phạm vi</Label>
                        <Select value={visibility} onValueChange={(v) => setVisibility(v as DatasetVisibility)}>
                          <SelectTrigger>
                            <SelectValue />
                          </SelectTrigger>
                          <SelectContent>
                            <SelectItem value="private">{VISIBILITY_LABEL.private}</SelectItem>
                            <SelectItem value="internal">{VISIBILITY_LABEL.internal}</SelectItem>
                            <SelectItem value="public">{VISIBILITY_LABEL.public}</SelectItem>
                          </SelectContent>
                        </Select>
                      </div>
                      <div className="space-y-1.5">
                        <Label htmlFor="ds-tags">Thẻ phương thức</Label>
                        <Input
                          id="ds-tags"
                          value={tags}
                          onChange={(e) => setTags(e.target.value)}
                          placeholder="CT, MRI, Kidney…"
                        />
                      </div>
                    </div>
                    <div className="flex justify-end">
                      <Button onClick={() => saveMut.mutate()} disabled={!dirty || saveMut.isPending}>
                        <Save className="mr-2 h-4 w-4" /> {saveMut.isPending ? 'Đang lưu…' : 'Lưu thay đổi'}
                      </Button>
                    </div>
                  </CardContent>
                </Card>

                {/* Stages pipeline — the labeling workflow */}
                <Card>
                  <CardHeader>
                    <CardTitle className="text-base">Giai đoạn xử lý</CardTitle>
                    <p className="text-sm text-muted-foreground">
                      Quy trình gán nhãn và kiểm duyệt cho bộ dữ liệu này. Bật “Tự động gán việc” để hệ thống
                      phân công nhiệm vụ ở mỗi giai đoạn.
                    </p>
                  </CardHeader>
                  <CardContent>
                    {stages.length === 0 ? (
                      <p className="py-4 text-center text-sm text-muted-foreground">
                        Chưa có giai đoạn nào. Thêm giai đoạn gán nhãn hoặc kiểm duyệt bên dưới.
                      </p>
                    ) : (
                      <Table>
                        <TableHeader>
                          <TableRow>
                            <TableHead>Tên giai đoạn</TableHead>
                            <TableHead>Loại</TableHead>
                            <TableHead>Review %</TableHead>
                            <TableHead>Tự động gán việc</TableHead>
                            <TableHead className="w-12" />
                          </TableRow>
                        </TableHeader>
                        <TableBody>
                          {stages.map((s) => (
                            <StageRow key={s.id} datasetId={id} stage={s} />
                          ))}
                        </TableBody>
                      </Table>
                    )}
                    <div className="mt-3 flex gap-2">
                      <Button
                        variant="outline"
                        size="sm"
                        onClick={() => addStageMut.mutate('label')}
                        disabled={addStageMut.isPending}
                      >
                        <Plus className="mr-1 h-4 w-4" /> Giai đoạn gán nhãn
                      </Button>
                      <Button
                        variant="outline"
                        size="sm"
                        onClick={() => addStageMut.mutate('review')}
                        disabled={addStageMut.isPending}
                      >
                        <Plus className="mr-1 h-4 w-4" /> Giai đoạn kiểm duyệt
                      </Button>
                    </div>
                  </CardContent>
                </Card>

                <MembersCard datasetId={id} />
              </>
            )}

            {section === 'danger' && (
              <Card className="border-destructive/40">
                <CardHeader>
                  <CardTitle className="text-base text-destructive">Xóa bộ dữ liệu</CardTitle>
                </CardHeader>
                <CardContent>
                  <p className="mb-3 text-sm text-muted-foreground">
                    Hành động này không thể hoàn tác. Toàn bộ tệp, phiên bản, giai đoạn và nhật ký của bộ dữ liệu
                    sẽ bị xóa vĩnh viễn.
                  </p>
                  {!confirmDelete ? (
                    <Button variant="destructive" onClick={() => setConfirmDelete(true)}>
                      <Trash2 className="mr-2 h-4 w-4" /> Xóa bộ dữ liệu
                    </Button>
                  ) : (
                    <div className="flex items-center gap-2">
                      <span className="text-sm font-medium">Bạn chắc chắn?</span>
                      <Button
                        variant="destructive"
                        onClick={() => deleteMut.mutate()}
                        disabled={deleteMut.isPending}
                      >
                        {deleteMut.isPending ? 'Đang xóa…' : 'Xóa vĩnh viễn'}
                      </Button>
                      <Button variant="ghost" onClick={() => setConfirmDelete(false)}>
                        Hủy
                      </Button>
                    </div>
                  )}
                </CardContent>
              </Card>
            )}
          </div>
        </div>
      )}
    </div>
  );
}

export default DatasetSettingsPage;
