import { useEffect, useMemo, useState } from 'react';
import { Link, useNavigate, useParams } from 'react-router-dom';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import {
  ArrowLeft,
  Boxes,
  CalendarClock,
  ClipboardCheck,
  Coins,
  FileText,
  FlaskConical,
  Info,
  Lock,
  Plus,
  ScrollText,
  Search,
} from 'lucide-react';

import {
  Button,
  Card,
  CardContent,
  Input,
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
  createEntity,
  deleteEntity,
  getCockpit,
  listDatasets,
  updateEntity,
  useAuth,
  type CockpitBundle,
  type CockpitEntity,
  type EntityRow,
} from '@ump/shared';

import {
  ENTITIES,
  ENTITY_ORDER,
  asNum,
  asStr,
  fmt,
  pct,
  type CockpitEntityKey,
  type EntityConfig,
} from '../components/cockpit/cockpitConfig';
import { Bar, EntityCard, EntityDrawer } from '../components/cockpit/CockpitWidgets';
import { CockpitSidebar } from '../components/cockpit/CockpitSidebar';
import { DetailSectionPanel } from '../components/cockpit/CockpitDetail';
import { SECTION_BY_TAB } from '../components/cockpit/detailConfig';
import { TeamManagementView } from '../components/cockpit/TeamManagementView';
import { DatasetNav, WorkspacePanel } from '../features/dataset-workspace/presentation/WorkspacePanel';

/* ----------------------------- overview widgets ---------------------------- */
// Folded into the relevant admin-detail tabs (Thông tin chung / Kinh phí / Thời gian).
function MilestonesCard({ bundle }: { bundle: CockpitBundle }) {
  return (
    <Card>
      <CardContent className="p-5">
        <h3 className="mb-3 flex items-center gap-2 font-semibold text-foreground">
          <CalendarClock size={16} className="text-rose-600" /> Tiến độ nội dung nghiên cứu
        </h3>
        {bundle.milestones.length === 0 ? (
          <p className="text-sm text-muted-foreground">Chưa có mốc tiến độ.</p>
        ) : (
          <div className="space-y-3">
            {bundle.milestones.map((m) => (
              <div key={m.id}>
                <div className="mb-1 flex justify-between text-sm">
                  <span className="truncate pr-2 text-foreground">{asStr(m.title)}</span>
                  <span className="shrink-0 tabular-nums text-muted-foreground">{pct(m.progress)}%</span>
                </div>
                <Bar value={m.progress} tone={m.status === 'Trễ hạn' ? 'bg-rose-500' : m.status === 'Hoàn thành' ? 'bg-emerald-500' : 'bg-primary'} />
              </div>
            ))}
          </div>
        )}
      </CardContent>
    </Card>
  );
}

function BestModelCard({ bundle }: { bundle: CockpitBundle }) {
  const best = [...bundle.models].sort((a, b) => asNum(b.auc) - asNum(a.auc))[0];
  return (
    <Card>
      <CardContent className="p-5">
        <h3 className="mb-2 flex items-center gap-2 font-semibold text-foreground">
          <FlaskConical size={16} className="text-violet-600" /> Mô hình tốt nhất
        </h3>
        {best && asNum(best.auc) > 0 ? (
          <>
            <div className="text-sm font-medium text-foreground">{asStr(best.name)}</div>
            <div className="mb-2 text-xs text-muted-foreground">{asStr(best.task)}</div>
            <div className="flex gap-3 text-sm">
              <div>
                <div className="text-2xl font-semibold tabular-nums text-violet-600">{asNum(best.auc).toFixed(2)}</div>
                <div className="text-xs text-muted-foreground">AUC</div>
              </div>
              <div>
                <div className="text-2xl font-semibold tabular-nums text-foreground">{asNum(best.sensitivity).toFixed(2)}</div>
                <div className="text-xs text-muted-foreground">Độ nhạy</div>
              </div>
              <div>
                <div className="text-2xl font-semibold tabular-nums text-foreground">{asNum(best.specificity).toFixed(2)}</div>
                <div className="text-xs text-muted-foreground">Độ đặc hiệu</div>
              </div>
            </div>
          </>
        ) : (
          <div className="text-sm text-muted-foreground">Chưa có kết quả đánh giá.</div>
        )}
      </CardContent>
    </Card>
  );
}

