/**
 * "Nhân viên chuyên môn" (phụ trách đào tạo / chuyển giao) — một định nghĩa dùng chung cho danh sách và hồ sơ nhân viên.
 *
 * Là chuyên môn khi: chức vụ có chữ "chuyên môn" (Nhân viên chuyên môn, Quản lý chuyên môn khu vực, Trưởng phòng chuyên môn…),
 * HOẶC thuộc một phòng ban có tên chứa "chuyên môn" (kể cả các team con của phòng đó).
 * Có phụ trách vài lớp/chuyên đề KHÔNG đủ để thành chuyên môn: nhân viên kinh doanh vẫn tự mở chuyên đề cho đại lý của mình.
 */
import { and, eq, ilike, or, sql, type SQL } from "drizzle-orm";
import { db } from "@/db";
import { departments } from "@/db/schema";
import { departmentSubtree } from "./rbac";

const TITLE_PATTERNS = ["%chuyên môn%", "%chuyen mon%"];

/** Phòng ban chuyên môn (tên chứa "chuyên môn") cùng toàn bộ nhánh con. */
export async function specialistDepartmentIds(tenantId: string): Promise<string[]> {
  const roots = await db
    .select({ id: departments.id })
    .from(departments)
    .where(and(eq(departments.tenantId, tenantId), or(...TITLE_PATTERNS.map((p) => ilike(departments.name, p)))));
  return departmentSubtree(
    tenantId,
    roots.map((r) => r.id),
  );
}

/**
 * Điều kiện SQL "là chuyên môn" cho truy vấn có bảng `users`.
 * `coalesce`: chức vụ để trống cho `null`, mà `not (null or false)` cũng là null → nhân viên biến mất khỏi tab đối lập.
 */
export function specialistCondition(departmentIds: string[]): SQL {
  const byDepartment = departmentIds.length > 0 ? sql` or users.department_id in (${sql.join(departmentIds.map((id) => sql`${id}`), sql`, `)})` : sql``;
  return sql`(coalesce(users.job_title ilike ${TITLE_PATTERNS[0]} or users.job_title ilike ${TITLE_PATTERNS[1]}, false)${byDepartment})`;
}

/** Cùng định nghĩa như `specialistCondition` nhưng cho một dòng đã có sẵn trong bộ nhớ. */
export function isSpecialist(row: { jobTitle: string | null; departmentId: string | null }, departmentIds: string[]): boolean {
  const title = (row.jobTitle ?? "").toLowerCase();
  if (title.includes("chuyên môn") || title.includes("chuyen mon")) return true;
  return !!row.departmentId && departmentIds.includes(row.departmentId);
}
