import Link from "next/link";
import { Avatar } from "@/components/avatar";
import { Badge, ProgressBar, SectionTitle, StatCard, TableWrap, TierBadge } from "@/components/ui";
import { PlanActualChart, RankBarChart, ShareChart, StaffingChart, TierChart, TrendChart } from "@/components/charts";
import { formatDate, formatNumber, formatPercent, formatPeriod, formatVnd, formatVndShort, STAGE_LABEL } from "@/lib/format";
import { REVENUE_TIERS } from "@/lib/classification";
import type { CustomerOverview, CustomerRankRow, NewByGroup, NewCustomerRow } from "@/lib/customer-report";
import type { PlanReport, ProductReportRow, PromoReport, SalesOverview, StaffingReport, TrendRow, TreeRow, ShareRow } from "@/lib/sales-analysis";

/* Các khối hiển thị của trang Phân tích bán hàng. Trang (page.tsx) lo tham số, quyền và tải dữ liệu; file này chỉ vẽ. */

const ROLE_LABEL: Record<string, string> = { CORE: "Chủ lực", POTENTIAL: "Tiềm năng", RECOVERY: "Khôi phục", NORMAL: "Thường" };
const roleTone = (role: string) => (role === "CORE" ? "brand" : role === "RECOVERY" ? "red" : "neutral");

/** Tên đối tượng của bảng dạng cây — thụt lề theo cấp (miền → tỉnh, phòng → team). */
function TreeName({ name, depth, bold }: { name: string; depth: number; bold?: boolean }) {
  return (
    <span style={{ paddingLeft: depth * 18 }} className={depth === 0 || bold ? "font-semibold text-ink-700" : "text-ink-600"}>
      {depth > 0 && <span className="mr-1 text-ink-300">└</span>}
      {name}
    </span>
  );
}

/** Chọn nhóm nút để vẽ biểu đồ: cấp nông nhất có từ 2 phần tử trở lên (miền; nếu chỉ có một miền thì vẽ các tỉnh của nó). */
export function chartLevel<T>(rows: TreeRow<T>[]): TreeRow<T>[] {
  for (let depth = 0; depth < 6; depth++) {
    const level = rows.filter((r) => r.depth === depth);
    if (level.length >= 2) return level;
  }
  return rows;
}

const Empty = ({ cols }: { cols: number }) => (
  <tr>
    <td colSpan={cols} className="py-8 text-center text-ink-400">
      Không có dữ liệu trong kỳ.
    </td>
  </tr>
);

/* -------------------------------------------------------------------------- */
/* Tổng quan                                                                  */
/* -------------------------------------------------------------------------- */

const growth = (now: number, before: number): { text: string; tone: "good" | "bad" | "default" } => {
  if (before <= 0) return { text: "kỳ trước chưa có doanh thu", tone: "default" };
  const pct = ((now - before) / before) * 100;
  return { text: `${pct >= 0 ? "▲" : "▼"} ${formatPercent(Math.abs(pct), 1)} so với kỳ trước`, tone: pct >= 0 ? "good" : "bad" };
};

export function OverviewView(props: {
  period: string;
  overview: SalesOverview;
  previousRevenue: number;
  target: { revenueTarget: number } | null;
  debt: { revenue: number; collected: number; outstanding: number; overdue: number; collectionRate: number | null };
  promoValue: number;
  staffing: StaffingReport["overall"];
  trend: TrendRow[];
  regionShare: TreeRow<ShareRow>[];
  tiers: { tier: string; count: number }[];
  keyDealers: { id: string; orgName: string; code: string; tier: string | null; avgRevenue: number; skuCount: number }[];
}) {
  const { overview, target, debt, staffing, trend } = props;
  const g = growth(overview.revenue, props.previousRevenue);
  const promoRatio = overview.revenue > 0 ? (props.promoValue / overview.revenue) * 100 : 0;
  const year = props.period.slice(0, 4);
  const yearTotal = trend.reduce(
    (acc, r) => ({ sales: acc.sales + r.sales, revenue: acc.revenue + r.revenue, collected: acc.collected + r.collected, outstanding: acc.outstanding + r.outstanding, orders: acc.orders + r.orders }),
    { sales: 0, revenue: 0, collected: 0, outstanding: 0, orders: 0 },
  );
  const activeMonths = new Set(
    props.period.length === 4
      ? trend.map((r) => r.month)
      : /Q/.test(props.period)
        ? trend.filter((r) => Math.ceil(Number(r.month.slice(5, 7)) / 3) === Number(props.period.slice(-1))).map((r) => r.month)
        : [props.period],
  );

  return (
    <>
      <div className="grid grid-cols-2 gap-3 lg:grid-cols-4">
        <StatCard label="Doanh số" value={formatVndShort(overview.sales)} hint={`${formatNumber(overview.salesOrders)} đơn đã lập${overview.pendingOrders > 0 ? ` · ${overview.pendingOrders} chờ duyệt` : ""}`} />
        <StatCard label="Doanh thu thực hiện" value={formatVndShort(overview.revenue)} hint={<span className={g.tone === "good" ? "text-emerald-700" : g.tone === "bad" ? "text-red-600" : ""}>{g.text}</span>} />
        <StatCard
          label="% Hoàn thành kế hoạch"
          value={target && target.revenueTarget > 0 ? formatPercent((overview.revenue / target.revenueTarget) * 100) : "—"}
          hint={target ? `Kế hoạch ${formatVndShort(target.revenueTarget)}` : "Chưa giao chỉ tiêu"}
          tone={target && target.revenueTarget > 0 ? (overview.revenue >= target.revenueTarget ? "good" : "warn") : "default"}
        />
        <StatCard
          label="Định biên doanh thu / NVKD"
          value={staffing.perHead != null ? formatVndShort(staffing.perHead) : "—"}
          hint={`${staffing.headcount} NVKD · ${staffing.withOrders} người có đơn`}
        />
      </div>

      <div className="mt-3 grid grid-cols-2 gap-3 lg:grid-cols-4">
        <StatCard label="Đã thu" value={formatVndShort(debt.collected)} hint={debt.collectionRate != null ? `${formatPercent(debt.collectionRate)} phải thu` : undefined} tone="good" />
        <StatCard label="Còn phải thu" value={formatVndShort(debt.outstanding)} hint="tiền hàng + phụ thu − đã thu" tone={debt.outstanding > 0 ? "warn" : "default"} />
        <StatCard label="Quá hạn" value={formatVndShort(debt.overdue)} hint="Đơn đã qua hạn thanh toán" tone={debt.overdue > 0 ? "bad" : "default"} />
        <StatCard label="Giá trị hàng khuyến mãi / doanh thu" value={formatPercent(promoRatio, 1)} hint={formatVnd(props.promoValue)} tone={promoRatio > 15 ? "warn" : "default"} />
      </div>

      <div className="mt-6">
        <SectionTitle hint={`năm ${year} · kỳ đang xem được tô đậm`}>Doanh số – doanh thu – công nợ theo tháng</SectionTitle>
        <div className="card p-4">
          <TrendChart data={trend.map((r) => ({ label: `T${Number(r.month.slice(5, 7))}`, sales: r.sales, revenue: r.revenue, collected: r.collected }))} />
        </div>
        <div className="mt-3">
          <TableWrap>
            <thead>
              <tr>
                <th>Tháng</th>
                <th className="text-right">Số đơn duyệt</th>
                <th className="text-right">Doanh số</th>
                <th className="text-right">Doanh thu</th>
                <th className="text-right">Đã thu</th>
                <th className="text-right">Còn phải thu</th>
              </tr>
            </thead>
            <tbody>
              {trend.map((r) => (
                <tr key={r.month} className={activeMonths.has(r.month) ? "bg-brand-50/60" : ""}>
                  <td className="font-medium text-ink-700">{formatPeriod(r.month)}</td>
                  <td className="tnum text-right text-ink-500">{r.orders || "—"}</td>
                  <td className="tnum text-right text-ink-500">{r.sales ? formatVndShort(r.sales) : "—"}</td>
                  <td className="tnum text-right font-semibold">{r.revenue ? formatVndShort(r.revenue) : "—"}</td>
                  <td className="tnum text-right text-ink-500">{r.collected ? formatVndShort(r.collected) : "—"}</td>
                  <td className="tnum text-right text-gold-500">{r.outstanding > 0 ? formatVndShort(r.outstanding) : "—"}</td>
                </tr>
              ))}
              <tr className="border-t-2 border-[var(--color-line)] font-semibold">
                <td>Cả năm {year}</td>
                <td className="tnum text-right">{yearTotal.orders}</td>
                <td className="tnum text-right">{formatVndShort(yearTotal.sales)}</td>
                <td className="tnum text-right">{formatVndShort(yearTotal.revenue)}</td>
                <td className="tnum text-right">{formatVndShort(yearTotal.collected)}</td>
                <td className="tnum text-right text-gold-500">{formatVndShort(yearTotal.outstanding)}</td>
              </tr>
            </tbody>
          </TableWrap>
          <p className="mt-2 text-xs text-ink-400">
            Doanh số = đơn đã lập chưa huỷ; doanh thu = đơn đã duyệt (không tính phụ thu phí); đã thu tính về tháng của đơn; còn phải thu = doanh thu + phụ thu − đã thu.
          </p>
        </div>
      </div>

      <div className="mt-6 grid gap-4 lg:grid-cols-3">
        <div className="card p-4">
          <SectionTitle hint="theo khu vực">Tỷ trọng thị trường</SectionTitle>
          <ShareChart data={chartLevel(props.regionShare).map((r) => ({ name: r.name, value: r.revenue }))} />
        </div>
        <div className="card p-4">
          <SectionTitle hint="doanh thu BQ tháng">Phân bố hạng đại lý</SectionTitle>
          <TierChart data={props.tiers} />
          <div className="mt-2 flex flex-wrap gap-x-3 gap-y-1 text-[11px] text-ink-400">
            {REVENUE_TIERS.map((t) => (
              <span key={t.tier}>{t.label}</span>
            ))}
          </div>
        </div>
        <div className="card p-4">
          <SectionTitle hint="do quản lý đánh dấu">Nhóm đại lý Key</SectionTitle>
          {props.keyDealers.length === 0 ? (
            <p className="py-8 text-center text-sm text-ink-400">Chưa đánh dấu đại lý Key nào.</p>
          ) : (
            <ul className="flex flex-col gap-2 text-sm">
              {props.keyDealers.map((d) => (
                <li key={d.id} className="flex items-center justify-between gap-2">
                  <span className="min-w-0 truncate">
                    <Link href={`/khach-hang/${d.id}`} className="font-medium text-ink-700 hover:text-brand-600">
                      {d.orgName}
                    </Link>
                    <span className="ml-1.5 text-[11px] text-ink-400">{d.code}</span>
                  </span>
                  <span className="flex shrink-0 items-center gap-2">
                    <TierBadge tier={d.tier} />
                    <span className="tnum text-xs text-ink-500">{formatVndShort(d.avgRevenue)}</span>
                  </span>
                </li>
              ))}
            </ul>
          )}
        </div>
      </div>
    </>
  );
}

