import { ActionForm } from "@/components/action-form";
import Link from "next/link";
import { notFound } from "next/navigation";
import { and, desc, eq, gte, lte, ne, sql } from "drizzle-orm";
import { requireSession } from "@/lib/auth";
import { db } from "@/db";
import {
  customers,
  customerClassifications,
  customerStageHistory,
  customerContacts,
  customerNotes,
  customerAttachments,
  customerCourseCompletions,
  trainingCourses,
  orders,
  orderLines,
  orderPayments,
  checkIns,
  planItems,
  weeklyPlans,
  products,
  territories,
  channels,
  users,
} from "@/db/schema";
import { dayInTz, monthKey, today, lastMonths, periodRange, quarterOfMonth, weekDays, weekStart, isRealDate, shiftMonth } from "@/lib/period";
import { orderViewChecker, scopeFilter } from "@/lib/rbac";
import { customerMetrics } from "@/lib/reports";
import { averageMonthlyDebt, overdueDebt } from "@/lib/customer-list";
import { formatVnd, formatVndShort, formatDate, formatDateTime, formatNumber, formatPeriod, orderStatusBadge, STAGE_LABEL } from "@/lib/format";
import { PageHeader, StatCard, TableWrap, SectionTitle, Badge, TierBadge, EmptyState } from "@/components/ui";
import { MonthlyRevenueChart } from "@/components/charts";
import { REVENUE_TIERS, SKU_TIERS, SKU_WINDOW_MONTHS } from "@/lib/classification";
import {
  changeStageAction,
  toggleKeyAction,
  addContactAction,
  updateContactAction,
  deleteContactAction,
  addNoteAction,
  deleteNoteAction,
  uploadAttachmentAction,
  deleteAttachmentAction,
  recordCourseCompletionAction,
  deleteCourseCompletionAction,
  updateLeadStatusAction,
  convertLeadAction,
} from "../actions";
import { LEAD_LABEL, LEAD_TONE, isLeadReport, stripReportTag } from "@/lib/lead-status";
import { idOr404 } from "@/lib/route-params";
import { canManageSettings } from "@/lib/rbac";
import { loadEntityHistory } from "@/lib/audit-view";
import { EntityHistory } from "@/components/entity-history";

const PERIOD_TABS = [
  { key: "tuan", label: "Tuần" },
  { key: "thang", label: "Tháng" },
  { key: "quy", label: "Quý" },
  { key: "nam", label: "Năm" },
] as const;

/** Trạng thái chọn được khi cập nhật khách tiềm năng — "Đã chốt" đi qua form chốt riêng (bắt buộc báo cáo + đủ hồ sơ). */
const LEAD_UPDATE_OPTIONS = ["NOT_CONTACTED", "CONTACTED", "CANCELLED"] as const;