function BudgetCard({ bundle }: { bundle: CockpitBundle }) {
  const allocated = bundle.milestones.reduce((s, m) => s + asNum(m.budget), 0);
  const budgetTotal = asNum(bundle.project.budgetTotal);
  return (
    <Card>
      <CardContent className="p-5">
        <h3 className="mb-2 font-semibold text-foreground">Ngân sách</h3>
        <div className="mb-1 text-sm text-muted-foreground">Đã phân bổ theo nội dung</div>
        <div className="text-2xl font-semibold tabular-nums text-foreground">
          {fmt(allocated)} <span className="text-sm font-normal text-muted-foreground">/ {fmt(budgetTotal)} tr.đ</span>
        </div>
        <div className="mt-2">
          <Bar value={budgetTotal ? (allocated / budgetTotal) * 100 : 0} tone="bg-amber-500" />
        </div>
      </CardContent>
    </Card>
  );
}

/* ------------------------------ audit view ------------------------------ */
function AuditView({ bundle }: { bundle: CockpitBundle }) {
  return (
    <div>
      <p className="mb-4 max-w-2xl text-sm text-muted-foreground">
        Nhật ký chỉ-thêm (append-only). Mỗi thay đổi ghi lại ai thao tác, lúc nào và nội dung cụ thể.
      </p>
      <Card>
        <CardContent className="p-0">
          {bundle.audit.length === 0 ? (
            <div className="px-4 py-10 text-center text-sm text-muted-foreground">Chưa có bản ghi.</div>
          ) : (
            bundle.audit.map((e, i) => (
              <div key={e.id} className={'flex flex-wrap items-center gap-x-4 gap-y-1 px-4 py-3 text-sm ' + (i ? 'border-t border-border' : '')}>
                <span className="w-40 shrink-0 font-mono text-xs text-muted-foreground">
                  {e.occurredAt ? new Date(e.occurredAt).toLocaleString('vi-VN') : ''}
                </span>
                <span className="w-48 shrink-0 text-foreground">
                  {e.actorName} <span className="text-muted-foreground">· {e.roleLabel}</span>
                </span>
                <span className="min-w-0 flex-1 text-muted-foreground">
                  {e.action} <span className="font-mono text-xs">{e.subject}</span>
                </span>
                {e.detail && <span className="shrink-0 font-mono text-xs text-muted-foreground">{e.detail}</span>}
              </div>
            ))
          )}
        </CardContent>
      </Card>
    </div>
  );
}

/* ------------------------------ entity view ----------------------------- */
function buildDraft(config: EntityConfig, item?: EntityRow): Record<string, string> {
  const d: Record<string, string> = {};
  for (const f of config.fields) {
    if (item) {
      const v = item[f.key];
      d[f.key] = v === undefined || v === null ? '' : String(v);
    } else {
      d[f.key] = f.default ?? '';
    }
  }
  return d;
}