/* -------------------------------------------------------------------------- */
/* Kế hoạch – thực hiện                                                       */
/* -------------------------------------------------------------------------- */

export function PlanView({ plan, benchmark, dimensionLabel }: { plan: PlanReport; benchmark: number; dimensionLabel: string }) {
  const withTarget = plan.rows.filter((r) => r.target != null && r.target > 0);
  const gapLabel = (gap: number | null) =>
    gap == null ? "—" : gap > 0 ? <span className="text-gold-500">thiếu {formatVndShort(gap)}</span> : <span className="text-emerald-700">vượt {formatVndShort(-gap)}</span>;
  return (
    <>
      {!plan.comparable && (
        <p className="mb-3 rounded-lg border border-gold-100 bg-gold-50 px-3 py-2 text-xs text-gold-500">
          Đang thu hẹp theo một đối tượng khác loại với bảng này, nên chỉ hiện doanh thu thực hiện. Chọn “Toàn bộ phạm vi của tôi” để so với kế hoạch {dimensionLabel.toLowerCase()}.
        </p>
      )}
      {withTarget.length > 0 && (
        <div className="card mb-4 p-4">
          <SectionTitle hint="kế hoạch (xám) so với thực hiện (cam)">Biểu đồ kế hoạch – thực hiện</SectionTitle>
          <PlanActualChart data={withTarget.slice(0, 12).map((r) => ({ name: r.name, target: r.target ?? 0, actual: r.actual }))} />
        </div>
      )}
      <TableWrap>
        <thead>
          <tr>
            <th>{dimensionLabel}</th>
            <th className="text-right">Kế hoạch</th>
            <th className="text-right">Thực hiện (doanh thu)</th>
            <th style={{ width: 150 }}>% Hoàn thành</th>
            <th className="text-right">Chênh lệch</th>
            <th className="text-right">Doanh số</th>
            <th className="text-right">Tỷ trọng</th>
          </tr>
        </thead>
        <tbody>
          {plan.rows.length === 0 && <Empty cols={7} />}
          {plan.rows.map((row) => (
            <tr key={row.id}>
              <td>
                <TreeName name={row.name} depth={row.depth} />
              </td>
              <td className="tnum text-right text-ink-400">{row.target != null ? formatVndShort(row.target) : "—"}</td>
              <td className="tnum text-right font-semibold">{formatVndShort(row.actual)}</td>
              <td>
                <div className="tnum mb-1 text-xs font-semibold text-ink-600">{row.pct != null ? formatPercent(row.pct) : "—"}</div>
                {row.pct != null && <ProgressBar percent={row.pct} benchmark={benchmark} />}
              </td>
              <td className="tnum text-right text-xs">{gapLabel(row.gap)}</td>
              <td className="tnum text-right text-ink-500">{row.sales ? formatVndShort(row.sales) : "—"}</td>
              <td className="tnum text-right text-ink-400">{formatPercent(row.sharePct, 1)}</td>
            </tr>
          ))}
          {plan.rows.length > 0 && (
            <tr className="border-t-2 border-[var(--color-line)] font-semibold">
              <td>Tổng cộng</td>
              <td className="tnum text-right">{plan.totals.target != null ? formatVndShort(plan.totals.target) : "—"}</td>
              <td className="tnum text-right">{formatVndShort(plan.totals.actual)}</td>
              <td className="tnum text-xs">{plan.totals.pct != null ? formatPercent(plan.totals.pct) : "—"}</td>
              <td className="tnum text-right text-xs">{plan.totals.target != null ? gapLabel(plan.totals.target - plan.totals.plannedActual) : "—"}</td>
              <td />
              <td />
            </tr>
          )}
        </tbody>
      </TableWrap>
      <p className="mt-2 text-xs text-ink-400">
        Kế hoạch là chỉ tiêu doanh thu giao ở Danh mục → Giao chỉ tiêu, cộng dồn các tháng trong kỳ. Đối tượng chưa được giao kế hoạch riêng thì lấy tổng kế hoạch các đơn vị con; chưa có gì thì hiện “—”.
        Vạch đứng trên thanh tiến độ là mức đáng lẽ đã đạt theo số ngày đã qua của kỳ.
        {plan.totals.target != null && plan.totals.actual > plan.totals.plannedActual && (
          <> % hoàn thành ở dòng tổng chỉ tính các đối tượng đã có kế hoạch (thực hiện {formatVndShort(plan.totals.plannedActual)}); còn {formatVndShort(plan.totals.actual - plan.totals.plannedActual)} doanh thu thuộc đối tượng chưa được giao kế hoạch.</>
        )}
      </p>
    </>
  );
}

/* -------------------------------------------------------------------------- */
/* Tỷ trọng đóng góp                                                          */
/* -------------------------------------------------------------------------- */

