import { and, desc, eq, ilike, or, sql, type SQL } from "drizzle-orm";
import { db } from "@/db";
import { companyDocuments, users } from "@/db/schema";

export type CompanyDocumentRow = {
  id: string;
  title: string;
  description: string | null;
  category: string;
  fileName: string;
  mimeType: string;
  fileSize: number;
  filePath: string;
  uploadedAt: Date;
  uploadedByName: string | null;
};

/** Bỏ ký tự đặc biệt của LIKE để ô tìm kiếm gõ `%` hay `_` không thành ký tự đại diện. */
function likePattern(text: string): string {
  return `%${text.replace(/[\\%_]/g, (ch) => `\\${ch}`)}%`;
}

/**
 * Văn bản công ty — toàn công ty xem được, không phân biệt vai trò hay phòng ban.
 * Lọc theo loại và tìm theo tên / trích yếu / tên tệp; phân trang để danh sách dài không nặng trang.
 */
export async function listCompanyDocuments(
  tenantId: string,
  options: { q?: string; category?: string; page?: number; pageSize?: number } = {},
): Promise<{ rows: CompanyDocumentRow[]; total: number; page: number; totalPages: number; byCategory: Record<string, number> }> {
  const pageSize = options.pageSize ?? 30;
  const search: SQL[] = [eq(companyDocuments.tenantId, tenantId)];
  if (options.q) {
    const term = likePattern(options.q);
    search.push(or(ilike(companyDocuments.title, term), ilike(companyDocuments.description, term), ilike(companyDocuments.fileName, term))!);
  }

  // Số văn bản theo từng loại (đã áp dụng ô tìm kiếm) để hiện trên các nút lọc.
  const categoryRows = await db
    .select({ category: companyDocuments.category, n: sql<number>`count(*)::int` })
    .from(companyDocuments)
    .where(and(...search))
    .groupBy(companyDocuments.category);
  const byCategory: Record<string, number> = {};
  for (const row of categoryRows) byCategory[row.category] = Number(row.n);

  const filters = options.category ? [...search, eq(companyDocuments.category, options.category)] : search;
  const total = options.category ? (byCategory[options.category] ?? 0) : Object.values(byCategory).reduce((sum, n) => sum + n, 0);
  const totalPages = Math.max(1, Math.ceil(total / pageSize));
  const page = Math.min(Math.max(1, options.page ?? 1), totalPages);

  const rows = await db
    .select({
      id: companyDocuments.id,
      title: companyDocuments.title,
      description: companyDocuments.description,
      category: companyDocuments.category,
      fileName: companyDocuments.fileName,
      mimeType: companyDocuments.mimeType,
      fileSize: companyDocuments.fileSize,
      filePath: companyDocuments.filePath,
      uploadedAt: companyDocuments.uploadedAt,
      uploadedByName: users.fullName,
    })
    .from(companyDocuments)
    .leftJoin(users, eq(companyDocuments.uploadedBy, users.id))
    .where(and(...filters))
    .orderBy(desc(companyDocuments.uploadedAt))
    .limit(pageSize)
    .offset((page - 1) * pageSize);

  return { rows, total, page, totalPages, byCategory };
}

/** Vài văn bản mới nhất cho trang chủ. */
export async function latestCompanyDocuments(tenantId: string, count = 3): Promise<CompanyDocumentRow[]> {
  return (await listCompanyDocuments(tenantId, { pageSize: count })).rows;
}
