import Link from "next/link";
import { and, eq, sql } from "drizzle-orm";
import { requireSession } from "@/lib/auth";
import { db } from "@/db";
import { customers } from "@/db/schema";
import {
  ALERT_FILTERS,
  LEAD_LABEL,
  RANGES,
  SKU_THRESHOLDS,
  SORTS,
  STAGES,
  areaLabel,
  customerFilterOptions,
  loadCustomerList,
  parseCustomerListQuery,
  MAX_MATCHED,
  type CustomerListQuery,
  type CustomerListRow,
  type CustomerWarning,
  type SortKey,
} from "@/lib/customer-list";
import { formatVndShort, formatNumber, formatDate, STAGE_LABEL } from "@/lib/format";
import { PageHeader, TableWrap, Badge, TierBadge, StatCard } from "@/components/ui";
import { CustomerTabs } from "./customer-tabs";

export const dynamic = "force-dynamic";

const PAGE_SIZE = 50;

const WARNING_TONE: Record<CustomerWarning["severity"], "red" | "gold" | "neutral"> = {
  CRITICAL: "red",
  WARNING: "gold",
  INFO: "neutral",
};

export default async function CustomersPage({ searchParams }: { searchParams: Promise<Record<string, string | undefined>> }) {
  const session = await requireSession();
  const params = await searchParams;
  const query = parseCustomerListQuery((key) => params[key]);

  const [list, options] = await Promise.all([loadCustomerList(session, query), customerFilterOptions(session)]);
  const { rows: all, range, scope, capped } = list;

  const totalPages = Math.max(1, Math.ceil(all.length / PAGE_SIZE));
  const page = Math.min(query.page, totalPages);
  const rows = all.slice((page - 1) * PAGE_SIZE, page * PAGE_SIZE);

  // Đếm theo từng trạng thái để hiển thị phễu, không phụ thuộc bộ lọc đang chọn.
  const counts = await db
    .select({ stage: customers.stage, count: sql<number>`count(*)::int` })
    .from(customers)
    .where(and(scope, eq(customers.isActive, true)))
    .groupBy(customers.stage);
  const countOf = (stage: string) => Number(counts.find((c) => c.stage === stage)?.count ?? 0);

  /** Đường dẫn giữ nguyên bộ lọc hiện tại, chỉ đổi những khoá được truyền vào. */
  const queryString = (patch: Partial<CustomerListQuery> = {}) => {
    const next = { ...query, page: 1, ...patch };
    const qs = new URLSearchParams();
    const set = (key: string, value: string | number, skip: boolean) => {
      if (!skip && value !== "" && value !== 0) qs.set(key, String(value));
    };
    set("q", next.q, false);
    set("stage", next.stage, false);
    set("tier", next.tier, false);
    set("lead", next.lead, false);
    set("sp", next.minSku, false);
    set("kv", next.territory, false);
    set("pb", next.dept, false);
    set("nv", next.owner, false);
    set("cb", next.alert, false);
    set("sap", next.sort, next.sort === "hang");
    set("huong", next.dir, next.dir === "giam");
    set("ky", next.range, next.range === "thang");
    set("trang", next.page, next.page === 1);
    return qs.toString();
  };
  const href = (patch: Partial<CustomerListQuery> = {}) => {
    const text = queryString(patch);
    return text ? `/khach-hang?${text}` : "/khach-hang";
  };
  // File Excel dùng đúng bộ lọc + xếp hạng đang xem (toàn bộ kết quả, không chỉ trang hiện tại).
  const exportHref = `/api/xuat-excel?loai=khach-hang${queryString() ? `&${queryString()}` : ""}`;

  /** Bấm lại đúng cột đang xếp thì đảo chiều; đổi sang cột khác thì bắt đầu từ giảm dần. */
  const sortHref = (key: SortKey) => href({ sort: key, dir: query.sort === key && query.dir === "giam" ? "tang" : "giam" });
  const arrow = (key: SortKey) => (query.sort === key ? (query.dir === "giam" ? " ↓" : " ↑") : "");

  const sortInfo = SORTS.find((s) => s.key === query.sort)!;
  const filtersActive = !!(query.q || query.stage || query.tier || query.lead || query.minSku || query.owner || query.dept || query.territory || query.alert);
  const monthNote = range.months.length > 1 ? ` (bình quân theo ${range.months.length} tháng đã bắt đầu)` : "";

  const sortLink = (key: SortKey, label: string) => (
    <Link href={sortHref(key)} className={`hover:underline ${query.sort === key ? "font-bold text-brand-600" : "text-ink-400"}`}>
      {label}
      {arrow(key)}
    </Link>
  );

  const warningChips = (row: CustomerListRow) =>
    row.warnings.length === 0 ? (
      <span className="text-ink-300">—</span>
    ) : (
      <div className="flex flex-col items-start gap-1">
        {row.warnings.map((w) => (
          <Badge key={w.kind} tone={WARNING_TONE[w.severity]}>
            {w.label}
          </Badge>
        ))}
      </div>
    );

  const phoneLink = (phone: string | null) =>
    phone ? (
      <a href={`tel:${phone.replace(/[^\d+]/g, "")}`} className="hover:text-brand-600 hover:underline">
        {phone}
      </a>
    ) : (
      <span className="text-ink-300">—</span>
    );

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

  return (
    <>
      <PageHeader
        title="Khách hàng"
        subtitle="Phễu chuyển đổi Sẽ → Đang → Đại lý, kèm phân hạng tự động theo doanh thu và số SKUs."
        actions={
          <>
            <a href={exportHref} className="btn-ghost" download>
              Xuất Excel
            </a>
            <Link href="/khach-hang/moi" className="btn-primary">
              Thêm khách hàng
            </Link>
          </>
        }
      />

      <CustomerTabs active="khach-hang" />

      <div className="grid grid-cols-3 gap-3">
        <StatCard label={STAGE_LABEL.LEAD} value={formatNumber(countOf("LEAD"))} hint="Đã tiếp cận" />
        <StatCard label={STAGE_LABEL.PROSPECT} value={formatNumber(countOf("PROSPECT"))} hint="Đã tham dự CT công ty" />
        <StatCard label={STAGE_LABEL.DEALER} value={formatNumber(countOf("DEALER"))} hint="Đã mở code chính thức" tone="good" />
      </div>

      {/* Bộ lọc */}
      <form className="mt-6 flex flex-wrap items-end gap-3" action="/khach-hang">
        <div className="min-w-48 flex-1">
          <label htmlFor="q" className="label-caps mb-1.5 block">
            Tìm kiếm
          </label>
          <input id="q" name="q" defaultValue={query.q} className="input" placeholder="Tên, mã KH, người liên hệ, SĐT, phường…" />
        </div>
        <div>
          <label htmlFor="stage" className="label-caps mb-1.5 block">
            Trạng thái
          </label>
          <select id="stage" name="stage" defaultValue={query.stage} className="input">
            <option value="">Tất cả</option>
            {STAGES.map((stage) => (
              <option key={stage} value={stage}>
                {STAGE_LABEL[stage]}
              </option>
            ))}
          </select>
        </div>
        {options.territories.length > 0 && (
          <div>
            <label htmlFor="kv" className="label-caps mb-1.5 block">
              Khu vực
            </label>
            <select id="kv" name="kv" defaultValue={query.territory} className="input">
              <option value="">Tất cả</option>
              {options.territories.map((t) => (
                <option key={t.id} value={t.id}>
                  {t.name}
                </option>
              ))}
            </select>
          </div>
        )}
        {options.departments.length > 0 && (
          <div>
            <label htmlFor="pb" className="label-caps mb-1.5 block">
              Phòng ban / Team
            </label>
            <select id="pb" name="pb" defaultValue={query.dept} className="input">
              <option value="">Tất cả</option>
              {options.departments.map((d) => (
                <option key={d.id} value={d.id}>
                  {d.name}
                </option>
              ))}
            </select>
          </div>
        )}
        {options.owners.length > 0 && (
          <div>
            <label htmlFor="nv" className="label-caps mb-1.5 block">
              Người phụ trách
            </label>
            <select id="nv" name="nv" defaultValue={query.owner} className="input">
              <option value="">Tất cả</option>
              {options.owners.map((o) => (
                <option key={o.id} value={o.id}>
                  {o.name}
                </option>
              ))}
            </select>
          </div>
        )}
        <div>
          <label htmlFor="tier" className="label-caps mb-1.5 block">
            Hạng doanh thu
          </label>
          <select id="tier" name="tier" defaultValue={query.tier} className="input">
            <option value="">Tất cả</option>
            {["A", "B", "C", "D", "E"].map((tier) => (
              <option key={tier} value={tier}>
                Hạng {tier}
              </option>
            ))}
          </select>
        </div>
        <div>
          <label htmlFor="sp" className="label-caps mb-1.5 block">
            Số SP ứng dụng
          </label>
          <select id="sp" name="sp" defaultValue={query.minSku ? String(query.minSku) : ""} className="input">
            <option value="">Tất cả</option>
            {SKU_THRESHOLDS.slice()
              .reverse()
              .map((n) => (
                <option key={n} value={n}>
                  Trên {n} SP
                </option>
              ))}
          </select>
        </div>
        <div>
          <label htmlFor="cb" className="label-caps mb-1.5 block">
            Cảnh báo
          </label>
          <select id="cb" name="cb" defaultValue={query.alert} className="input">
            <option value="">Tất cả</option>
            {ALERT_FILTERS.map((item) => (
              <option key={item.key} value={item.key}>
                {item.label}
              </option>
            ))}
          </select>
        </div>
        <div>
          <label htmlFor="lead" className="label-caps mb-1.5 block">
            Chuyển đổi (khách tiềm năng)
          </label>
          <select id="lead" name="lead" defaultValue={query.lead} className="input">
            <option value="">Tất cả</option>
            {Object.entries(LEAD_LABEL).map(([value, label]) => (
              <option key={value} value={value}>
                {label}
              </option>
            ))}
          </select>
        </div>
        <div>
          <label htmlFor="sap" className="label-caps mb-1.5 block">
            Xếp hạng theo
          </label>
          <select id="sap" name="sap" defaultValue={query.sort} className="input">
            {SORTS.map((item) => (
              <option key={item.key} value={item.key}>
                {item.label}
              </option>
            ))}
          </select>
        </div>
        <div>
          <label htmlFor="huong" className="label-caps mb-1.5 block">
            Thứ tự
          </label>
          <select id="huong" name="huong" defaultValue={query.dir} className="input">
            <option value="giam">Cao → thấp</option>
            <option value="tang">Thấp → cao</option>
          </select>
        </div>
        <div>
          <label htmlFor="ky" className="label-caps mb-1.5 block">
            Kỳ tính
          </label>
          <select id="ky" name="ky" defaultValue={query.range} className="input">
            {RANGES.map((item) => (
              <option key={item.key} value={item.key}>
                {item.label}
              </option>
            ))}
          </select>
        </div>
        <button type="submit" className="btn-ghost">
          Lọc
        </button>
        {(filtersActive || query.sort !== "hang" || query.dir !== "giam" || query.range !== "thang") && (
          <Link href="/khach-hang" className="pb-2 text-sm text-ink-500 hover:underline">
            Bỏ lọc
          </Link>
        )}
      </form>

      <p className="mt-2 text-xs text-ink-400">
        {formatNumber(all.length)} khách phù hợp · xếp theo “{sortInfo.label}” ({query.dir === "giam" ? "cao → thấp" : "thấp → cao"})
        {` · số liệu theo kỳ: ${range.label}${monthNote}`}
        {capped ? ` · chỉ xét ${formatNumber(MAX_MATCHED)} khách đầu tiên, hãy thu hẹp bộ lọc` : ""}
      </p>

      {/* Điện thoại / máy tính bảng / màn hình nhỏ (< 1280px): mỗi khách một thẻ — bảng nhiều cột buộc phải vuốt ngang. */}
      <div className="mt-4 flex flex-col gap-2 xl:hidden">
        {rows.length === 0 && <div className="card px-4 py-8 text-center text-sm text-ink-400">Không tìm thấy khách hàng phù hợp bộ lọc.</div>}
        {rows.map((row) => (
          <div key={row.id} className="card p-3.5">
            <Link href={`/khach-hang/${row.id}`} className="block active:opacity-70">
              <div className="flex items-start justify-between gap-3">
                <div className="min-w-0">
                  <div className="font-semibold text-ink-700">
                    {row.isKey && (
                      <span className="mr-1 text-gold-500" aria-label="Đại lý Key">
                        ★
                      </span>
                    )}
                    {row.orgName}
                  </div>
                  <div className="mt-0.5 text-[11px] text-ink-400">{row.code}</div>
                </div>
                <div className="flex shrink-0 items-center gap-1.5">
                  <TierBadge tier={row.revenueTier} />
                  <Badge tone={stageTone(row.stage)}>{STAGE_LABEL[row.stage]}</Badge>
                </div>
              </div>
            </Link>

            <dl className="mt-2 grid grid-cols-[auto_1fr] gap-x-3 gap-y-0.5 text-xs">
              <dt className="text-ink-400">Liên hệ</dt>
              <dd className="text-ink-600">{row.contactName ?? "—"}</dd>
              <dt className="text-ink-400">Điện thoại</dt>
              <dd className="text-ink-600">{phoneLink(row.phone)}</dd>
              <dt className="text-ink-400">Phụ trách</dt>
              <dd className="text-ink-600">{row.ownerName ?? "—"}</dd>
              <dt className="text-ink-400">Khu vực</dt>
              <dd className="text-ink-600">{areaLabel(row)}</dd>
            </dl>

            {row.stage === "LEAD" && (
              <div className="mt-1.5 text-xs text-ink-500">
                {LEAD_LABEL[row.leadStatus] ?? row.leadStatus}
                {row.leadNeed ? ` · ${row.leadNeed}` : ""}
              </div>
            )}

            {row.warnings.length > 0 && <div className="mt-2">{warningChips(row)}</div>}

            <div className="mt-2.5 flex items-end justify-between gap-3 border-t border-line pt-2.5 text-xs">
              <div className="text-ink-400">
                {row.lastOrderDate ? `Đơn gần nhất ${formatDate(row.lastOrderDate)} · ${formatVndShort(row.lastOrderValue)}` : "Chưa có đơn hàng"}
              </div>
              {row.outstanding > 0 && (
                <div className="shrink-0 text-right">
                  <div className="text-[10px] uppercase tracking-wide text-ink-400">Công nợ</div>
                  <div className="tnum text-sm font-bold text-gold-500">{formatVndShort(row.outstanding)}</div>
                </div>
              )}
            </div>
            <div className="mt-1.5 text-[11px] text-ink-400">
              {range.label}: DS {formatVndShort(row.salesAvg)}/th · DT {formatVndShort(row.revenueAvg)}/th · {row.orderCount} đơn
            </div>
          </div>
        ))}
      </div>

      {/* Máy tính: bảng đầy đủ theo đúng danh sách cột khách yêu cầu, thêm cột số liệu theo kỳ. */}
      <div className="mt-4 hidden xl:block">
        <TableWrap>
          <thead>
            <tr>
              <th>Tên cơ sở</th>
              <th>Người liên hệ chính · Điện thoại</th>
              <th>Người phụ trách</th>
              <th>Khu vực (Phường - Tỉnh)</th>
              <th className="text-right">{sortLink("gan", "Ngày lên đơn gần nhất")}</th>
              <th className="text-right">{sortLink("no", "Công nợ")}</th>
              <th>Cảnh báo</th>
              <th>Số liệu theo kỳ · {range.label}</th>
            </tr>
          </thead>
          <tbody>
            {rows.length === 0 && (
              <tr>
                <td colSpan={8} className="py-10 text-center text-ink-400">
                  Không tìm thấy khách hàng phù hợp bộ lọc.
                </td>
              </tr>
            )}
            {rows.map((row) => (
              <tr key={row.id} className="align-top">
                <td>
                  <Link href={`/khach-hang/${row.id}`} className="font-medium text-ink-700 hover:text-brand-600">
                    {row.isKey && (
                      <span className="mr-1 text-gold-500" title="Đại lý Key" aria-label="Đại lý Key">
                        ★
                      </span>
                    )}
                    {row.orgName}
                  </Link>
                  <div className="mt-0.5 flex flex-wrap items-center gap-1.5 text-[11px] text-ink-400">
                    <span>{row.code}</span>
                    <Badge tone={stageTone(row.stage)}>{STAGE_LABEL[row.stage]}</Badge>
                    <TierBadge tier={row.revenueTier} />
                  </div>
                  {row.stage === "LEAD" && (
                    <div className="mt-0.5 text-[11px] text-ink-500">
                      {LEAD_LABEL[row.leadStatus] ?? row.leadStatus}
                      {row.leadNeed ? ` · nhu cầu: ${row.leadNeed}` : ""}
                      {row.leadSource ? ` · nguồn: ${row.leadSource}` : ""}
                    </div>
                  )}
                </td>
                <td className="text-ink-600">
                  <div>{row.contactName ?? "—"}</div>
                  {row.contactPosition && <div className="text-[11px] text-ink-400">{row.contactPosition}</div>}
                  <div className="whitespace-nowrap">{phoneLink(row.phone)}</div>
                </td>
                <td className="text-ink-600">{row.ownerName ?? "—"}</td>
                <td className="min-w-36 text-ink-600">
                  <div>{areaLabel(row)}</div>
                  {row.channelName && <div className="text-[11px] text-ink-400">{row.channelName}</div>}
                </td>
                <td className="tnum text-right">
                  {row.lastOrderDate ? (
                    <>
                      <div className="text-ink-700">{formatDate(row.lastOrderDate)}</div>
                      <div className="text-[11px] text-ink-400">{formatVndShort(row.lastOrderValue)}</div>
                    </>
                  ) : (
                    <span className="text-ink-300">—</span>
                  )}
                </td>
                <td className="tnum text-right">
                  {row.outstanding > 0 ? (
                    <>
                      <div className="font-semibold text-gold-500">{formatVndShort(row.outstanding)}</div>
                      {row.overdue > 0 && <div className="text-[11px] font-medium text-red-600">quá hạn {formatVndShort(row.overdue)}</div>}
                    </>
                  ) : (
                    <span className="text-ink-300">—</span>
                  )}
                </td>
                <td>{warningChips(row)}</td>
                <td className="min-w-52 whitespace-nowrap text-[11px] text-ink-500">
                  <div className="grid grid-cols-[auto_1fr] gap-x-3 gap-y-0 leading-[1.05rem]">
                    <span>{sortLink("ds", "DS BQ/tháng")}</span>
                    <span className="tnum text-right text-ink-700">{formatVndShort(row.salesAvg)}</span>
                    <span>{sortLink("dt", "DT BQ/tháng")}</span>
                    <span className="tnum text-right text-ink-700">{formatVndShort(row.revenueAvg)}</span>
                    <span>{sortLink("nobq", "Nợ BQ/tháng")}</span>
                    <span className="tnum text-right text-ink-700">{formatVndShort(row.debtAvg)}</span>
                    <span>{sortLink("don", "Số lần lên đơn")}</span>
                    <span className="tnum text-right text-ink-700">{row.orderCount}</span>
                    <span>{sortLink("sp", "SP ứng dụng")}</span>
                    <span className="tnum text-right text-ink-700">
                      {row.skuCount ?? "—"} {row.skuTier && <TierBadge tier={row.skuTier} />}
                    </span>
                    <span>{sortLink("hang", "DT BQ 12 tháng")}</span>
                    <span className="tnum text-right text-ink-700">{row.avgRevenue != null ? formatVndShort(row.avgRevenue) : "—"}</span>
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </TableWrap>
      </div>

      {totalPages > 1 && (
        <nav className="mt-4 flex items-center justify-center gap-3 text-sm" aria-label="Phân trang">
          {page > 1 ? (
            <Link href={href({ page: 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} · {(page - 1) * PAGE_SIZE + 1}–{Math.min(page * PAGE_SIZE, all.length)} / {formatNumber(all.length)}
          </span>
          {page < totalPages ? (
            <Link href={href({ page: page + 1 })} className="btn-ghost">
              Sau →
            </Link>
          ) : (
            <span className="btn-ghost pointer-events-none opacity-40">Sau →</span>
          )}
        </nav>
      )}

      <p className="mt-3 text-xs text-ink-400">
        Doanh số = đơn đã lập chưa huỷ (kể cả chờ duyệt); doanh thu = đơn đã duyệt. Số “bình quân tháng” chia cho số tháng đã bắt đầu
        trong kỳ. Công nợ bình quân tháng = trung bình công nợ cuối mỗi tháng (tháng đang chạy: tới hôm nay). Hạng doanh thu tính trên
        doanh thu bình quân tháng <b>12 tháng gần nhất</b>; SP ứng dụng đếm trong 3 tháng gần nhất — hai số này do hệ thống tự tính lại
        mỗi đêm. Công nợ là phần chưa thu của các đơn đã duyệt.
      </p>
    </>
  );
}