export function TreeShareView({ rows, total, label }: { rows: TreeRow<ShareRow>[]; total: number; label: string }) {
  const chartRows = chartLevel(rows);
  return (
    <>
      <div className="mb-4 grid gap-4 lg:grid-cols-2">
        <div className="card p-4">
          <SectionTitle hint="tỷ trọng doanh thu">Biểu đồ tròn</SectionTitle>
          <ShareChart data={chartRows.map((r) => ({ name: r.name, value: r.revenue }))} />
        </div>
        <div className="card p-4">
          <SectionTitle hint="xếp theo doanh thu">Biểu đồ xếp hạng</SectionTitle>
          <RankBarChart data={chartRows.map((r) => ({ name: r.name, value: r.revenue }))} />
        </div>
      </div>
      <TableWrap>
        <thead>
          <tr>
            <th>{label}</th>
            <th className="text-right">Số đơn</th>
            <th className="text-right">Doanh số</th>
            <th className="text-right">Doanh thu</th>
            <th className="text-right">Tỷ trọng</th>
          </tr>
        </thead>
        <tbody>
          {rows.length === 0 && <Empty cols={5} />}
          {rows.map((row) => (
            <tr key={row.id}>
              <td>
                <TreeName name={row.name} depth={row.depth} />
              </td>
              <td className="tnum text-right text-ink-500">{row.orders}</td>
              <td className="tnum text-right text-ink-500">{row.sales ? formatVndShort(row.sales) : "—"}</td>
              <td className="tnum text-right font-semibold">{formatVndShort(row.revenue)}</td>
              <td className="tnum text-right text-ink-400">{formatPercent(row.sharePct, 1)}</td>
            </tr>
          ))}
          {rows.length > 0 && (
            <tr className="border-t-2 border-[var(--color-line)] font-semibold">
              <td>Tổng doanh thu</td>
              <td />
              <td />
              <td className="tnum text-right">{formatVndShort(total)}</td>
              <td className="tnum text-right">100%</td>
            </tr>
          )}
        </tbody>
      </TableWrap>
      <p className="mt-2 text-xs text-ink-400">Giá trị của cấp cha đã gồm mọi đơn vị con nằm dưới nó; tỷ trọng tính trên tổng doanh thu của phạm vi đang xem.</p>
    </>
  );
}

export type LeaderRow = {
  rank: number;
  userId: string | null;
  fullName: string;
  departmentName: string;
  jobTitle: string | null;
  territoryName: string | null;
  avatar: string | null;
  orderCount: number;
  customerCount: number;
  newCustomers: number;
  sales: number;
  revenue: number;
  debt: number;
  sharePct: number;
};

/** Tỷ trọng doanh thu của từng nhân viên (biểu đồ + bảng gọn); bảng xếp hạng đầy đủ ở mục "Xếp hạng NV". */
export function StaffShareView({ rows, profileHref, rankingHref }: { rows: LeaderRow[]; profileHref: (id: string) => string; rankingHref: string }) {
  const total = rows.reduce((sum, r) => sum + r.revenue, 0);
  return (
    <>
      <div className="mb-4 grid gap-4 lg:grid-cols-2">
        <div className="card p-4">
          <SectionTitle hint="tỷ trọng doanh thu">Biểu đồ tròn</SectionTitle>
          <ShareChart data={rows.map((r) => ({ name: r.fullName, value: r.revenue }))} />
        </div>
        <div className="card p-4">
          <SectionTitle hint="xếp theo doanh thu">Biểu đồ xếp hạng</SectionTitle>
          <RankBarChart data={rows.map((r) => ({ name: r.fullName, value: r.revenue }))} />
        </div>
      </div>
      <TableWrap>
        <thead>
          <tr>
            <th>Nhân viên</th>
            <th>Phòng ban</th>
            <th className="text-right">Số đơn</th>
            <th className="text-right">Doanh thu</th>
            <th className="text-right">Tỷ trọng</th>
          </tr>
        </thead>
        <tbody>
          {rows.length === 0 && <Empty cols={5} />}
          {[...rows]
            .sort((a, b) => b.revenue - a.revenue || a.fullName.localeCompare(b.fullName, "vi"))
            .map((row) => (
              <tr key={row.userId ?? row.fullName}>
                <td>
                  {row.userId ? (
                    <Link href={profileHref(row.userId)} className="font-medium text-ink-700 hover:text-brand-600">
                      {row.fullName}
                    </Link>
                  ) : (
                    <span className="font-medium text-ink-700">{row.fullName}</span>
                  )}
                </td>
                <td className="text-ink-500">{row.departmentName}</td>
                <td className="tnum text-right text-ink-500">{row.orderCount}</td>
                <td className="tnum text-right font-semibold">{formatVndShort(row.revenue)}</td>
                <td className="tnum text-right text-ink-400">{formatPercent(row.sharePct, 1)}</td>
              </tr>
            ))}
          {rows.length > 0 && (
            <tr className="border-t-2 border-[var(--color-line)] font-semibold">
              <td colSpan={3}>Tổng doanh thu</td>
              <td className="tnum text-right">{formatVndShort(total)}</td>
              <td className="tnum text-right">100%</td>
            </tr>
          )}
        </tbody>
      </TableWrap>
      <p className="mt-2 text-xs text-ink-400">
        Xếp hạng theo doanh số, doanh thu, công nợ, khách mở mới và KPI kế hoạch của từng nhân viên ở mục{" "}
        <Link href={rankingHref} className="text-brand-600 hover:underline">
          Xếp hạng NV
        </Link>
        .
      </p>
    </>
  );
}

/* -------------------------------------------------------------------------- */
/* Xếp hạng nhân viên (KPI nhân viên)                                         */
/* -------------------------------------------------------------------------- */

export type RankSort = "doanhthu" | "doanhso" | "no" | "moi";
const RANK_META: Record<RankSort, { label: string; column: "revenue" | "sales" | "debt" | "newCustomers"; unit: "money" | "count"; hint: string }> = {
  doanhthu: { label: "Doanh thu", column: "revenue", unit: "money", hint: "đơn đã duyệt, cao → thấp" },
  doanhso: { label: "Doanh số", column: "sales", unit: "money", hint: "đơn đã lập chưa huỷ, cao → thấp" },
  no: { label: "Công nợ", column: "debt", unit: "money", hint: "còn phải thu của đơn trong kỳ, cao → thấp" },
  moi: { label: "Khách mở mới", column: "newCustomers", unit: "count", hint: "số khách mở mới, nhiều → ít" },
};

const rankBadge = (rank: number) => (
  <span className={`tnum inline-flex h-7 min-w-7 items-center justify-center rounded-full px-1.5 text-xs font-bold ${rank === 1 ? "bg-gold-100 text-gold-500" : rank <= 3 ? "bg-ink-100 text-brand-600" : "text-ink-400"}`}>{rank}</span>
);

