import { ActionForm } from "@/components/action-form";
import Link from "next/link";
import { and, asc, eq, inArray } from "drizzle-orm";
import { requireSession } from "@/lib/auth";
import { canEditCatalog, scopeFilter, visibleTerritoryIds, visibleUserIds } from "@/lib/rbac";
import { db } from "@/db";
import { targets, users, territories, customers } from "@/db/schema";
import { monthKey, today, isRealMonth } from "@/lib/period";
import { formatVnd, formatPeriod, formatNumber } from "@/lib/format";
import { PageHeader, TableWrap, EmptyState, SectionTitle } from "@/components/ui";
import { TargetForm } from "./target-form";
import { deleteTargetAction, recomputeAction } from "./actions";

export const dynamic = "force-dynamic";

export default async function TargetsPage({
  searchParams,
}: {
  searchParams: Promise<{ ky?: string }>;
}) {
  const session = await requireSession();
  const params = await searchParams;
  const periodKey = isRealMonth(params.ky) ? params.ky : monthKey(today());

  if (!canEditCatalog(session)) {
    return (
      <>
        <PageHeader title="Chỉ tiêu kế hoạch" />
        <EmptyState
          message="Bạn không có quyền giao chỉ tiêu."
          hint="Chức năng này dành cho Ban giám đốc, Giám đốc khu vực và Quản lý (giao chỉ tiêu cho cấp dưới)."
        />
      </>
    );
  }

  // Cha giao cho con: quản lý chỉ thấy nhân viên, khu vực, đại lý thuộc nhánh mình (và không tự giao cho mình).
  const [allowedUsers, allowedTerritories, customerScope] = await Promise.all([
    visibleUserIds(session),
    visibleTerritoryIds(session),
    scopeFilter(session, { tenantId: customers.tenantId, ownerId: customers.ownerId, territoryId: customers.territoryId }),
  ]);
  const NONE = ["00000000-0000-0000-0000-000000000000"];

  const [staff, territoryRows, dealerRows, targetRows] = await Promise.all([
    db
      .select({ id: users.id, name: users.fullName })
      .from(users)
      .where(
        and(
          eq(users.tenantId, session.tenantId),
          eq(users.isActive, true),
          eq(users.role, "SALES"),
          allowedUsers ? inArray(users.id, allowedUsers.length > 0 ? allowedUsers : NONE) : undefined,
        ),
      )
      .orderBy(asc(users.fullName)),
    db
      .select({ id: territories.id, name: territories.name })
      .from(territories)
      .where(
        and(
          eq(territories.tenantId, session.tenantId),
          eq(territories.isActive, true),
          inArray(territories.level, ["REGION", "PROVINCE"]),
          allowedTerritories ? inArray(territories.id, allowedTerritories.length > 0 ? allowedTerritories : NONE) : undefined,
        ),
      )
      .orderBy(asc(territories.code)),
    db
      .select({ id: customers.id, name: customers.orgName, code: customers.code })
      .from(customers)
      .where(
        and(
          eq(customers.tenantId, session.tenantId),
          eq(customers.stage, "DEALER"),
          eq(customers.isActive, true),
          customerScope,
        ),
      )
      .orderBy(asc(customers.orgName)),
    db
      .select()
      .from(targets)
      .where(and(eq(targets.tenantId, session.tenantId), eq(targets.periodKey, periodKey)))
      .orderBy(asc(targets.scopeType)),
  ]);

  const dealerOptions = dealerRows.map((d) => ({ id: d.id, name: `${d.name} · ${d.code}` }));

  const nameById = new Map<string, string>([
    ...staff.map((s) => [s.id, s.name] as [string, string]),
    ...territoryRows.map((t) => [t.id, t.name] as [string, string]),
    ...dealerRows.map((d) => [d.id, `${d.name} · ${d.code}`] as [string, string]),
  ]);

  const totalAssigned = targetRows
    .filter((row) => row.scopeType === "USER")
    .reduce((sum, row) => sum + Number(row.revenueTarget), 0);

  const companyTarget = targetRows.find((row) => row.scopeType === "COMPANY");

  return (
    <>
      <PageHeader
        title="Chỉ tiêu kế hoạch"
        subtitle={`${formatPeriod(periodKey)} — mẫu số để tính % hoàn thành ở báo cáo và KPI.`}
        actions={
          <>
            <form action="/danh-muc/chi-tieu" className="flex items-end gap-2">
              <input type="month" name="ky" defaultValue={periodKey} className="input" aria-label="Chọn kỳ" />
              <button type="submit" className="btn-ghost">
                Xem
              </button>
            </form>
            <Link href="/danh-muc" className="btn-ghost">
              ← Danh mục
            </Link>
          </>
        }
      />

      <TargetForm
        periodKey={periodKey}
        staff={staff}
        territories={territoryRows}
        dealers={dealerOptions}
        canAssignCompany={session.role === "DIRECTOR"}
      />

      {/* Đối chiếu tổng giao cho nhân viên với chỉ tiêu công ty */}
      {companyTarget && (
        <div className="card mt-4 flex flex-wrap items-center justify-between gap-3 p-4">
          <div>
            <div className="label-caps">Chỉ tiêu toàn công ty</div>
            <div className="tnum text-lg font-bold text-ink-700">
              {formatVnd(Number(companyTarget.revenueTarget))}
            </div>
          </div>
          <div>
            <div className="label-caps">Đã giao cho nhân viên</div>
            <div className="tnum text-lg font-bold text-ink-700">{formatVnd(totalAssigned)}</div>
          </div>
          <div>
            <div className="label-caps">Chênh lệch</div>
            <div
              className={`tnum text-lg font-bold ${
                totalAssigned >= Number(companyTarget.revenueTarget) ? "text-brand-600" : "text-gold-500"
              }`}
            >
              {formatVnd(totalAssigned - Number(companyTarget.revenueTarget))}
            </div>
          </div>
        </div>
      )}

      <div className="mt-6">
        <SectionTitle hint={`${targetRows.length} chỉ tiêu đã giao`}>
          Chỉ tiêu {formatPeriod(periodKey)}
        </SectionTitle>
        {targetRows.length === 0 ? (
          <EmptyState
            message="Chưa giao chỉ tiêu nào cho kỳ này."
            hint="Không có chỉ tiêu thì cột % hoàn thành ở báo cáo và KPI sẽ để trống."
          />
        ) : (
          <TableWrap>
            <thead>
              <tr>
                <th>Phạm vi</th>
                <th>Đối tượng</th>
                <th className="text-right">Doanh thu</th>
                <th className="text-right">Số đơn</th>
                <th className="text-right">KH mở mới</th>
                <th />
              </tr>
            </thead>
            <tbody>
              {targetRows.map((row) => (
                <tr key={row.id}>
                  <td className="text-ink-500">
                    {
                      {
                        COMPANY: "Toàn công ty",
                        DEPARTMENT: "Phòng ban",
                        USER: "Nhân viên",
                        TERRITORY: "Khu vực",
                        CUSTOMER: "Khách hàng",
                      }[row.scopeType]
                    }
                  </td>
                  <td className="font-medium text-ink-700">
                    {row.scopeId ? (nameById.get(row.scopeId) ?? "—") : "Toàn công ty"}
                  </td>
                  <td className="tnum text-right font-semibold">{formatVnd(Number(row.revenueTarget))}</td>
                  <td className="tnum text-right text-ink-500">{formatNumber(row.orderTarget)}</td>
                  <td className="tnum text-right text-ink-500">{formatNumber(row.newCustomerTarget)}</td>
                  <td className="text-right">
                    <ActionForm action={deleteTargetAction} success="Đã xoá chỉ tiêu." confirm="Xoá chỉ tiêu này?">
                      <input type="hidden" name="id" value={row.id} />
                      <button type="submit" className="btn-ghost px-2 py-1 text-xs text-red-600">
                        Xoá
                      </button>
                    </ActionForm>
                  </td>
                </tr>
              ))}
            </tbody>
          </TableWrap>
        )}
      </div>

      {/* Tính lại số liệu */}
      <div className="card mt-6 flex flex-wrap items-center justify-between gap-4 p-4">
        <div>
          <h2 className="text-base font-bold text-ink-700">Tính lại số liệu ngay</h2>
          <p className="mt-1 max-w-lg text-sm text-ink-500">
            Phân hạng đại lý, KPI, cảnh báo và dự báo bình thường được tính trong job hằng đêm. Bấm nút
            này sau khi vừa nhập dữ liệu từ Excel hoặc vừa sửa chỉ tiêu, nếu cần thấy số liệu mới ngay.
          </p>
        </div>
        <ActionForm action={recomputeAction} success="Đã tính lại số liệu.">
          <input type="hidden" name="periodKey" value={periodKey} />
          <button type="submit" className="btn-primary">
            Tính lại {formatPeriod(periodKey)}
          </button>
        </ActionForm>
      </div>
    </>
  );
}