function formatFileSize(bytes: number): string {
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB`;
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
}

export const dynamic = "force-dynamic";

/** Thứ tự phễu, dùng để dựng các nút chuyển trạng thái. */
const STAGE_ORDER = ["LEAD", "PROSPECT", "DEALER"] as const;

export default async function CustomerDetailPage({
  params,
  searchParams,
}: {
  params: Promise<{ id: string }>;
  searchParams: Promise<{ ky?: string; ngay?: string }>;
}) {
  const session = await requireSession();
  const id = idOr404((await params).id);
  const sp = await searchParams;
  const period = monthKey(today());

  const scope = await scopeFilter(session, {
    tenantId: customers.tenantId,
    ownerId: customers.ownerId,
    territoryId: customers.territoryId,
  });

  const [customer] = await db
    .select({
      id: customers.id,
      code: customers.code,
      orgName: customers.orgName,
      contactName: customers.contactName,
      taxCode: customers.taxCode,
      phone: customers.phone,
      email: customers.email,
      address: customers.address,
      ward: customers.ward,
      contactPosition: customers.contactPosition,
      contactBirthDate: customers.contactBirthDate,
      receiverName: customers.receiverName,
      receiverPhone: customers.receiverPhone,
      receiverAddress: customers.receiverAddress,
      leadNeed: customers.leadNeed,
      leadSource: customers.leadSource,
      leadStatus: customers.leadStatus,
      createdAt: customers.createdAt,
      stage: customers.stage,
      isKey: customers.isKey,
      dealerSince: customers.dealerSince,
      note: customers.note,
      territoryName: territories.name,
      channelName: channels.name,
      ownerName: users.fullName,
    })
    .from(customers)
    .leftJoin(territories, eq(customers.territoryId, territories.id))
    .leftJoin(channels, eq(customers.channelId, channels.id))
    .leftJoin(users, eq(customers.ownerId, users.id))
    .where(and(scope, eq(customers.id, id)))
    .limit(1);

  // Ngoài phạm vi dữ liệu của người xem (NVKD: khách của mình; quản lý: nhánh phòng ban) thì coi như không tồn tại.
  if (!customer) notFound();

  /* Kết quả kinh doanh theo kỳ (tuần/tháng/quý/năm) — yêu cầu mục 5: doanh số, doanh thu, công nợ.
     Doanh số = tổng giá trị đơn đã lập (chưa huỷ, kể cả đang chờ duyệt); doanh thu = đơn đã duyệt;
     công nợ = doanh thu của kỳ trừ số đã thu cho các đơn đó. */
  const perTab = PERIOD_TABS.some((t) => t.key === sp.ky) ? (sp.ky as (typeof PERIOD_TABS)[number]["key"]) : "thang";
  const perAnchor = isRealDate(sp.ngay) ? sp.ngay : today();
  const perMonth = monthKey(perAnchor);
  const perRange =
    perTab === "tuan"
      ? (() => {
          const days = weekDays(weekStart(perAnchor));
          return { start: days[0], end: days[6] };
        })()
      : perTab === "quy"
        ? periodRange(quarterOfMonth(perMonth))
        : perTab === "nam"
          ? periodRange(perAnchor.slice(0, 4))
          : periodRange(perMonth);
  const perWhere = and(
    eq(orders.tenantId, session.tenantId),
    eq(orders.customerId, id),
    gte(orders.orderDate, perRange.start),
    lte(orders.orderDate, perRange.end),
  );
  const [perOrders] = await db
    .select({
      sales: sql<number>`coalesce(sum(${orders.totalAmount}) filter (where ${orders.status} <> 'CANCELLED'), 0)::bigint`,
      revenue: sql<number>`coalesce(sum(${orders.totalAmount}) filter (where ${orders.status} = 'CONFIRMED'), 0)::bigint`,
      surcharge: sql<number>`coalesce(sum(${orders.surchargeAmount}) filter (where ${orders.status} = 'CONFIRMED'), 0)::bigint`,
      orderCount: sql<number>`(count(*) filter (where ${orders.status} <> 'CANCELLED'))::int`,
    })
    .from(orders)
    .where(perWhere);
  const [perPaid] = await db
    .select({ paid: sql<number>`coalesce(sum(${orderPayments.amount}), 0)::bigint` })
    .from(orderPayments)
    .innerJoin(orders, eq(orderPayments.orderId, orders.id))
    .where(and(perWhere, eq(orders.status, "CONFIRMED")));
  const perSales = Number(perOrders?.sales ?? 0);
  const perRevenue = Number(perOrders?.revenue ?? 0);
  // Phụ thu phí khách phải trả nhưng không tính vào doanh thu sản phẩm → "còn nợ" = doanh thu + phụ thu − đã thu.
  const perPayable = perRevenue + Number(perOrders?.surcharge ?? 0);
  const perPaidAmount = Number(perPaid?.paid ?? 0);
  // Công nợ tại CUỐI kỳ = tổng nợ còn lại tính tới hết kỳ (gồm cả nợ từ các kỳ trước), khác "nợ phát sinh trong kỳ" ở trên.
  const perDebtDate = perRange.end < today() ? perRange.end : today();
  const perDebtEnd = (await averageMonthlyDebt(session.tenantId, [id], [perDebtDate])).get(id) ?? 0;
  const addDays = (iso: string, days: number) => new Date(Date.parse(`${iso}T00:00:00Z`) + days * 86_400_000).toISOString().slice(0, 10);
  const perPrev =
    perTab === "tuan"
      ? addDays(perRange.start, -7)
      : perTab === "quy"
        ? `${shiftMonth(perRange.start.slice(0, 7), 3)}-01`
        : perTab === "nam"
          ? `${Number(perRange.start.slice(0, 4)) - 1}-01-01`
          : `${shiftMonth(perRange.start.slice(0, 7), 1)}-01`;
  const perNext =
    perTab === "tuan"
      ? addDays(perRange.start, 7)
      : perTab === "quy"
        ? `${shiftMonth(perRange.start.slice(0, 7), -3)}-01`
        : perTab === "nam"
          ? `${Number(perRange.start.slice(0, 4)) + 1}-01-01`
          : `${shiftMonth(perRange.start.slice(0, 7), -1)}-01`;
  const perNextAllowed = perNext <= today();

  /* Lịch sử đi hỗ trợ: các lượt check-in tại điểm bán và các việc trong kế hoạch tuần
     gắn với khách này, gộp thành một dòng thời gian. */
  const [visitRows, planRows] = await Promise.all([
    db
      .select({
        at: checkIns.checkedAt,
        note: checkIns.note,
        outOfRange: checkIns.outOfRange,
        userName: users.fullName,
      })
      .from(checkIns)
      .leftJoin(users, eq(checkIns.userId, users.id))
      .where(and(eq(checkIns.tenantId, session.tenantId), eq(checkIns.customerId, id)))
      .orderBy(desc(checkIns.checkedAt))
      .limit(15),
    db
      .select({
        date: planItems.planDate,
        content: planItems.content,
        objective: planItems.objective,
        status: planItems.status,
        missedReason: planItems.missedReason,
        userName: users.fullName,
      })
      .from(planItems)
      .innerJoin(weeklyPlans, eq(planItems.planId, weeklyPlans.id))
      .leftJoin(users, eq(weeklyPlans.userId, users.id))
      .where(and(eq(planItems.tenantId, session.tenantId), eq(planItems.customerId, id), ne(planItems.status, "PLANNED")))
      .orderBy(desc(planItems.planDate))
      .limit(15),
  ]);
  const supportHistory = [
    ...visitRows.map((v) => ({
      date: dayInTz(v.at),
      who: v.userName ?? "—",
      text: `Check-in tại điểm bán${v.outOfRange ? " (ngoài phạm vi)" : ""}${v.note ? ` — ${v.note}` : ""}`,
      tone: v.outOfRange ? ("gold" as const) : ("green" as const),
      label: "Đã đến",
    })),
    ...planRows.map((p) => ({
      date: String(p.date),
      who: p.userName ?? "—",
      text: `${p.content}${p.objective ? ` — mục tiêu: ${p.objective}` : ""}${p.missedReason ? ` — lý do: ${p.missedReason}` : ""}`,
      tone: p.status === "DONE" ? ("green" as const) : ("red" as const),
      label: p.status === "DONE" ? "Đã làm" : "Chưa đạt",
    })),
  ]
    .sort((a, b) => b.date.localeCompare(a.date))
    .slice(0, 15);

  const months = lastMonths(period, 12);
  const skuWindowStart = periodRange(lastMonths(period, SKU_WINDOW_MONTHS)[0]).start;

  const [classification] = await db
    .select()
    .from(customerClassifications)
    .where(
      and(eq(customerClassifications.customerId, id), eq(customerClassifications.periodKey, period)),
    )
    .limit(1);

  const [monthlyRevenue, recentOrders, allProducts, history, contacts, notes, attachments, courseCompletions, courseOptions] =
    await Promise.all([
    db
      .select({
        month: sql<string>`to_char(${orders.orderDate}, 'YYYY-MM')`,
        revenue: sql<number>`coalesce(sum(${orders.totalAmount}), 0)::bigint`,
      })
      .from(orders)
      .where(and(eq(orders.customerId, id), eq(orders.status, "CONFIRMED")))
      .groupBy(sql`to_char(${orders.orderDate}, 'YYYY-MM')`),
    db
      .select({
        id: orders.id,
        code: orders.code,
        orderDate: orders.orderDate,
        totalAmount: orders.totalAmount,
        promoValue: orders.promoValue,
        surchargeAmount: orders.surchargeAmount,
        vatRequired: orders.vatRequired,
        status: orders.status,
        needsRevision: orders.needsRevision,
        salesUserId: orders.salesUserId,
        territoryId: orders.territoryId,
        dueDate: orders.dueDate,
        salesName: users.fullName,
        paid: sql<number>`coalesce(sum(${orderPayments.amount}), 0)::bigint`,
      })
      .from(orders)
      .leftJoin(users, eq(orders.salesUserId, users.id))
      .leftJoin(orderPayments, eq(orderPayments.orderId, orders.id))
      .where(and(eq(orders.tenantId, session.tenantId), eq(orders.customerId, id)))
      .groupBy(orders.id, users.fullName)
      .orderBy(desc(orders.orderDate), desc(orders.createdAt))
      .limit(50),
    db
      .select({
        productId: orderLines.productId,
        code: products.code,
        name: products.name,
        qtySold: sql<number>`coalesce(sum(${orderLines.qtySold}), 0)::int`,
        qtyPromo: sql<number>`coalesce(sum(${orderLines.qtyPromo}), 0)::int`,
        revenue: sql<number>`coalesce(sum(${orderLines.amount}), 0)::bigint`,
        lastDate: sql<string>`max(${orders.orderDate})::text`,
        // Đang ứng dụng = có mua trong cửa sổ SKU (cùng cách đếm với hạng SKU của hệ thống).
        recentQty: sql<number>`coalesce(sum(${orderLines.qtySold}) filter (where ${orders.orderDate} >= ${skuWindowStart}), 0)::int`,
      })
      .from(orderLines)
      .innerJoin(orders, eq(orderLines.orderId, orders.id))
      .innerJoin(products, eq(orderLines.productId, products.id))
      .where(and(eq(orders.customerId, id), eq(orders.status, "CONFIRMED"), sql`${orderLines.qtySold} > 0`))
      .groupBy(orderLines.productId, products.code, products.name)
      .orderBy(desc(sql`sum(${orderLines.amount})`)),
    db
      .select()
      .from(customerStageHistory)
      .where(eq(customerStageHistory.customerId, id))
      .orderBy(desc(customerStageHistory.changedAt)),
    db
      .select()
      .from(customerContacts)
      .where(eq(customerContacts.customerId, id))
      .orderBy(desc(customerContacts.createdAt)),
    db
      .select({
        id: customerNotes.id,
        content: customerNotes.content,
        recordedAt: customerNotes.recordedAt,
        recordedByName: users.fullName,
      })
      .from(customerNotes)
      .leftJoin(users, eq(customerNotes.recordedBy, users.id))
      .where(eq(customerNotes.customerId, id))
      .orderBy(desc(customerNotes.recordedAt)),
    db
      .select({
        id: customerAttachments.id,
        fileName: customerAttachments.fileName,
        mimeType: customerAttachments.mimeType,
        fileSize: customerAttachments.fileSize,
        filePath: customerAttachments.filePath,
        uploadedAt: customerAttachments.uploadedAt,
        uploadedByName: users.fullName,
      })
      .from(customerAttachments)
      .leftJoin(users, eq(customerAttachments.uploadedBy, users.id))
      .where(eq(customerAttachments.customerId, id))
      .orderBy(desc(customerAttachments.uploadedAt)),
    db
      .select({
        id: customerCourseCompletions.id,
        courseId: customerCourseCompletions.courseId,
        courseName: trainingCourses.name,
        completedDate: customerCourseCompletions.completedDate,
        isFree: customerCourseCompletions.isFree,
        note: customerCourseCompletions.note,
      })
      .from(customerCourseCompletions)
      .innerJoin(trainingCourses, eq(customerCourseCompletions.courseId, trainingCourses.id))
      .where(eq(customerCourseCompletions.customerId, id))
      .orderBy(desc(customerCourseCompletions.completedDate)),
    db
      .select({ id: trainingCourses.id, name: trainingCourses.name })
      .from(trainingCourses)
      .where(and(eq(trainingCourses.tenantId, session.tenantId), eq(trainingCourses.isActive, true)))
      .orderBy(trainingCourses.name),
  ]);

  const canOpenOrder = await orderViewChecker(session);
  const [metricsMap, overdueMap, [orderTotals]] = await Promise.all([
    customerMetrics(session, [id]),
    overdueDebt(session.tenantId, [id], today()),
    db
      .select({ count: sql<number>`(count(*) filter (where ${orders.status} <> 'CANCELLED'))::int` })
      .from(orders)
      .where(and(eq(orders.tenantId, session.tenantId), eq(orders.customerId, id))),
  ]);
  const outstanding = Math.max(metricsMap.get(id)?.outstanding ?? 0, 0);
  const overdueNow = overdueMap.get(id) ?? 0;
  // "Đang ứng dụng" = có mua trong cửa sổ SKU; số này khớp với "SKUs" của hạng SKU và của danh sách khách.
  const activeProducts = allProducts.filter((p) => Number(p.recentQty) > 0);
  const pastProducts = allProducts.filter((p) => Number(p.recentQty) <= 0);

  const revenueMap = new Map(monthlyRevenue.map((r) => [r.month, Number(r.revenue)]));
  const chartData = months.map((month) => ({ month, revenue: revenueMap.get(month) ?? 0 }));
  const totalRevenue = monthlyRevenue.reduce((sum, r) => sum + Number(r.revenue), 0);
  // Ngày chốt từ khách tiềm năng = mốc chuyển từ "Sẽ" sang giai đoạn khác trong lịch sử trạng thái.
  const convertedAt = history.find((entry) => entry.fromStage === "LEAD")?.changedAt ?? null;
  // Báo cáo trạng thái của khách tiềm năng: các dòng trao đổi có nhãn "[Đã liên hệ]"... ở đầu.
  const leadReports = notes
    .filter((note) => isLeadReport(note.content))
    .slice(0, 6)
    .map((note) => ({ ...note, tag: note.content.match(/^\[[^\]]+\]/)?.[0] ?? "" }));

  // Lịch sử chỉnh sửa hồ sơ (kể cả người liên quan, ghi chú, tệp, khoá học) — chỉ Ban giám đốc xem.
  const auditHistory = canManageSettings(session)
    ? await loadEntityHistory(session.tenantId, customer.id, ["customer", "customer_contact", "customer_note", "customer_attachment", "customer_course_completion"])
    : null;

  return (
    <>
      <PageHeader
        title={customer.orgName}
        subtitle={`${customer.code} · ${customer.channelName ?? "—"} · ${customer.territoryName ?? "—"}`}
        actions={
          <>
            <Link href={`/khach-hang/${customer.id}/sua`} className="btn-ghost">
              Sửa hồ sơ
            </Link>
            <Link href="/khach-hang" className="btn-ghost">
              ← Danh sách
            </Link>
          </>
        }
      />

      <div className="mb-5 flex flex-wrap items-center gap-2">
        <Badge tone={customer.stage === "DEALER" ? "brand" : customer.stage === "PROSPECT" ? "gold" : "neutral"}>
          {STAGE_LABEL[customer.stage]}
        </Badge>
        {customer.isKey && <Badge tone="gold">Đại lý Key</Badge>}
        {classification && (classification.monthsInactive ?? 0) >= 2 && (
          <Badge tone="red">{classification.monthsInactive} tháng không lấy hàng</Badge>
        )}

        {/* Chuyển trạng thái trong phễu — mỗi lần chuyển đều được ghi mốc thời gian. */}
        {/* Khách tiềm năng chỉ chuyển thành khách qua form "Chốt" bên dưới (bắt buộc báo cáo). */}
        {customer.leadStatus === "CONVERTED" && (
          <Badge tone="green">
            Từ khách tiềm năng{convertedAt ? ` · chốt ${formatDate(convertedAt)}` : ""}
          </Badge>
        )}
        {STAGE_ORDER.filter((stage) => stage !== customer.stage && customer.stage !== "LEAD").map((stage) => (
          <ActionForm key={stage} action={changeStageAction} success="Đã chuyển trạng thái." confirm={`Chuyển khách này sang ${STAGE_LABEL[stage]}?`}>
            <input type="hidden" name="id" value={customer.id} />
            <input type="hidden" name="stage" value={stage} />
            <button type="submit" className="btn-ghost px-3 py-1 text-xs">
              Chuyển sang {STAGE_LABEL[stage]}
            </button>
          </ActionForm>
        ))}

        {session.role !== "SALES" && customer.stage === "DEALER" && (
          <ActionForm action={toggleKeyAction} success="Đã cập nhật đại lý Key.">
            <input type="hidden" name="id" value={customer.id} />
            <button type="submit" className="btn-ghost px-3 py-1 text-xs">
              {customer.isKey ? "Bỏ đánh dấu Key" : "Đánh dấu ĐL Key"}
            </button>
          </ActionForm>
        )}
      </div>

      {customer.stage === "LEAD" && (
        <div className="card mb-5 p-4">
          <div className="mb-2 flex flex-wrap items-center gap-2">
            <SectionTitle>Khách tiềm năng</SectionTitle>
            <Badge tone={LEAD_TONE[customer.leadStatus] ?? "neutral"}>{LEAD_LABEL[customer.leadStatus] ?? customer.leadStatus}</Badge>
            <span className="text-xs text-ink-400">
              Thêm ngày {formatDate(customer.createdAt)} · nguồn: {customer.leadSource ?? "—"} · nhu cầu: {customer.leadNeed ?? "—"}
            </span>
          </div>

          <ActionForm action={updateLeadStatusAction} success="Đã cập nhật trạng thái khách tiềm năng." resetOnSuccess>
            <input type="hidden" name="id" value={customer.id} />
            <div className="flex flex-wrap items-end gap-2">
              <select name="leadStatus" defaultValue={customer.leadStatus} className="input w-auto" aria-label="Trạng thái chuyển đổi">
                {LEAD_UPDATE_OPTIONS.map((value) => (
                  <option key={value} value={value}>
                    {LEAD_LABEL[value]}
                  </option>
                ))}
              </select>
              <input name="report" className="input min-w-56 flex-1" placeholder="Báo cáo: kết quả liên hệ / lý do huỷ (bắt buộc với Đã liên hệ, Đã huỷ)" />
              <button type="submit" className="btn-ghost">
                Cập nhật
              </button>
            </div>
          </ActionForm>

          <details className="mt-3 rounded-lg border border-[var(--color-line)] p-3">
            <summary className="cursor-pointer text-sm font-semibold text-emerald-700">Chốt — chuyển thành khách</summary>
            <ActionForm action={convertLeadAction} success="Đã chốt — chuyển thành khách." className="mt-3 grid gap-2 lg:grid-cols-2">
              <input type="hidden" name="id" value={customer.id} />
              <label className="text-[11px] text-ink-400">
                Chuyển thành
                <select name="stage" defaultValue="PROSPECT" className="input">
                  <option value="PROSPECT">{STAGE_LABEL.PROSPECT} — đã tham dự chương trình công ty</option>
                  <option value="DEALER">{STAGE_LABEL.DEALER} — mở code chính thức</option>
                </select>
              </label>
              <label className="text-[11px] text-ink-400">
                Tên cơ sở
                <input
                  name="orgName"
                  defaultValue={customer.orgName !== customer.contactName ? customer.orgName : ""}
                  placeholder="Tên phòng khám / TMV / Spa"
                  className="input"
                />
              </label>
              <label className="text-[11px] text-ink-400 lg:col-span-2">
                Báo cáo kết quả chốt (bắt buộc)
                <textarea name="report" rows={2} required placeholder="Khách đồng ý gì, hẹn gì, đơn đầu tiên dự kiến…" className="input" />
              </label>
              <button type="submit" className="btn-primary self-start px-3 py-1.5 text-xs">
                Chốt — chuyển thành khách
              </button>
              <p className="text-[11px] text-ink-400 lg:col-span-2">Hồ sơ phải đủ loại, người liên hệ, điện thoại, tỉnh, phường và địa chỉ; nếu thiếu hệ thống sẽ nói rõ thiếu gì.</p>
            </ActionForm>
          </details>

          {leadReports.length > 0 && (
            <ul className="mt-3 flex flex-col gap-1 border-t border-[var(--color-line)] pt-2 text-xs text-ink-500">
              {leadReports.map((report) => (
                <li key={report.id}>
                  <span className="tnum text-ink-400">{formatDateTime(report.recordedAt)}</span> · {report.tag} {stripReportTag(report.content)}
                  <span className="text-ink-400"> — {report.recordedByName ?? "—"}</span>
                </li>
              ))}
            </ul>
          )}
        </div>
      )}

      <div className="grid gap-4 lg:grid-cols-3">
        {/* Thông tin liên hệ */}
        <div className="card p-4">
          <SectionTitle>Thông tin liên hệ</SectionTitle>
          <dl className="flex flex-col gap-2 text-sm">
            <div className="flex justify-between gap-3">
              <dt className="text-ink-400">Người liên hệ</dt>
              <dd className="text-right text-ink-700">{customer.contactName ?? "—"}</dd>
            </div>
            <div className="flex justify-between gap-3">
              <dt className="text-ink-400">Chức vụ</dt>
              <dd className="text-right text-ink-700">{customer.contactPosition ?? "—"}</dd>
            </div>
            <div className="flex justify-between gap-3">
              <dt className="text-ink-400">Ngày sinh</dt>
              <dd className="tnum text-right text-ink-700">{formatDate(customer.contactBirthDate)}</dd>
            </div>
            <div className="flex justify-between gap-3">
              <dt className="text-ink-400">Điện thoại</dt>
              <dd className="tnum text-right text-ink-700">{customer.phone ?? "—"}</dd>
            </div>
            <div className="flex justify-between gap-3">
              <dt className="text-ink-400">Mã số thuế</dt>
              <dd className="tnum text-right text-ink-700">{customer.taxCode ?? "—"}</dd>
            </div>
            <div className="flex justify-between gap-3">
              <dt className="text-ink-400">NVKD phụ trách</dt>
              <dd className="text-right text-ink-700">{customer.ownerName ?? "—"}</dd>
            </div>
            <div className="flex justify-between gap-3">
              <dt className="text-ink-400">Mở code từ</dt>
              <dd className="tnum text-right text-ink-700">{formatDate(customer.dealerSince)}</dd>
            </div>
            <div className="flex flex-col gap-1">
              <dt className="text-ink-400">Địa chỉ</dt>
              <dd className="text-ink-700">
                {[customer.address, customer.ward, customer.territoryName].filter(Boolean).join(", ") || "—"}
              </dd>
            </div>
            {(customer.receiverName || customer.receiverPhone || customer.receiverAddress) && (
              <div className="flex flex-col gap-1 border-t border-[var(--color-line)] pt-2">
                <dt className="text-ink-400">Người nhận hàng</dt>
                <dd className="text-ink-700">
                  {[customer.receiverName, customer.receiverPhone].filter(Boolean).join(" · ") || "—"}
                  {customer.receiverAddress ? <div className="text-xs text-ink-500">{customer.receiverAddress}</div> : null}
                </dd>
              </div>
            )}
          </dl>
        </div>

        {/* Phân hạng tự động */}
        <div className="card p-4 lg:col-span-2">
          <SectionTitle hint={`kỳ ${formatPeriod(period)}`}>Phân hạng tự động</SectionTitle>
          {!classification ? (
            <p className="py-6 text-center text-sm text-ink-400">
              Chưa có dữ liệu phân hạng cho kỳ này.
            </p>
          ) : (
            <div className="grid grid-cols-2 gap-3 lg:grid-cols-4">
              <div>
                <div className="label-caps mb-1">Hạng doanh thu</div>
                <div className="flex items-center gap-2">
                  <TierBadge tier={classification.revenueTier} />
                  <span className="tnum text-sm font-semibold text-ink-700">
                    {formatVndShort(Number(classification.avgMonthlyRevenue))}
                  </span>
                </div>
                <div className="mt-1 text-[11px] text-ink-400">
                  {REVENUE_TIERS.find((t) => t.tier === classification.revenueTier)?.label}
                </div>
              </div>
              <div>
                <div className="label-caps mb-1">Hạng SKUs</div>
                <div className="flex items-center gap-2">
                  <TierBadge tier={classification.skuTier} />
                  <span className="tnum text-sm font-semibold text-ink-700">
                    {classification.skuCount} SP
                  </span>
                </div>
                <div className="mt-1 text-[11px] text-ink-400">
                  {SKU_TIERS.find((t) => t.tier === classification.skuTier)?.label}
                </div>
              </div>
              <div>
                <div className="label-caps mb-1">Đơn tái hàng</div>
                <div className="tnum text-lg font-bold text-ink-700">{classification.reorderCount}</div>
                <div className="text-[11px] text-ink-400">trong tháng này</div>
              </div>
              <div>
                <div className="label-caps mb-1">Tháng có lấy hàng</div>
                <div className="tnum text-lg font-bold text-ink-700">
                  {classification.monthsPurchasedInQuarter}/3
                </div>
                <div className="text-[11px] text-ink-400">
                  quý này · {classification.monthsPurchasedInYear} tháng trong năm
                </div>
              </div>
            </div>
          )}
        </div>
      </div>

      <div className="mt-5 grid grid-cols-2 gap-3 lg:grid-cols-4">
        <StatCard label="Tổng doanh thu" value={formatVndShort(totalRevenue)} hint={`${formatVnd(totalRevenue)} · đơn đã duyệt, toàn lịch sử`} />
        <StatCard label="Số đơn đã lập" value={formatNumber(Number(orderTotals?.count ?? 0))} hint="chưa tính đơn huỷ" />
        <StatCard
          label="Công nợ hiện tại"
          value={formatVndShort(outstanding)}
          hint={overdueNow > 0 ? `trong đó quá hạn ${formatVndShort(overdueNow)}` : "chưa thu của các đơn đã duyệt"}
          tone={overdueNow > 0 ? "bad" : outstanding > 0 ? "warn" : "good"}
        />
        <StatCard
          label="Doanh thu BQ tháng"
          value={classification ? formatVndShort(Number(classification.avgMonthlyRevenue)) : "—"}
          hint="12 tháng gần nhất"
        />
      </div>

      <div className="mt-6 card p-4">
        <SectionTitle hint={`${formatDate(perRange.start)} → ${formatDate(perRange.end)}`}>
          Doanh số · Doanh thu · Công nợ theo kỳ
        </SectionTitle>
        <form className="mb-4 flex flex-wrap items-end gap-3" action={`/khach-hang/${id}`}>
          <div className="flex gap-1 rounded-lg border border-[var(--color-line)] bg-white p-1">
            {PERIOD_TABS.map((item) => (
              <Link
                key={item.key}
                href={`/khach-hang/${id}?ky=${item.key}&ngay=${perAnchor}`}
                className={`rounded-md px-3 py-1.5 text-sm font-semibold ${
                  perTab === item.key ? "bg-brand-500 text-white" : "text-ink-500 hover:bg-ink-50"
                }`}
              >
                {item.label}
              </Link>
            ))}
          </div>
          <input type="hidden" name="ky" value={perTab} />
          <div className="flex items-center gap-1">
            <Link href={`/khach-hang/${id}?ky=${perTab}&ngay=${perPrev}`} className="btn-ghost px-3 py-1.5" aria-label="Kỳ trước">
              ←
            </Link>
            {perNextAllowed ? (
              <Link href={`/khach-hang/${id}?ky=${perTab}&ngay=${perNext}`} className="btn-ghost px-3 py-1.5" aria-label="Kỳ sau">
                →
              </Link>
            ) : (
              <span className="btn-ghost pointer-events-none px-3 py-1.5 opacity-40" aria-hidden>
                →
              </span>
            )}
          </div>
          <div>
            <label htmlFor="ngay" className="label-caps mb-1.5 block">
              Mốc thời gian
            </label>
            <input id="ngay" name="ngay" type="date" defaultValue={perAnchor} className="input" />
          </div>
          <button type="submit" className="btn-ghost">
            Xem
          </button>
        </form>
        <div className="grid grid-cols-2 gap-3 lg:grid-cols-5">
          <StatCard label="Doanh số" value={formatVndShort(perSales)} hint={`${formatNumber(Number(perOrders?.orderCount ?? 0))} đơn đã lập`} />
          <StatCard label="Doanh thu" value={formatVndShort(perRevenue)} hint="đơn đã duyệt" />
          <StatCard label="Đã thu" value={formatVndShort(perPaidAmount)} hint="của các đơn đã duyệt" />
          <StatCard
            label="Còn nợ của kỳ"
            value={formatVndShort(Math.max(0, perPayable - perPaidAmount))}
            hint="phải thu kỳ này (gồm phụ thu) chưa thu"
            tone={perPayable - perPaidAmount > 0 ? "warn" : "good"}
          />
          <StatCard
            label="Công nợ cuối kỳ"
            value={formatVndShort(Math.max(0, perDebtEnd))}
            hint={`tổng nợ tới ${formatDate(perDebtDate)}, gồm cả nợ cũ`}
            tone={perDebtEnd > 0 ? "warn" : "good"}
          />
        </div>
      </div>

      <div className="mt-6 card p-4">
        <SectionTitle hint="12 tháng gần nhất">Diễn biến doanh thu</SectionTitle>
        <MonthlyRevenueChart data={chartData} />
      </div>

      <div className="mt-6">
        <SectionTitle hint={`${recentOrders.length}${Number(orderTotals?.count ?? 0) > recentOrders.length ? ` đơn gần nhất / ${orderTotals?.count}` : " đơn"}`}>
          Lịch sử lên đơn
        </SectionTitle>
        {recentOrders.length === 0 ? (
          <EmptyState message="Khách hàng chưa phát sinh đơn hàng nào." />
        ) : (
          <TableWrap>
            <thead>
              <tr>
                <th>Mã đơn</th>
                <th>Ngày</th>
                <th>NVKD</th>
                <th>Trạng thái</th>
                <th className="text-right">Thành tiền</th>
                <th className="text-right">Đã thu</th>
                <th className="text-right">Còn nợ</th>
              </tr>
            </thead>
            <tbody>
              {recentOrders.map((order) => {
                const badge = orderStatusBadge(order);
                const owed = order.status === "CONFIRMED" ? Math.max(Number(order.totalAmount) + Number(order.surchargeAmount) - Number(order.paid), 0) : 0;
                const late = owed > 0 && !!order.dueDate && order.dueDate < today();
                return (
                  <tr key={order.id}>
                    <td className="font-medium text-ink-700">
                      {canOpenOrder(order) ? (
                        <Link href={`/don-hang/${order.id}`} className="hover:text-brand-600 hover:underline">
                          {order.code}
                        </Link>
                      ) : (
                        order.code
                      )}
                    </td>
                    <td className="tnum text-ink-500">{formatDate(order.orderDate)}</td>
                    <td className="text-ink-500">{order.salesName ?? "—"}</td>
                    <td>
                      <Badge tone={badge.tone}>{badge.label}</Badge>
                    </td>
                    <td className="tnum text-right font-semibold">{formatVnd(Number(order.totalAmount))}</td>
                    <td className="tnum text-right text-ink-500">{order.status === "CONFIRMED" && Number(order.paid) > 0 ? formatVndShort(Number(order.paid)) : "—"}</td>
                    <td className="tnum text-right">
                      {owed > 0 ? (
                        <span className={`font-semibold ${late ? "text-red-600" : "text-gold-500"}`}>
                          {formatVndShort(owed)}
                          {late && <span className="block text-[11px] font-medium">quá hạn {formatDate(order.dueDate)}</span>}
                        </span>
                      ) : (
                        <span className="text-ink-300">—</span>
                      )}
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </TableWrap>
        )}
      </div>

      <div className="mt-6">
        <SectionTitle hint={`${activeProducts.length} SP trong ${SKU_WINDOW_MONTHS} tháng gần nhất`}>Sản phẩm đang ứng dụng</SectionTitle>
        {activeProducts.length === 0 ? (
          <EmptyState message="Chưa có sản phẩm nào đang ứng dụng." hint={`Sản phẩm xuất hiện khi khách có đơn đã duyệt trong ${SKU_WINDOW_MONTHS} tháng gần nhất.`} />
        ) : (
          <TableWrap>
            <thead>
              <tr>
                <th>Sản phẩm</th>
                <th className="text-right">SL bán</th>
                <th className="text-right">SL KM</th>
                <th className="text-right">Doanh thu</th>
                <th className="text-right">Lần mua gần nhất</th>
              </tr>
            </thead>
            <tbody>
              {activeProducts.map((product) => (
                <tr key={product.productId}>
                  <td>
                    <div className="font-medium text-ink-700">{product.name}</div>
                    <div className="text-[11px] text-ink-400">{product.code}</div>
                  </td>
                  <td className="tnum text-right">{formatNumber(Number(product.qtySold))}</td>
                  <td className="tnum text-right text-ink-400">{formatNumber(Number(product.qtyPromo))}</td>
                  <td className="tnum text-right font-medium">{formatVndShort(Number(product.revenue))}</td>
                  <td className="tnum text-right text-ink-500">{formatDate(product.lastDate)}</td>
                </tr>
              ))}
            </tbody>
          </TableWrap>
        )}
        <p className="mt-1.5 text-[11px] text-ink-400">Số liệu SL/doanh thu là toàn lịch sử của từng sản phẩm; danh sách chỉ gồm sản phẩm có mua trong {SKU_WINDOW_MONTHS} tháng gần nhất.</p>
        {pastProducts.length > 0 && (
          <details className="card mt-3 p-3">
            <summary className="cursor-pointer text-sm font-semibold text-ink-600">Từng dùng nhưng {SKU_WINDOW_MONTHS} tháng nay không mua ({pastProducts.length} SP)</summary>
            <ul className="mt-2 flex flex-col gap-1 text-sm">
              {pastProducts.map((product) => (
                <li key={product.productId} className="flex flex-wrap justify-between gap-2 text-ink-600">
                  <span>
                    {product.name} <span className="text-[11px] text-ink-400">{product.code}</span>
                  </span>
                  <span className="tnum text-xs text-ink-400">mua lần cuối {formatDate(product.lastDate)}</span>
                </li>
              ))}
            </ul>
          </details>
        )}
      </div>

      {history.length > 0 && (
        <div className="mt-6">
          <SectionTitle hint="mốc chuyển đổi phễu">Lịch sử trạng thái</SectionTitle>
          <div className="card p-4">
            <ul className="flex flex-col gap-2 text-sm">
              {history.map((entry) => (
                <li key={entry.id} className="flex flex-wrap items-center gap-2">
                  <span className="tnum text-xs text-ink-400">{formatDate(entry.changedAt)}</span>
                  {entry.fromStage && (
                    <>
                      <Badge>{STAGE_LABEL[entry.fromStage]}</Badge>
                      <span className="text-ink-300">→</span>
                    </>
                  )}
                  <Badge tone="brand">{STAGE_LABEL[entry.toStage]}</Badge>
                  {entry.note && <span className="text-xs text-ink-400">{entry.note}</span>}
                </li>
              ))}
            </ul>
          </div>
        </div>
      )}

      <div className="mt-6">
        <SectionTitle hint="check-in và kế hoạch tuyến đã báo cáo">Lịch sử báo cáo &amp; đi hỗ trợ</SectionTitle>
        {supportHistory.length === 0 ? (
          <EmptyState message="Chưa có lượt đi hỗ trợ nào." hint="Xuất hiện khi NVKD check-in hoặc báo cáo kết quả buổi làm việc tại khách này." />
        ) : (
          <div className="card p-4">
            <ul className="flex flex-col gap-2 text-sm">
              {supportHistory.map((entry, index) => (
                <li key={index} className="flex flex-wrap items-start gap-2">
                  <span className="tnum w-20 shrink-0 text-xs text-ink-400">{formatDate(entry.date)}</span>
                  <Badge tone={entry.tone}>{entry.label}</Badge>
                  <span className="min-w-0 flex-1 text-ink-600">
                    {entry.text} <span className="text-xs text-ink-400">· {entry.who}</span>
                  </span>
                </li>
              ))}
            </ul>
          </div>
        )}
      </div>

      {/* Người liên quan & Thông tin trao đổi — yêu cầu mục 5 */}
      <div className="mt-6 grid gap-4 lg:grid-cols-2">
        <div>
          <SectionTitle hint={`${contacts.length} người`}>Người liên quan</SectionTitle>
          <div className="card p-4">
            {contacts.length === 0 ? (
              <p className="py-4 text-center text-sm text-ink-400">
                Chưa có người liên quan nào khác ngoài người liên hệ chính.
              </p>
            ) : (
              <ul className="flex flex-col gap-2.5">
                {contacts.map((contact) => (
                  <li
                    key={contact.id}
                    className="flex items-start justify-between gap-2 border-b border-[var(--color-line)] pb-2 last:border-0"
                  >
                    <div className="min-w-0 flex-1">
                      <div className="text-sm font-medium text-ink-700">{contact.fullName}</div>
                      <div className="text-[11px] text-ink-400">
                        {contact.position ?? "—"}
                        {contact.phone ? ` · ${contact.phone}` : ""}
                      </div>
                      <details className="mt-1">
                        <summary className="cursor-pointer text-[11px] font-semibold text-brand-600">Sửa</summary>
                        <ActionForm action={updateContactAction} success="Đã cập nhật người liên quan." className="mt-1.5 grid gap-2 lg:grid-cols-3">
                          <input type="hidden" name="id" value={contact.id} />
                          <input type="hidden" name="customerId" value={customer.id} />
                          <input name="fullName" required defaultValue={contact.fullName} placeholder="Họ tên" className="input" aria-label="Họ tên" />
                          <input name="position" defaultValue={contact.position ?? ""} placeholder="Chức vụ" className="input" aria-label="Chức vụ" />
                          <input name="phone" defaultValue={contact.phone ?? ""} placeholder="Điện thoại" className="input" aria-label="Điện thoại" />
                          <button type="submit" className="btn-ghost self-start text-xs">
                            Lưu
                          </button>
                        </ActionForm>
                      </details>
                    </div>
                    {session.role !== "SALES" && (
                      <ActionForm action={deleteContactAction} success="Đã xoá người liên quan." confirm="Xoá người liên quan này?">
                        <input type="hidden" name="id" value={contact.id} />
                        <input type="hidden" name="customerId" value={customer.id} />
                        <button type="submit" className="btn-ghost px-2 py-1 text-xs text-red-600">
                          Xoá
                        </button>
                      </ActionForm>
                    )}
                  </li>
                ))}
              </ul>
            )}
            <ActionForm
              action={addContactAction} success="Đã thêm người liên quan." resetOnSuccess
              className="mt-3 flex flex-col gap-2 border-t border-[var(--color-line)] pt-3"
            >
              <input type="hidden" name="customerId" value={customer.id} />
              <div className="grid gap-2 lg:grid-cols-3">
                <input name="fullName" required placeholder="Họ tên" className="input" />
                <input name="position" placeholder="Chức vụ" className="input" />
                <input name="phone" placeholder="Điện thoại" className="input" />
              </div>
              <button type="submit" className="btn-ghost self-start text-xs">
                + Thêm người liên quan
              </button>
            </ActionForm>
          </div>
        </div>

        <div>
          <SectionTitle hint={`${notes.length} lần trao đổi`}>Thông tin trao đổi</SectionTitle>
          <div className="card p-4">
            {notes.length === 0 ? (
              <p className="py-4 text-center text-sm text-ink-400">Chưa có nội dung trao đổi nào.</p>
            ) : (
              <ul className="flex max-h-72 flex-col gap-2.5 overflow-y-auto">
                {notes.map((note) => (
                  <li key={note.id} className="border-b border-[var(--color-line)] pb-2 last:border-0">
                    <div className="flex items-baseline justify-between gap-2">
                      <span className="tnum text-[11px] text-ink-400">
                        {formatDateTime(note.recordedAt)} · {note.recordedByName ?? "—"}
                      </span>
                      {session.role !== "SALES" && (
                        <ActionForm action={deleteNoteAction} success="Đã xoá ghi chú." confirm="Xoá ghi chú này?">
                          <input type="hidden" name="id" value={note.id} />
                          <input type="hidden" name="customerId" value={customer.id} />
                          <button type="submit" className="btn-ghost px-1 py-0 text-[11px] text-red-600">
                            Xoá
                          </button>
                        </ActionForm>
                      )}
                    </div>
                    <p className="mt-0.5 text-sm text-ink-700">{note.content}</p>
                  </li>
                ))}
              </ul>
            )}
            <ActionForm
              action={addNoteAction} success="Đã thêm ghi chú." resetOnSuccess
              className="mt-3 flex flex-col gap-2 border-t border-[var(--color-line)] pt-3"
            >
              <input type="hidden" name="customerId" value={customer.id} />
              <textarea
                name="content"
                required
                rows={2}
                placeholder="Nội dung trao đổi, cuộc gọi, phản hồi của khách…"
                className="input"
              />
              <button type="submit" className="btn-ghost self-start text-xs">
                + Ghi nhận trao đổi
              </button>
            </ActionForm>
          </div>
        </div>
      </div>

      <div className="mt-6">
        <SectionTitle hint={`${attachments.length} tệp`}>Tệp đính kèm</SectionTitle>
        <div className="card p-4">
          {attachments.length === 0 ? (
            <p className="py-4 text-center text-sm text-ink-400">
              Chưa có tệp đính kèm nào — hợp đồng, giấy phép kinh doanh, ảnh CCCD...
            </p>
          ) : (
            <ul className="flex flex-col gap-2.5">
              {attachments.map((file) => (
                <li
                  key={file.id}
                  className="flex items-center justify-between gap-2 border-b border-[var(--color-line)] pb-2 last:border-0"
                >
                  <a
                    href={`/api/anh/${file.filePath}`}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="min-w-0 hover:underline"
                  >
                    <div className="truncate text-sm font-medium text-ink-700">{file.fileName}</div>
                    <div className="text-[11px] text-ink-400">
                      {formatFileSize(file.fileSize)} · {formatDateTime(file.uploadedAt)} ·{" "}
                      {file.uploadedByName ?? "—"}
                    </div>
                  </a>
                  {session.role !== "SALES" && (
                    <ActionForm action={deleteAttachmentAction} success="Đã xoá tệp đính kèm." confirm="Xoá tệp đính kèm này?">
                      <input type="hidden" name="id" value={file.id} />
                      <input type="hidden" name="customerId" value={customer.id} />
                      <button type="submit" className="btn-ghost shrink-0 px-2 py-1 text-xs text-red-600">
                        Xoá
                      </button>
                    </ActionForm>
                  )}
                </li>
              ))}
            </ul>
          )}
          <ActionForm
            action={uploadAttachmentAction} success="Đã tải tệp lên." resetOnSuccess
            className="mt-3 flex flex-col gap-2 border-t border-[var(--color-line)] pt-3 lg:flex-row lg:items-center"
          >
            <input type="hidden" name="customerId" value={customer.id} />
            <input
              name="file"
              type="file"
              required
              accept="application/pdf,image/png,image/jpeg"
              className="input"
            />
            <button type="submit" className="btn-ghost shrink-0 self-start text-xs">
              + Đính kèm tệp
            </button>
          </ActionForm>
          <p className="mt-1.5 text-[11px] text-ink-400">PDF, PNG hoặc JPEG — tối đa 8MB.</p>
        </div>
      </div>

      <div className="mt-6">
        <SectionTitle hint={`${courseCompletions.length} khóa`}>Khóa học đã học</SectionTitle>
        <div className="card p-4">
          {courseCompletions.length === 0 ? (
            <p className="py-4 text-center text-sm text-ink-400">
              Chưa ghi nhận khách học khóa nào — tránh phải lục giấy tờ khi cần đối chiếu.
            </p>
          ) : (
            <ul className="flex flex-col gap-2.5">
              {courseCompletions.map((c) => (
                <li
                  key={c.id}
                  className="flex items-center justify-between gap-2 border-b border-[var(--color-line)] pb-2 last:border-0"
                >
                  <div className="min-w-0">
                    <div className="truncate text-sm font-medium text-ink-700">{c.courseName}</div>
                    <div className="text-[11px] text-ink-400">
                      Học ngày {formatDate(c.completedDate)} · {c.isFree ? "Miễn phí" : "Đóng phí"}
                      {c.note ? ` · ${c.note}` : ""}
                    </div>
                  </div>
                  {session.role !== "SALES" && (
                    <ActionForm action={deleteCourseCompletionAction} success="Đã xoá lịch sử học." confirm="Xoá lịch sử học này?">
                      <input type="hidden" name="id" value={c.id} />
                      <input type="hidden" name="customerId" value={customer.id} />
                      <button type="submit" className="btn-ghost shrink-0 px-2 py-1 text-xs text-red-600">
                        Xoá
                      </button>
                    </ActionForm>
                  )}
                </li>
              ))}
            </ul>
          )}
          {courseOptions.length > 0 && (
            <ActionForm
              action={recordCourseCompletionAction} success="Đã ghi nhận khoá học." resetOnSuccess
              className="mt-3 flex flex-col gap-2 border-t border-[var(--color-line)] pt-3 lg:flex-row lg:items-end"
            >
              <input type="hidden" name="customerId" value={customer.id} />
              <select name="courseId" required className="input" defaultValue="">
                <option value="" disabled>
                  — Chọn khóa học —
                </option>
                {courseOptions.map((course) => (
                  <option key={course.id} value={course.id}>
                    {course.name}
                  </option>
                ))}
              </select>
              <input type="date" name="completedDate" required defaultValue={today()} className="input" />
              <label className="flex items-center gap-1.5 whitespace-nowrap text-sm text-ink-600">
                <input type="checkbox" name="isFree" className="h-4 w-4 accent-brand-500" />
                Miễn phí
              </label>
              <input name="note" placeholder="Ghi chú (tuỳ chọn)" className="input" />
              <button type="submit" className="btn-ghost shrink-0 self-start text-xs">
                + Ghi nhận
              </button>
            </ActionForm>
          )}
          {courseOptions.length === 0 && (
            <p className="mt-3 border-t border-[var(--color-line)] pt-3 text-[11px] text-ink-400">
              Chưa có khóa học nào trong danh mục — thêm ở Danh mục → Khóa học.
            </p>
          )}
        </div>
      </div>
      {auditHistory && (
        <div className="mt-6">
          <EntityHistory entries={auditHistory} />
        </div>
      )}
    </>
  );
}