export function RankingView(props: {
  rows: LeaderRow[];
  sort: RankSort;
  sortLinks: { key: RankSort; href: string }[];
  plan: Map<string, { target: number | null; pct: number | null }>;
  profileHref: (id: string) => string;
  benchmark: number;
  unassignedNew: number;
}) {
  const { rows, sort, plan } = props;
  const meta = RANK_META[sort];
  const value = (row: LeaderRow) => row[meta.column];
  const show = (row: LeaderRow) => (meta.unit === "count" ? formatNumber(value(row)) : formatVndShort(value(row)));
  const highlight = (column: typeof meta.column) => (meta.column === column ? "bg-brand-50/70" : "");
  const person = (row: LeaderRow, size: number) => (
    <span className="flex min-w-0 items-center gap-2.5">
      <Avatar name={row.fullName} src={row.avatar} size={size} />
      <span className="min-w-0">
        <span className="block truncate font-medium text-ink-700">{row.fullName}</span>
        <span className="block truncate text-[11px] font-normal text-ink-400">{row.jobTitle ?? "Nhân viên kinh doanh"}</span>
      </span>
    </span>
  );
  const nameCell = (row: LeaderRow, size: number) =>
    row.userId ? (
      <Link href={props.profileHref(row.userId)} className="hover:text-brand-600">
        {person(row, size)}
      </Link>
    ) : (
      person(row, size)
    );

  return (
    <>
      <div className="mb-4 flex w-fit flex-wrap gap-1 rounded-lg border border-[var(--color-line)] bg-white p-1">
        {props.sortLinks.map((l) => (
          <Link key={l.key} href={l.href} className={`rounded-md px-3 py-1.5 text-sm font-semibold ${sort === l.key ? "bg-brand-500 text-white" : "text-ink-500 hover:bg-ink-50"}`}>
            {RANK_META[l.key].label}
          </Link>
        ))}
      </div>

      <div className="card mb-4 p-4">
        <SectionTitle hint={meta.hint}>Xếp hạng theo {meta.label.toLowerCase()}</SectionTitle>
        <RankBarChart data={rows.map((r) => ({ name: r.fullName, value: value(r) }))} unit={meta.unit} seriesName={meta.label} showPercent={false} max={12} />
      </div>

      {/* Điện thoại: mỗi người một thẻ, chỉ tiêu chí đang xếp hạng là số lớn. */}
      <div className="flex flex-col gap-2 lg:hidden">
        {rows.length === 0 && <Empty cols={1} />}
        {rows.map((row) => {
          const p = row.userId ? plan.get(row.userId) : undefined;
          return (
            <div key={row.userId ?? row.fullName} className="card p-3.5">
              <div className="flex items-start gap-3">
                {rankBadge(row.rank)}
                <div className="min-w-0 flex-1">
                  {nameCell(row, 36)}
                  <div className="mt-0.5 text-[11px] text-ink-400">
                    {row.departmentName}
                    {row.territoryName ? ` · ${row.territoryName}` : ""}
                  </div>
                </div>
                <div className="text-right">
                  <div className="text-[10px] uppercase tracking-wide text-ink-400">{meta.label}</div>
                  <div className="tnum text-lg font-bold text-ink-700">{show(row)}</div>
                </div>
              </div>
              <div className="mt-2 grid grid-cols-3 gap-2 text-xs text-ink-500">
                <span>
                  Doanh thu <b className="tnum block text-ink-700">{formatVndShort(row.revenue)}</b>
                </span>
                <span>
                  Doanh số <b className="tnum block text-ink-700">{formatVndShort(row.sales)}</b>
                </span>
                <span>
                  Công nợ <b className="tnum block text-gold-500">{row.debt > 0 ? formatVndShort(row.debt) : "—"}</b>
                </span>
                <span>
                  KH mở mới <b className="tnum block text-ink-700">{row.newCustomers}</b>
                </span>
                <span>
                  Số đơn <b className="tnum block text-ink-700">{row.orderCount}</b>
                </span>
                <span>
                  % kế hoạch <b className="tnum block text-ink-700">{p?.pct != null ? formatPercent(p.pct) : "—"}</b>
                </span>
              </div>
            </div>
          );
        })}
      </div>

      <div className="hidden lg:block">
        <TableWrap>
          <thead>
            <tr>
              <th style={{ width: 56 }}>Hạng</th>
              <th>Nhân viên</th>
              <th>Phòng ban · Khu vực</th>
              <th className="text-right">Số đơn</th>
              <th className="text-right">Số KH</th>
              <th className={`text-right ${highlight("newCustomers")}`}>KH mở mới</th>
              <th className={`text-right ${highlight("sales")}`}>Doanh số</th>
              <th className={`text-right ${highlight("revenue")}`}>Doanh thu</th>
              <th className={`text-right ${highlight("debt")}`}>Công nợ</th>
              <th style={{ width: 120 }}>% Kế hoạch</th>
              <th className="text-right">Tỷ trọng</th>
            </tr>
          </thead>
          <tbody>
            {rows.length === 0 && <Empty cols={11} />}
            {rows.map((row) => {
              const p = row.userId ? plan.get(row.userId) : undefined;
              return (
                <tr key={row.userId ?? row.fullName} className="align-middle">
                  <td>{rankBadge(row.rank)}</td>
                  <td>{nameCell(row, 32)}</td>
                  <td className="text-ink-500">
                    {row.departmentName}
                    {row.territoryName && <div className="text-[11px] text-ink-400">{row.territoryName}</div>}
                  </td>
                  <td className="tnum text-right text-ink-500">{row.orderCount}</td>
                  <td className="tnum text-right text-ink-500">{row.customerCount}</td>
                  <td className={`tnum text-right ${highlight("newCustomers")} ${meta.column === "newCustomers" ? "font-semibold" : "text-ink-500"}`}>{row.newCustomers}</td>
                  <td className={`tnum text-right ${highlight("sales")} ${meta.column === "sales" ? "font-semibold" : "text-ink-500"}`}>{formatVndShort(row.sales)}</td>
                  <td className={`tnum text-right ${highlight("revenue")} ${meta.column === "revenue" ? "font-semibold" : "font-medium"}`}>{formatVndShort(row.revenue)}</td>
                  <td className={`tnum text-right text-gold-500 ${highlight("debt")} ${meta.column === "debt" ? "font-semibold" : ""}`}>{row.debt > 0 ? formatVndShort(row.debt) : "—"}</td>
                  <td>
                    <div className="tnum mb-1 text-xs font-semibold text-ink-600">{p?.pct != null ? formatPercent(p.pct) : "—"}</div>
                    {p?.pct != null && <ProgressBar percent={p.pct} benchmark={props.benchmark} />}
                  </td>
                  <td className="tnum text-right text-ink-400">{formatPercent(row.sharePct, 1)}</td>
                </tr>
              );
            })}
          </tbody>
        </TableWrap>
      </div>
      <p className="mt-2 text-xs text-ink-400">
        Bấm tên để mở hồ sơ và báo cáo chi tiết của nhân viên đúng kỳ đang xem. Doanh số = đơn đã lập chưa huỷ; doanh thu = đơn đã duyệt; công nợ = doanh thu + phụ thu − đã thu của các đơn trong kỳ; % kế hoạch = doanh thu so với chỉ tiêu giao cho nhân viên (vạch đứng là mức đáng lẽ đã đạt theo số ngày đã qua). Bằng điểm thì cùng hạng.
        {props.unassignedNew > 0 && ` Còn ${props.unassignedNew} khách mở mới trong kỳ chưa giao cho NVKD nào (ví dụ khách từ Marketing chưa phân công) nên không nằm trong cột KH mở mới.`}
      </p>
    </>
  );
}

/* -------------------------------------------------------------------------- */
/* Khách hàng                                                                 */
/* -------------------------------------------------------------------------- */

const stageTone = (stage: string) => (stage === "DEALER" ? "brand" : stage === "PROSPECT" ? "gold" : "neutral");

/** Các thẻ số lượng và tỷ lệ khách mở mới / tổng khách — dùng ở đầu cả hai mục con. */
export function CustomerOverviewCards({ overview, periodLabel }: { overview: CustomerOverview; periodLabel: string }) {
  const stages = (["DEALER", "PROSPECT", "LEAD"] as const).map((k) => `${STAGE_LABEL[k]} ${overview.newByStage[k] ?? 0}`).join(" · ");
  return (
    <div className="grid grid-cols-2 gap-3 lg:grid-cols-4">
      <StatCard label="Tổng khách hàng" value={formatNumber(overview.total)} hint={(["DEALER", "PROSPECT", "LEAD"] as const).map((k) => `${STAGE_LABEL[k]} ${overview.totalByStage[k] ?? 0}`).join(" · ")} />
      <StatCard label={`Khách mở mới · ${periodLabel}`} value={formatNumber(overview.newCount)} hint={stages} />
      <StatCard
        label="Tỷ lệ mở mới / tổng khách"
        value={overview.ratioPct != null ? formatPercent(overview.ratioPct, 1) : "—"}
        hint={`${formatNumber(overview.newCount)} / ${formatNumber(overview.total)} khách đến hết kỳ`}
        tone={overview.ratioPct != null && overview.ratioPct >= 10 ? "good" : "default"}
      />
      <StatCard
        label="Khách có đơn trong kỳ"
        value={formatNumber(overview.buyers)}
        hint={`${overview.total > 0 ? formatPercent((overview.buyers / overview.total) * 100) : "—"} tổng khách · ${overview.newBuyers} khách mới đã lên đơn`}
      />
    </div>
  );
}