function EntityView({
  entityKey,
  bundle,
  projectId,
  canEdit,
}: {
  entityKey: CockpitEntityKey;
  bundle: CockpitBundle;
  projectId: string;
  canEdit: boolean;
}) {
  const config = ENTITIES[entityKey];
  const items = bundle[entityKey];
  const qc = useQueryClient();
  const [q, setQ] = useState('');
  const [statusFilter, setStatusFilter] = useState('Tất cả');
  const [drawer, setDrawer] = useState<{ id: string | null; data: Record<string, string> } | null>(null);

  const statuses = useMemo(() => {
    const badgeField = config.fields.find((f) => f.key === config.badge);
    return ['Tất cả', ...(badgeField?.options ?? [])];
  }, [config]);

  const invalidate = () => qc.invalidateQueries({ queryKey: ['cockpit', projectId] });
  const saveMut = useMutation({
    mutationFn: (vars: { id: string | null; data: Record<string, string> }) =>
      vars.id
        ? updateEntity(projectId, entityKey as CockpitEntity, vars.id, vars.data)
        : createEntity(projectId, entityKey as CockpitEntity, vars.data),
    onSuccess: () => {
      invalidate();
      toast.success('Đã lưu.');
      setDrawer(null);
    },
    onError: () => toast.error('Lưu thất bại.'),
  });
  const delMut = useMutation({
    mutationFn: (itemId: string) => deleteEntity(projectId, entityKey as CockpitEntity, itemId),
    onSuccess: () => {
      invalidate();
      toast.success('Đã xóa.');
    },
    onError: () => toast.error('Xóa thất bại.'),
  });

  const filtered = items.filter((it) => {
    const mq = !q || JSON.stringify(it).toLowerCase().includes(q.toLowerCase());
    const ms = statusFilter === 'Tất cả' || asStr(it[config.badge]) === statusFilter;
    return mq && ms;
  });

  const remove = (it: EntityRow) => {
    if (!window.confirm(`Xóa ${config.singular} "${asStr(it[config.primary])}"?`)) return;
    delMut.mutate(it.id);
  };

  return (
    <div>
      {!canEdit && (
        <div className="mb-4 flex items-center gap-2 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-800">
          <Lock size={15} /> Bạn chỉ được xem mục này. Thêm / sửa / xóa đã bị khóa.
        </div>
      )}

      <div className="mb-4 flex flex-wrap items-center gap-2">
        <div className="relative min-w-0 flex-1">
          <Search size={15} className="absolute left-3 top-2.5 text-muted-foreground" />
          <Input value={q} onChange={(e) => setQ(e.target.value)} placeholder={`Tìm ${config.singular}...`} className="pl-9" />
        </div>
        <Select value={statusFilter} onValueChange={setStatusFilter}>
          <SelectTrigger className="w-44">
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            {statuses.map((s) => (
              <SelectItem key={s} value={s}>
                {s}
              </SelectItem>
            ))}
          </SelectContent>
        </Select>
        <Button
          onClick={() => setDrawer({ id: null, data: buildDraft(config) })}
          disabled={!canEdit}
          title={canEdit ? '' : 'Không có quyền'}
        >
          {canEdit ? <Plus size={16} className="mr-1.5" /> : <Lock size={15} className="mr-1.5" />} Thêm
        </Button>
      </div>

      {filtered.length === 0 ? (
        <div className="rounded-xl border border-dashed border-border py-16 text-center text-sm text-muted-foreground">
          Chưa có {config.singular} nào phù hợp.
        </div>
      ) : (
        <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
          {filtered.map((it) => (
            <EntityCard
              key={it.id}
              config={config}
              item={it}
              canEdit={canEdit}
              onEdit={() => setDrawer({ id: it.id, data: buildDraft(config, it) })}
              onDelete={() => remove(it)}
            />
          ))}
        </div>
      )}

      {drawer && (
        <EntityDrawer
          open
          isNew={drawer.id === null}
          config={config}
          draft={drawer.data}
          onChange={(k, v) => setDrawer((d) => (d ? { ...d, data: { ...d.data, [k]: v } } : d))}
          onSave={() => saveMut.mutate(drawer)}
          onClose={() => setDrawer(null)}
          saving={saveMut.isPending}
        />
      )}
    </div>
  );
}

