/**
 * Bộ chọn phạm vi cho báo cáo: toàn bộ phạm vi của mình, hoặc thu hẹp vào một khu vực, một phòng ban/team,
 * hay một nhân viên (yêu cầu: "hiển thị theo công ty, khu vực, phòng, team, nhân viên").
 *
 * Giá trị nằm trên URL dạng `pv=dept:<uuid>`. Bộ chọn chỉ THU HẸP phạm vi quyền đang có — điều kiện được AND
 * thêm vào phạm vi gốc ở `reports.ts`, nên sửa tay URL sang một khu vực ngoài quyền chỉ cho ra kết quả rỗng.
 */
import "server-only";
import { and, asc, eq, inArray } from "drizzle-orm";
import { db } from "@/db";
import { departments, territories, users } from "@/db/schema";
import type { ReportFocus, SessionUser } from "./auth";
import { visibleDepartmentIds, visibleTerritoryIds, visibleUserIds } from "./rbac";

const FOCUS_RE = /^(user|dept|terr):([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/;

export function parseFocus(raw: string | undefined): ReportFocus | undefined {
  const match = raw ? FOCUS_RE.exec(raw) : null;
  return match ? { type: match[1] as ReportFocus["type"], id: match[2] } : undefined;
}

/** NVKD chỉ thấy dữ liệu của chính mình nên không có gì để thu hẹp. */
export function withFocus(session: SessionUser, raw: string | undefined): SessionUser {
  if (session.role === "SALES") return session;
  const focus = parseFocus(raw);
  return focus ? { ...session, focus } : session;
}

export type FocusOptions = {
  departments: { id: string; name: string }[];
  territories: { id: string; name: string }[];
  users: { id: string; name: string }[];
};

export async function loadFocusOptions(session: SessionUser): Promise<FocusOptions | null> {
  if (session.role === "SALES") return null;

  const [deptIds, territoryIds, userIds] = await Promise.all([
    visibleDepartmentIds(session),
    visibleTerritoryIds(session),
    visibleUserIds(session),
  ]);

  const [deptRows, territoryRows, userRows] = await Promise.all([
    db
      .select({ id: departments.id, name: departments.name })
      .from(departments)
      .where(
        and(
          eq(departments.tenantId, session.tenantId),
          eq(departments.isActive, true),
          deptIds ? inArray(departments.id, deptIds.length > 0 ? deptIds : ["00000000-0000-0000-0000-000000000000"]) : undefined,
        ),
      )
      .orderBy(asc(departments.sortOrder), asc(departments.code)),
    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"]),
          territoryIds ? inArray(territories.id, territoryIds.length > 0 ? territoryIds : ["00000000-0000-0000-0000-000000000000"]) : undefined,
        ),
      )
      .orderBy(asc(territories.code)),
    db
      .select({ id: users.id, name: users.fullName })
      .from(users)
      .where(
        and(
          eq(users.tenantId, session.tenantId),
          eq(users.isActive, true),
          userIds ? inArray(users.id, userIds.length > 0 ? userIds : ["00000000-0000-0000-0000-000000000000"]) : undefined,
        ),
      )
      .orderBy(asc(users.fullName)),
  ]);

  return { departments: deptRows, territories: territoryRows, users: userRows };
}