/** Nút chuyển trang dùng chung cho các danh sách dài. */
export function Pager({ page, totalPages, total, unit, hrefFor }: { page: number; totalPages: number; total: number; unit: string; hrefFor: (page: number) => string }) {
  if (totalPages <= 1) return null;
  return (
    <nav className="mt-4 flex items-center justify-center gap-3 text-sm" aria-label="Phân trang">
      {page > 1 ? (
        <Link href={hrefFor(page - 1)} className="btn-ghost">
          ← Trước
        </Link>
      ) : (
        <span className="btn-ghost pointer-events-none opacity-40">← Trước</span>
      )}
      <span className="text-ink-500">
        Trang {page}/{totalPages} · {formatNumber(total)} {unit}
      </span>
      {page < totalPages ? (
        <Link href={hrefFor(page + 1)} className="btn-ghost">
          Sau →
        </Link>
      ) : (
        <span className="btn-ghost pointer-events-none opacity-40">Sau →</span>
      )}
    </nav>
  );
}

export type CustomerRankSortKey = "doanhthu" | "doanhso" | "no";
const CUSTOMER_RANK_META: Record<CustomerRankSortKey, { label: string; column: "revenue" | "sales" | "debt"; hint: string }> = {
  doanhthu: { label: "Doanh thu", column: "revenue", hint: "đơn đã duyệt, cao → thấp" },
  doanhso: { label: "Doanh số", column: "sales", hint: "đơn đã lập chưa huỷ, cao → thấp" },
  no: { label: "Công nợ", column: "debt", hint: "còn phải thu của đơn trong kỳ, cao → thấp" },
};

export function CustomerRankingView(props: {
  ranking: { rows: CustomerRankRow[]; total: number; page: number; totalPages: number; sumRevenue: number; sumSales: number; sumDebt: number };
  sort: CustomerRankSortKey;
  sortLinks: { key: CustomerRankSortKey; href: string }[];
  pageHref: (page: number) => string;
  chartRows: { name: string; value: number }[];
}) {
  const { ranking, sort } = props;
  const meta = CUSTOMER_RANK_META[sort];
  const rows = ranking.rows;
  const rankBadgeEl = (rank: number) => (
    <span className={`tnum inline-flex h-7 min-w-7 items-center justify-center rounded-full px-1.5 text-xs font-bold ${rank === 1 ? "bg-gold-100 text-gold-500" : rank <= 3 ? "bg-ink-100 text-brand-600" : "text-ink-400"}`}>{rank}</span>
  );
  const highlight = (column: typeof meta.column) => (meta.column === column ? "bg-brand-50/70" : "");
  const valueOf = (r: CustomerRankRow) => r[meta.column];
  return (
    <>
      <div className="mb-4 flex w-fit flex-wrap gap-1 rounded-lg border border-[var(--color-line)] bg-white p-1">
        {props.sortLinks.map((l) => (
          <Link key={l.key} href={l.href} className={`rounded-md px-3 py-1.5 text-sm font-semibold ${sort === l.key ? "bg-brand-500 text-white" : "text-ink-500 hover:bg-ink-50"}`}>
            {CUSTOMER_RANK_META[l.key].label}
          </Link>
        ))}
      </div>

      <div className="card mb-4 p-4">
        <SectionTitle hint={`${meta.hint} · 10 khách đầu`}>Xếp hạng khách hàng theo {meta.label.toLowerCase()}</SectionTitle>
        <RankBarChart data={props.chartRows} seriesName={meta.label} showPercent={false} max={10} />
      </div>

      {/* Điện thoại: mỗi khách một thẻ. */}
      <div className="flex flex-col gap-2 lg:hidden">
        {rows.length === 0 && <Empty cols={1} />}
        {rows.map((r) => (
          <div key={r.customerId} className="card p-3.5">
            <div className="flex items-start gap-3">
              {rankBadgeEl(r.rank)}
              <div className="min-w-0 flex-1">
                <Link href={`/khach-hang/${r.customerId}`} className="block truncate font-medium text-ink-700 hover:text-brand-600">
                  {r.orgName}
                </Link>
                <div className="text-[11px] text-ink-400">
                  {r.code} · {r.territoryName ?? "—"} · {r.ownerName ?? "chưa giao NVKD"}
                </div>
              </div>
              <div className="text-right">
                <div className="text-[10px] uppercase tracking-wide text-ink-400">{meta.label}</div>
                <div className="tnum text-lg font-bold text-ink-700">{formatVndShort(valueOf(r))}</div>
              </div>
            </div>
            <div className="mt-2 grid grid-cols-3 gap-2 text-xs text-ink-500">
              <span>
                Doanh thu <b className="tnum block text-ink-700">{formatVndShort(r.revenue)}</b>
              </span>
              <span>
                Doanh số <b className="tnum block text-ink-700">{formatVndShort(r.sales)}</b>
              </span>
              <span>
                Công nợ <b className="tnum block text-gold-500">{r.debt > 0 ? formatVndShort(r.debt) : "—"}</b>
              </span>
            </div>
          </div>
        ))}
      </div>

      <div className="hidden lg:block">
        <TableWrap>
          <thead>
            <tr>
              <th style={{ width: 56 }}>Hạng</th>
              <th>Khách hàng</th>
              <th>Khu vực · NVKD</th>
              <th className="text-center">Hạng ĐL</th>
              <th className="text-right">Số đơn</th>
              <th className={`text-right ${highlight("sales")}`}>Doanh số</th>
              <th className={`text-right ${highlight("revenue")}`}>Doanh thu</th>
              <th className={`text-right ${highlight("debt")}`}>Công nợ</th>
              <th className="text-right">Đơn gần nhất</th>
            </tr>
          </thead>
          <tbody>
            {rows.length === 0 && <Empty cols={9} />}
            {rows.map((r) => (
              <tr key={r.customerId} className="align-middle">
                <td>{rankBadgeEl(r.rank)}</td>
                <td>
                  <Link href={`/khach-hang/${r.customerId}`} className="font-medium text-ink-700 hover:text-brand-600">
                    {r.orgName}
                  </Link>
                  <div className="text-[11px] text-ink-400">
                    {r.code}
                    {r.contactName ? ` · ${r.contactName}` : ""}
                    {r.phone ? ` · ${r.phone}` : ""}
                  </div>
                </td>
                <td className="text-ink-500">
                  {r.territoryName ?? "—"}
                  <div className="text-[11px] text-ink-400">{r.ownerName ?? "chưa giao NVKD"}</div>
                </td>
                <td className="text-center">
                  <TierBadge tier={r.tier} />
                </td>
                <td className="tnum text-right text-ink-500">{r.orderCount || "—"}</td>
                <td className={`tnum text-right ${highlight("sales")} ${meta.column === "sales" ? "font-semibold" : "text-ink-500"}`}>{formatVndShort(r.sales)}</td>
                <td className={`tnum text-right ${highlight("revenue")} ${meta.column === "revenue" ? "font-semibold" : "font-medium"}`}>{formatVndShort(r.revenue)}</td>
                <td className={`tnum text-right text-gold-500 ${highlight("debt")} ${meta.column === "debt" ? "font-semibold" : ""}`}>{r.debt > 0 ? formatVndShort(r.debt) : "—"}</td>
                <td className="tnum text-right text-ink-400">{r.lastOrderDate ? formatDate(r.lastOrderDate) : "—"}</td>
              </tr>
            ))}
            {ranking.total > 0 && (
              <tr className="border-t-2 border-[var(--color-line)] font-semibold">
                <td colSpan={5}>Tổng {formatNumber(ranking.total)} khách trong bảng</td>
                <td className="tnum text-right">{formatVndShort(ranking.sumSales)}</td>
                <td className="tnum text-right">{formatVndShort(ranking.sumRevenue)}</td>
                <td className="tnum text-right text-gold-500">{formatVndShort(ranking.sumDebt)}</td>
                <td />
              </tr>
            )}
          </tbody>
        </TableWrap>
      </div>
      <Pager page={ranking.page} totalPages={ranking.totalPages} total={ranking.total} unit="khách" hrefFor={props.pageHref} />
      <p className="mt-2 text-xs text-ink-400">
        Chỉ hiện khách có giá trị lớn hơn 0 ở tiêu chí đang xếp. Doanh số = đơn đã lập chưa huỷ; doanh thu = đơn đã duyệt; công nợ = doanh thu + phụ thu − đã thu của các đơn trong kỳ. Bằng điểm thì cùng hạng. Bấm tên khách để mở hồ sơ và báo cáo của khách. Xếp theo doanh thu / công nợ bình quân tháng và lọc chi tiết hơn ở mục Khách hàng.
      </p>
    </>
  );
}

