import { prisma } from "../config/prisma.js";
import { computePriorityForDate, summarisePriority, type ExpirySummary } from "./priority.js";

export interface RenewalItem {
  id: string;
  kind: "company" | "employee" | "document";
  entityId: number;
  companyId: number | null;
  entityName: string;
  companyName?: string;
  title: string;
  expiryDate: Date;
  priority: ExpirySummary;
}

export interface RenewalFilters {
  search?: string;
  kind?: string;
  companyId?: number;
  priority?: string;
  days?: number;
  from?: string;
  to?: string;
  page?: number;
  pageSize?: number;
}

/**
 * قائمة التجديدات الموحدة: سجلات الشركات (سجل تجاري/رخصة) + المستندات +
 * الإقامات والجوازات والتأمين للعمالة، مع فلاتر وترتيب حسب الأولوية.
 */
export async function listRenewals(filters: RenewalFilters) {
  let items: RenewalItem[] = [];
  const companyId = filters.companyId;

  // 1) الشركات: السجل التجاري (الرخص تُدار كوثائق مستقلة من قائمة المستندات)
  const companies = await prisma.company.findMany({
    where: companyId
      ? { id: companyId }
      : { crExpiry: { not: null } },
    select: { id: true, name: true, crExpiry: true, crNo: true },
  });
  const companiesMap = new Map(companies.map((c) => [c.id, c.name]));
  for (const c of companies) {
    if (!c.crExpiry) continue;
    items.push({
      id: `company-${c.id}-cr`,
      kind: "company",
      entityId: c.id,
      companyId: c.id,
      entityName: c.name,
      companyName: c.name,
      title: "السجل التجاري",
      expiryDate: c.crExpiry,
      priority: summarisePriority(await computePriorityForDate(c.crExpiry)),
    });
  }

  // 2) العمالة: الإقامة + الجواز + التأمين الطبي
  const employees = await prisma.employee.findMany({
    where: companyId ? { companyId } : {},
    select: { id: true, fullName: true, companyId: true, iqamaExpiry: true, passportExpiry: true, insuranceExpiry: true },
  });
  const employeesMap = new Map(employees.map((e) => [e.id, e.fullName]));
  for (const e of employees) {
    const companyName = companiesMap.get(e.companyId) ?? "";
    for (const [key, title] of [
      ["iqamaExpiry", "إقامة"],
      ["passportExpiry", "جواز سفر"],
      ["insuranceExpiry", "تأمين طبي"],
    ] as const) {
      const date = (e as any)[key];
      if (!date) continue;
      items.push({
        id: `employee-${e.id}-${key}`,
        kind: "employee",
        entityId: e.id,
        companyId: e.companyId,
        entityName: e.fullName,
        companyName,
        title,
        expiryDate: date,
        priority: summarisePriority(await computePriorityForDate(date)),
      });
    }
  }

  // 3) المستندات الحكومية/الداخلية
  const documents = await prisma.document.findMany({
    where: companyId ? { companyId } : {},
    select: { id: true, companyId: true, employeeId: true, title: true, expiryDate: true, documentType: { select: { nameAr: true } } },
  });
  for (const d of documents) {
    items.push({
      id: `document-${d.id}`,
      kind: "document",
      entityId: d.id,
      companyId: d.companyId,
      entityName: employeesMap.get(d.employeeId ?? 0) ?? companiesMap.get(d.companyId) ?? "",
      companyName: companiesMap.get(d.companyId) ?? "",
      title: `${d.documentType?.nameAr ?? ""} — ${d.title}`,
      expiryDate: d.expiryDate,
      priority: summarisePriority(await computePriorityForDate(d.expiryDate)),
    });
  }

  // فلاتر نصية (بحث، نوع)
  if (filters.search) {
    const q = String(filters.search).trim();
    if (q) items = items.filter((i) => i.entityName.includes(q) || i.title.includes(q) || (i.companyName ?? "").includes(q));
  }
  if (filters.kind && filters.kind !== "all") {
    items = items.filter((i) => i.kind === filters.kind);
  }

  // إجماليات الأولويات (لكل الأصناف بعد فلاتر البحث/النوع/الشركة)
  const totals = { expired: 0, critical: 0, high: 0, medium: 0, low: 0 };
  for (const it of items) {
    const s = it.priority.status;
    if (s in totals) totals[s]++;
  }

  // فلتر الأولوية
  if (filters.priority && filters.priority !== "all") {
    items = items.filter((i) => i.priority.status === filters.priority);
  }

  // فلتر الفترة الزمنية
  const now = new Date();
  if (filters.days) {
    const horizon = new Date(now.getTime() + Number(filters.days) * 86400000);
    items = items.filter((i) => i.expiryDate >= now && i.expiryDate <= horizon);
  }
  if (filters.from) {
    const from = new Date(String(filters.from));
    items = items.filter((i) => i.expiryDate >= from);
  }
  if (filters.to) {
    const to = new Date(String(filters.to));
    items = items.filter((i) => i.expiryDate <= to);
  }

  // ترتيب: حسب الأولوية ثم تاريخ الانتهاء
  const order: Record<string, number> = { expired: 0, critical: 1, high: 2, medium: 3, low: 4 };
  items.sort((a, b) => {
    const diff = (order[a.priority.status] ?? 5) - (order[b.priority.status] ?? 5);
    if (diff !== 0) return diff;
    return a.expiryDate.getTime() - b.expiryDate.getTime();
  });

  const pg = Math.max(1, Number(filters.page) || 1);
  const size = Math.min(200, Math.max(1, Number(filters.pageSize) || 50));
  const start = (pg - 1) * size;
  const paged = items.slice(start, start + size);

  return {
    data: paged,
    totals,
    kinds: {
      company: items.filter((i) => i.kind === "company").length,
      employee: items.filter((i) => i.kind === "employee").length,
      document: items.filter((i) => i.kind === "document").length,
    },
    pagination: { page: pg, pageSize: size, total: items.length, pages: Math.ceil(items.length / size) },
  };
}