/* --------------------------------- page --------------------------------- */
export function CockpitPage() {
  const { id = '' } = useParams();
  const navigate = useNavigate();
  const { user, hasRole } = useAuth();
  const [tab, setTab] = useState<string>('general');

  const { data: bundle, isLoading, isError } = useQuery({
    queryKey: ['cockpit', id],
    queryFn: () => getCockpit(id),
    enabled: !!id,
  });

  // The cockpit is for approved projects; bounce anything else back to the proposal view.
  useEffect(() => {
    if (bundle && bundle.project.status !== 'approved') {
      navigate(`/dashboard/proposals/${id}`, { replace: true });
    }
  }, [bundle, id, navigate]);

  // Imaging datasets for the "Dữ liệu hình ảnh" tab — the selector ("Bộ dữ liệu") lives in the
  // sidebar, so this query + selection are owned here and shared with the sidebar nav + the pane.
  const isWorkspace = tab === 'workspace';
  const [selectedDataset, setSelectedDataset] = useState<string | null>(null);
  const dsQuery = useQuery({
    queryKey: ['imagehub', 'datasets', 'project', id],
    queryFn: () => listDatasets({ projectId: id }),
    enabled: isWorkspace,
  });

  if (isLoading) return <div className="p-6 text-sm text-muted-foreground">Đang tải…</div>;
  if (isError || !bundle) return <div className="p-6 text-sm text-destructive">Không tải được đề tài.</div>;

  const canEdit = hasRole('admin') || user?.id === bundle.project.ownerUserId;

  // Tab bar: the administrative-detail sheet first (Thông tin chung … Nghiệm thu),
  // then the research-management tabs (members / data / models / assets / milestones / log).
  const DETAIL_TABS = new Set(['general', 'contract', 'funding', 'timeline', 'acceptance']);
  const tabs = [
    { key: 'general', title: 'Thông tin chung', icon: Info },
    { key: 'contract', title: 'Hợp đồng', icon: FileText },
    { key: 'funding', title: 'Kinh phí', icon: Coins },
    { key: 'timeline', title: 'Thời gian', icon: CalendarClock },
    { key: 'acceptance', title: 'Nghiệm thu', icon: ClipboardCheck },
    // "Dữ liệu" routes straight to the imaging workspace ("Dữ liệu hình ảnh") — the generic
    // datasets CRUD is folded in, since in ImageHub the project data IS the image data.
    ...ENTITY_ORDER.flatMap((k) =>
      k === 'datasets'
        ? [{ key: 'workspace', title: 'Dữ liệu hình ảnh', icon: Boxes }]
        : [{ key: k as string, title: ENTITIES[k].title, icon: ENTITIES[k].icon }],
    ),
    { key: 'audit', title: 'Nhật ký', icon: ScrollText },
  ];

  const content = (bundle.project.content ?? {}) as Record<string, unknown>;
  const datasets = dsQuery.data ?? [];
  const activeDatasetId = selectedDataset ?? datasets[0]?.id ?? null;

  return (
    <div className="mx-auto max-w-7xl space-y-4">
      <Link to="/dashboard/projects" className="inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground">
        <ArrowLeft size={15} /> Đề tài của tôi
      </Link>

      <div className="grid gap-5 lg:grid-cols-[300px_minmax(0,1fr)]">
        <div className="lg:sticky lg:top-4 lg:self-start">
          <CockpitSidebar
            bundle={bundle}
            datasetNav={
              isWorkspace ? (
                <DatasetNav
                  datasets={datasets}
                  activeId={activeDatasetId}
                  onSelect={setSelectedDataset}
                  projectId={id}
                  loading={dsQuery.isLoading}
                  error={dsQuery.isError}
                />
              ) : undefined
            }
          />
        </div>

        <div className="min-w-0 space-y-5">
          <div className="flex gap-1 overflow-x-auto border-b border-border">
            {tabs.map((t) => {
              const Icon = t.icon;
              const active = tab === t.key;
              const count =
                t.key === 'audit'
                  ? bundle.audit.length
                  : DETAIL_TABS.has(t.key) || t.key === 'workspace'
                    ? null
                    : bundle[t.key as CockpitEntityKey].length;
              return (
                <button
                  key={t.key}
                  onClick={() => setTab(t.key)}
                  className={
                    'inline-flex items-center gap-1.5 whitespace-nowrap border-b-2 px-3 py-2.5 text-sm font-medium transition-colors ' +
                    (active
                      ? 'border-primary text-foreground'
                      : 'border-transparent text-muted-foreground hover:text-foreground')
                  }
                >
                  <Icon size={15} /> {t.title}
                  {count != null && (
                    <span
                      className={
                        'rounded-full px-1.5 text-xs ' +
                        (active ? 'bg-primary/10 text-primary' : 'bg-muted text-muted-foreground')
                      }
                    >
                      {count}
                    </span>
                  )}
                </button>
              );
            })}
          </div>

          {DETAIL_TABS.has(tab) ? (
            <div className="space-y-5">
              <DetailSectionPanel
                section={SECTION_BY_TAB[tab]}
                content={content}
                projectId={id}
                canEdit={canEdit}
              />
              {tab === 'general' && <BestModelCard bundle={bundle} />}
              {tab === 'funding' && <BudgetCard bundle={bundle} />}
              {tab === 'timeline' && <MilestonesCard bundle={bundle} />}
            </div>
          ) : tab === 'workspace' ? (
            <WorkspacePanel
              projectId={id}
              datasetId={activeDatasetId}
              loading={dsQuery.isLoading}
              error={dsQuery.isError}
              isEmpty={datasets.length === 0}
            />
          ) : tab === 'audit' ? (
            <AuditView bundle={bundle} />
          ) : tab === 'members' ? (
            <TeamManagementView members={bundle.members} projectId={id} canEdit={canEdit} />
          ) : (
            <EntityView entityKey={tab as CockpitEntityKey} bundle={bundle} projectId={id} canEdit={canEdit} />
          )}
        </div>
      </div>
    </div>
  );
}