export function NewCustomersView(props: {
  groups: TreeRow<NewByGroup>[];
  groupLabel: string;
  list: { rows: NewCustomerRow[]; total: number; page: number; totalPages: number };
  pageHref: (page: number) => string;
  periodLabel: string;
}) {
  const { groups, list } = props;
  const totalNew = groups.filter((g) => g.depth === 0).reduce((sum, g) => sum + g.newCount, 0);
  const totalAll = groups.filter((g) => g.depth === 0).reduce((sum, g) => sum + g.total, 0);
  return (
    <>
      <SectionTitle hint="số lượng và tỷ lệ trên tổng khách của từng nhóm">Khách mở mới theo {props.groupLabel.toLowerCase()}</SectionTitle>
      <TableWrap>
        <thead>
          <tr>
            <th>{props.groupLabel}</th>
            <th className="text-right">Khách mở mới</th>
            <th className="text-right">Tổng khách</th>
            <th className="text-right">Tỷ lệ mới / tổng</th>
            <th className="text-right">Khách có đơn trong kỳ</th>
          </tr>
        </thead>
        <tbody>
          {groups.length === 0 && <Empty cols={5} />}
          {groups.map((g) => (
            <tr key={g.id}>
              <td>
                <TreeName name={g.name} depth={g.depth} />
              </td>
              <td className="tnum text-right font-semibold">{g.newCount || "—"}</td>
              <td className="tnum text-right text-ink-500">{g.total}</td>
              <td className="tnum text-right text-ink-400">{g.ratioPct != null && g.newCount > 0 ? formatPercent(g.ratioPct, 1) : "—"}</td>
              <td className="tnum text-right text-ink-500">{g.buyers || "—"}</td>
            </tr>
          ))}
          {groups.length > 0 && (
            <tr className="border-t-2 border-[var(--color-line)] font-semibold">
              <td>Tổng cộng</td>
              <td className="tnum text-right">{totalNew}</td>
              <td className="tnum text-right">{totalAll}</td>
              <td className="tnum text-right">{totalAll > 0 ? formatPercent((totalNew / totalAll) * 100, 1) : "—"}</td>
              <td />
            </tr>
          )}
        </tbody>
      </TableWrap>

      <div className="mt-8">
        <SectionTitle hint={`${formatNumber(list.total)} khách trong ${props.periodLabel.toLowerCase()}`}>Danh sách khách hàng mới</SectionTitle>
        {/* Điện thoại: mỗi khách một thẻ. */}
        <div className="flex flex-col gap-2 lg:hidden">
          {list.rows.length === 0 && <Empty cols={1} />}
          {list.rows.map((c) => (
            <Link key={c.id} href={`/khach-hang/${c.id}`} className="card p-3.5 active:bg-ink-50">
              <div className="flex items-start justify-between gap-2">
                <div className="min-w-0">
                  <div className="truncate font-medium text-ink-700">{c.orgName}</div>
                  <div className="text-[11px] text-ink-400">
                    {c.code} · {formatDate(c.createdDate)}
                  </div>
                </div>
                <Badge tone={stageTone(c.stage)}>{STAGE_LABEL[c.stage]}</Badge>
              </div>
              <div className="mt-1.5 text-xs text-ink-500">
                {[c.contactName, c.phone].filter(Boolean).join(" · ") || "—"}
                <div className="text-[11px] text-ink-400">
                  {c.territoryName ?? "—"} · {c.ownerName ?? "chưa giao NVKD"}
                </div>
              </div>
            </Link>
          ))}
        </div>
        <div className="hidden lg:block">
          <TableWrap>
            <thead>
              <tr>
                <th>Ngày tạo</th>
                <th>Khách hàng</th>
                <th>Kênh · Khu vực</th>
                <th>NVKD phụ trách</th>
                <th>Loại</th>
                <th className="text-right">Số đơn</th>
                <th className="text-right">Trị giá đơn</th>
              </tr>
            </thead>
            <tbody>
              {list.rows.length === 0 && <Empty cols={7} />}
              {list.rows.map((c) => (
                <tr key={c.id}>
                  <td className="tnum whitespace-nowrap text-ink-500">{formatDate(c.createdDate)}</td>
                  <td>
                    <Link href={`/khach-hang/${c.id}`} className="font-medium text-ink-700 hover:text-brand-600">
                      {c.orgName}
                    </Link>
                    <div className="text-[11px] text-ink-400">
                      {c.code}
                      {c.contactName ? ` · ${c.contactName}` : ""}
                      {c.phone ? ` · ${c.phone}` : ""}
                    </div>
                  </td>
                  <td className="text-ink-500">
                    <div>{c.channelName ?? "—"}</div>
                    <div className="text-[11px] text-ink-400">{c.territoryName ?? "—"}</div>
                  </td>
                  <td className="text-ink-500">{c.ownerName ?? "—"}</td>
                  <td>
                    <Badge tone={stageTone(c.stage)}>{STAGE_LABEL[c.stage]}</Badge>
                  </td>
                  <td className="tnum text-right text-ink-500">{c.orderCount || "—"}</td>
                  <td className="tnum text-right font-semibold">{c.revenue > 0 ? formatVndShort(c.revenue) : "—"}</td>
                </tr>
              ))}
            </tbody>
          </TableWrap>
        </div>
        <Pager page={list.page} totalPages={list.totalPages} total={list.total} unit="khách mới" hrefFor={props.pageHref} />
        <p className="mt-2 text-xs text-ink-400">Ngày tạo tính theo giờ Việt Nam. Trị giá đơn = đơn đã duyệt của khách tính tới hết kỳ. Tuần và ngày xem ở mục Báo cáo.</p>
      </div>
    </>
  );
}

/* -------------------------------------------------------------------------- */
/* Sản phẩm                                                                   */
/* -------------------------------------------------------------------------- */

export function ProductView(props: {
  rows: ProductReportRow[];
  total: number;
  totalSales: number;
}) {
  const { rows, total } = props;
  const byGroup = [...rows.reduce((map, r) => map.set(r.groupName, (map.get(r.groupName) ?? 0) + r.revenue), new Map<string, number>())].map(([name, value]) => ({ name, value }));
  const byRole = ["CORE", "POTENTIAL", "RECOVERY", "NORMAL"].map((role) => {
    const list = rows.filter((r) => r.role === role);
    return { role, count: list.length, revenue: list.reduce((sum, r) => sum + r.revenue, 0) };
  });
  return (
    <>
      <div className="grid gap-4 lg:grid-cols-2">
        <div className="card p-4">
          <SectionTitle hint="10 sản phẩm dẫn đầu · % trên tổng doanh thu">Tỷ trọng theo sản phẩm</SectionTitle>
          <RankBarChart data={rows.map((r) => ({ name: r.name, value: r.revenue }))} />
        </div>
        <div className="card p-4">
          <SectionTitle hint="theo nhóm sản phẩm">Tỷ trọng theo nhóm</SectionTitle>
          <ShareChart data={byGroup} />
        </div>
      </div>

      <div className="mt-6">
        <SectionTitle hint={`${rows.length} sản phẩm có bán trong kỳ`}>Báo cáo doanh số từng sản phẩm</SectionTitle>
        <TableWrap>
          <thead>
            <tr>
              <th>Mã</th>
              <th>Sản phẩm</th>
              <th>Nhóm SP</th>
              <th>Vai trò</th>
              <th className="text-right">SL bán</th>
              <th className="text-right">SL KM</th>
              <th className="text-right">Số KH mua</th>
              <th className="text-right">Doanh số</th>
              <th className="text-right">Doanh thu</th>
              <th className="text-right">Tỷ trọng</th>
            </tr>
          </thead>
          <tbody>
            {rows.length === 0 && <Empty cols={10} />}
            {rows.map((r) => (
              <tr key={r.productId}>
                <td className="tnum text-ink-400">{r.code}</td>
                <td className="font-medium text-ink-700">
                  {r.name}
                  <span className="ml-1 text-[11px] font-normal text-ink-400">/{r.unit}</span>
                </td>
                <td className="text-ink-500">{r.groupName}</td>
                <td>
                  <Badge tone={roleTone(r.role)}>{ROLE_LABEL[r.role] ?? r.role}</Badge>
                </td>
                <td className="tnum text-right">{formatNumber(r.qtySold)}</td>
                <td className="tnum text-right text-ink-400">{formatNumber(r.qtyPromo)}</td>
                <td className="tnum text-right text-ink-500">{r.customers}</td>
                <td className="tnum text-right text-ink-500">{formatVndShort(r.sales)}</td>
                <td className="tnum text-right font-semibold">{formatVndShort(r.revenue)}</td>
                <td className="tnum text-right text-ink-400">{formatPercent(r.sharePct, 1)}</td>
              </tr>
            ))}
            {rows.length > 0 && (
              <tr className="border-t-2 border-[var(--color-line)] font-semibold">
                <td colSpan={4}>Tổng cộng</td>
                <td className="tnum text-right">{formatNumber(rows.reduce((sum, r) => sum + r.qtySold, 0))}</td>
                <td className="tnum text-right">{formatNumber(rows.reduce((sum, r) => sum + r.qtyPromo, 0))}</td>
                <td />
                <td className="tnum text-right">{formatVndShort(props.totalSales)}</td>
                <td className="tnum text-right">{formatVndShort(total)}</td>
                <td className="tnum text-right">100%</td>
              </tr>
            )}
          </tbody>
        </TableWrap>
        <p className="mt-2 text-xs text-ink-400">
          Muốn xem tỷ trọng sản phẩm riêng của một khu vực, phòng ban, team hay nhân viên: chọn ở ô “Phạm vi xem” phía trên. Xuất Excel có đủ mọi sản phẩm.
        </p>
      </div>

      <div className="mt-6 grid gap-4 lg:grid-cols-2">
        <div>
          <SectionTitle hint="tỷ trọng theo vai trò">Phân nhóm sản phẩm</SectionTitle>
          <TableWrap>
            <thead>
              <tr>
                <th>Nhóm</th>
                <th className="text-right">Số SP có bán</th>
                <th className="text-right">Doanh thu</th>
                <th className="text-right">Tỷ trọng</th>
              </tr>
            </thead>
            <tbody>
              {byRole.map((row) => (
                <tr key={row.role}>
                  <td>
                    <Badge tone={roleTone(row.role)}>{ROLE_LABEL[row.role]}</Badge>
                  </td>
                  <td className="tnum text-right text-ink-500">{row.count}</td>
                  <td className="tnum text-right font-medium">{formatVndShort(row.revenue)}</td>
                  <td className="tnum text-right text-ink-400">{total > 0 ? formatPercent((row.revenue / total) * 100, 1) : "—"}</td>
                </tr>
              ))}
            </tbody>
          </TableWrap>
        </div>
      </div>

      <p className="mt-6 text-xs text-ink-400">
        Dự báo dự trù sản phẩm các tháng tới (kèm chỉnh tay số đặt hàng) ở{" "}
        <Link href="/canh-bao?muc=du-bao" className="text-brand-600 hover:underline">
          Cảnh báo → Dự báo
        </Link>
        .
      </p>
    </>
  );
}

/** Tỷ trọng đóng góp của từng sản phẩm (mục Tỷ trọng đóng góp → Sản phẩm); bảng đầy đủ nằm ở mục Sản phẩm. */
export function ProductShareView({ rows, total }: { rows: ProductReportRow[]; total: number }) {
  return (
    <>
      <div className="mb-4 grid gap-4 lg:grid-cols-2">
        <div className="card p-4">
          <SectionTitle hint="tỷ trọng doanh thu">Biểu đồ tròn</SectionTitle>
          <ShareChart data={rows.map((r) => ({ name: r.name, value: r.revenue }))} />
        </div>
        <div className="card p-4">
          <SectionTitle hint="10 sản phẩm dẫn đầu">Biểu đồ xếp hạng</SectionTitle>
          <RankBarChart data={rows.map((r) => ({ name: r.name, value: r.revenue }))} />
        </div>
      </div>
      <TableWrap>
        <thead>
          <tr>
            <th>Sản phẩm</th>
            <th>Nhóm SP</th>
            <th className="text-right">SL bán</th>
            <th className="text-right">Doanh thu</th>
            <th className="text-right">Tỷ trọng</th>
          </tr>
        </thead>
        <tbody>
          {rows.length === 0 && <Empty cols={5} />}
          {rows.map((r) => (
            <tr key={r.productId}>
              <td className="font-medium text-ink-700">
                {r.name}
                <span className="ml-1.5 text-[11px] font-normal text-ink-400">{r.code}</span>
              </td>
              <td className="text-ink-500">{r.groupName}</td>
              <td className="tnum text-right">{formatNumber(r.qtySold)}</td>
              <td className="tnum text-right font-semibold">{formatVndShort(r.revenue)}</td>
              <td className="tnum text-right text-ink-400">{formatPercent(r.sharePct, 1)}</td>
            </tr>
          ))}
          {rows.length > 0 && (
            <tr className="border-t-2 border-[var(--color-line)] font-semibold">
              <td colSpan={3}>Tổng doanh thu</td>
              <td className="tnum text-right">{formatVndShort(total)}</td>
              <td className="tnum text-right">100%</td>
            </tr>
          )}
        </tbody>
      </TableWrap>
      <p className="mt-2 text-xs text-ink-400">Muốn xem tỷ trọng sản phẩm của riêng một khu vực, phòng ban, team hay nhân viên: chọn ở ô “Phạm vi xem” phía trên.</p>
    </>
  );
}

/* -------------------------------------------------------------------------- */
/* Khuyến mãi                                                                 */
/* -------------------------------------------------------------------------- */

function PromoTable({ title, hint, rows, label }: { title: string; hint?: string; rows: TreeRow<PromoReport["totals"]>[]; label: string }) {
  return (
    <div className="mt-6">
      <SectionTitle hint={hint}>{title}</SectionTitle>
      <TableWrap>
        <thead>
          <tr>
            <th>{label}</th>
            <th className="text-right">Số đơn có KM</th>
            <th className="text-right">SL hàng KM</th>
            <th className="text-right">Giá trị KM</th>
            <th className="text-right">Doanh thu</th>
            <th className="text-right">KM / doanh thu</th>
          </tr>
        </thead>
        <tbody>
          {rows.length === 0 && <Empty cols={6} />}
          {rows.map((row) => (
            <tr key={row.id}>
              <td>
                <TreeName name={row.name} depth={row.depth} />
              </td>
              <td className="tnum text-right text-ink-500">{row.orders || "—"}</td>
              <td className="tnum text-right">{row.qty ? formatNumber(row.qty) : "—"}</td>
              <td className="tnum text-right font-semibold">{row.value ? formatVndShort(row.value) : "—"}</td>
              <td className="tnum text-right text-ink-500">{row.revenue ? formatVndShort(row.revenue) : "—"}</td>
              <td className="tnum text-right text-ink-400">{row.ratioPct != null ? formatPercent(row.ratioPct, 1) : "—"}</td>
            </tr>
          ))}
        </tbody>
      </TableWrap>
    </div>
  );
}

/** Ba bảng khuyến mãi theo khu vực / phòng ban / nhân viên — dùng ở cả trang Phân tích và Báo cáo. */
export function PromoBreakdown({ promo }: { promo: PromoReport }) {
  return (
    <>
      <PromoTable title="Khuyến mãi theo khu vực" hint="miền → tỉnh" rows={promo.byTerritory} label="Khu vực" />
      <PromoTable title="Khuyến mãi theo phòng ban / team" rows={promo.byDepartment} label="Phòng ban" />
      <PromoTable title="Khuyến mãi theo nhân viên" rows={promo.byStaff} label="Nhân viên" />
    </>
  );
}

export function PromoView({ promo }: { promo: PromoReport }) {
  const { totals } = promo;
  return (
    <>
      <div className="grid grid-cols-2 gap-3 lg:grid-cols-4">
        <StatCard label="Giá trị khuyến mãi đã dùng" value={formatVndShort(totals.value)} hint={formatVnd(totals.value)} />
        <StatCard label="SL hàng khuyến mãi" value={formatNumber(totals.qty)} hint={`${formatNumber(totals.orders)} lượt đơn có hàng KM`} />
        <StatCard label="Doanh thu cùng kỳ" value={formatVndShort(totals.revenue)} />
        <StatCard label="Giá trị KM / doanh thu" value={totals.ratioPct != null ? formatPercent(totals.ratioPct, 1) : "—"} tone={totals.ratioPct != null && totals.ratioPct > 15 ? "warn" : "default"} />
      </div>
      <p className="mt-2 text-xs text-ink-400">
        Khuyến mãi của công ty là chính sách chiết khấu theo bậc giá trị đơn và mua nhiều tặng nhiều — luôn quy ra hàng, không có ngân sách bằng tiền. Vì vậy “ngân sách đã dùng” ở đây là giá trị hàng khuyến mãi đã tặng (số lượng × đơn giá).
      </p>

      <div className="mt-4 grid gap-4 lg:grid-cols-2">
        <div className="card p-4">
          <SectionTitle hint="tỷ trọng giá trị KM">Theo khu vực</SectionTitle>
          <ShareChart data={chartLevel(promo.byTerritory).map((r) => ({ name: r.name, value: r.value }))} />
        </div>
        <div className="card p-4">
          <SectionTitle hint="10 nhân viên dùng nhiều nhất">Theo nhân viên</SectionTitle>
          <RankBarChart data={promo.byStaff.map((r) => ({ name: r.name, value: r.value }))} />
        </div>
      </div>

      <PromoBreakdown promo={promo} />

      <div className="mt-6">
        <SectionTitle hint="sản phẩm được tặng nhiều nhất">Sản phẩm khuyến mãi đã sử dụng</SectionTitle>
        <TableWrap>
          <thead>
            <tr>
              <th>Mã</th>
              <th>Sản phẩm</th>
              <th className="text-right">SL hàng KM</th>
              <th className="text-right">Giá trị KM</th>
              <th className="text-right">Tỷ trọng</th>
            </tr>
          </thead>
          <tbody>
            {promo.byProduct.length === 0 && <Empty cols={5} />}
            {promo.byProduct.map((r) => (
              <tr key={r.productId}>
                <td className="tnum text-ink-400">{r.code}</td>
                <td className="font-medium text-ink-700">{r.name}</td>
                <td className="tnum text-right">{formatNumber(r.qty)}</td>
                <td className="tnum text-right font-semibold">{formatVndShort(r.value)}</td>
                <td className="tnum text-right text-ink-400">{totals.value > 0 ? formatPercent((r.value / totals.value) * 100, 1) : "—"}</td>
              </tr>
            ))}
          </tbody>
        </TableWrap>
      </div>
    </>
  );
}

/* -------------------------------------------------------------------------- */
/* Định biên                                                                  */
/* -------------------------------------------------------------------------- */

function StaffingGroupTable({ title, rows, label }: { title: string; rows: StaffingReport["byDepartment"]; label: string }) {
  return (
    <div>
      <SectionTitle>{title}</SectionTitle>
      <TableWrap>
        <thead>
          <tr>
            <th>{label}</th>
            <th className="text-right">Định biên (NVKD)</th>
            <th className="text-right">Có đơn</th>
            <th className="text-right">Doanh thu</th>
            <th className="text-right">Doanh thu / NVKD</th>
          </tr>
        </thead>
        <tbody>
          {rows.length === 0 && <Empty cols={5} />}
          {rows.map((r) => (
            <tr key={r.id}>
              <td className="font-medium text-ink-700">{r.name}</td>
              <td className="tnum text-right">{r.row.headcount}</td>
              <td className="tnum text-right text-ink-500">{r.row.withOrders}</td>
              <td className="tnum text-right text-ink-500">{formatVndShort(r.row.revenue)}</td>
              <td className="tnum text-right font-semibold">{r.row.perHead != null ? formatVndShort(r.row.perHead) : "—"}</td>
            </tr>
          ))}
        </tbody>
      </TableWrap>
    </div>
  );
}

export function StaffingView({ staffing }: { staffing: StaffingReport }) {
  const { overall } = staffing;
  const average = overall.perHead;
  return (
    <>
      <div className="grid grid-cols-2 gap-3 lg:grid-cols-4">
        <StatCard label="Định biên NVKD" value={formatNumber(overall.headcount)} hint="nhân viên kinh doanh đang làm việc (không tính chuyên môn)" />
        <StatCard label="NVKD có đơn trong kỳ" value={formatNumber(overall.withOrders)} hint={overall.headcount > 0 ? `${formatPercent((overall.withOrders / overall.headcount) * 100)} định biên` : undefined} />
        <StatCard label="Doanh thu / NVKD" value={overall.perHead != null ? formatVndShort(overall.perHead) : "—"} hint={overall.perActive != null ? `${formatVndShort(overall.perActive)} tính riêng người có đơn` : undefined} />
        <StatCard label="Doanh thu / NVKD / tháng" value={overall.revenuePerHeadPerMonth != null ? formatVndShort(overall.revenuePerHeadPerMonth) : "—"} hint={`chia theo ${overall.monthsElapsed.toFixed(1).replace(".", ",")} tháng đã trôi của kỳ`} />
      </div>

      <div className="card mt-4 p-4">
        <SectionTitle hint="đường nét đứt là bình quân định biên">Doanh thu từng NVKD</SectionTitle>
        <StaffingChart data={staffing.byStaff.map((s) => ({ name: s.name.split(" ").slice(-2).join(" "), revenue: s.revenue }))} average={average} />
      </div>

      <div className="mt-6 grid gap-4 lg:grid-cols-2">
        <StaffingGroupTable title="Theo team / phòng ban" rows={staffing.byDepartment} label="Team" />
        <StaffingGroupTable title="Theo khu vực (miền)" rows={staffing.byRegion} label="Miền" />
      </div>

      <div className="mt-6">
        <SectionTitle hint="so với bình quân định biên">Từng nhân viên</SectionTitle>
        <TableWrap>
          <thead>
            <tr>
              <th>Nhân viên</th>
              <th>Team</th>
              <th className="text-right">Số đơn</th>
              <th className="text-right">Doanh số</th>
              <th className="text-right">Doanh thu</th>
              <th className="text-right">So với bình quân</th>
            </tr>
          </thead>
          <tbody>
            {staffing.byStaff.length === 0 && <Empty cols={6} />}
            {staffing.byStaff.map((s) => (
              <tr key={s.id}>
                <td className="font-medium text-ink-700">{s.name}</td>
                <td className="text-ink-500">{s.departmentName}</td>
                <td className="tnum text-right text-ink-500">{s.orders || "—"}</td>
                <td className="tnum text-right text-ink-500">{s.sales ? formatVndShort(s.sales) : "—"}</td>
                <td className="tnum text-right font-semibold">{s.revenue ? formatVndShort(s.revenue) : "—"}</td>
                <td className="tnum text-right text-xs">
                  {average && average > 0 ? (
                    <span className={s.revenue >= average ? "text-emerald-700" : "text-gold-500"}>{formatPercent((s.revenue / average) * 100)}</span>
                  ) : (
                    "—"
                  )}
                </td>
              </tr>
            ))}
          </tbody>
        </TableWrap>
        <p className="mt-2 text-xs text-ink-400">
          Định biên = số NVKD trong phạm vi bạn xem; doanh thu/NVKD = doanh thu ÷ định biên (người chưa có đơn vẫn được tính vì đó là năng suất thật của định biên). Đổi ô “Phạm vi xem” để xem theo toàn công ty, khu vực, phòng ban, team hoặc từng nhân viên.
        </p>
      </div>
    </>
  );
}

