import type { Request, Response } from "express";
import { prisma } from "../../config/prisma.js";
import { asyncHandler } from "../../utils/asyncHandler.js";
import { listRenewals } from "../../utils/renewals.js";

export const expiriesReport = asyncHandler(async (req: Request, res: Response) => {
  const { from, to, kind, priority, companyId, days, search, page, pageSize } = req.query;
  const result = await listRenewals({
    from: from ? String(from) : undefined,
    to: to ? String(to) : undefined,
    kind: kind ? String(kind) : undefined,
    priority: priority ? String(priority) : undefined,
    companyId: companyId ? Number(companyId) : undefined,
    days: days ? Number(days) : undefined,
    search: search ? String(search) : undefined,
    page: page ? Number(page) : 1,
    pageSize: pageSize ? Number(pageSize) : 200,
  });
  res.json({ success: true, ...result });
});

export const summaryReport = asyncHandler(async (req: Request, res: Response) => {
  const { from, to, companyId } = req.query;
  const createdWhere: any = {};
  if (from || to) {
    createdWhere.createdAt = {};
    if (from) createdWhere.createdAt.gte = new Date(String(from));
    if (to) createdWhere.createdAt.lte = new Date(String(to));
  }
  if (companyId) createdWhere.companyId = Number(companyId);

  const today = new Date();
  const inDays = (n: number) => new Date(today.getTime() + n * 86400000);
  const scope = companyId ? { companyId: Number(companyId) } : {};
  const companyScope = companyId ? { id: Number(companyId) } : {};

  const [employeesCreated, documentsCreated, expiredDocs, docs30, docs60, byType] = await Promise.all([
    prisma.employee.count({ where: createdWhere }),
    prisma.document.count({ where: createdWhere }),
    prisma.document.count({ where: { ...scope, expiryDate: { lt: today } } }),
    prisma.document.count({ where: { ...scope, expiryDate: { gte: today, lte: inDays(30) } } }),
    prisma.document.count({ where: { ...scope, expiryDate: { gte: today, lte: inDays(60) } } }),
    prisma.document.groupBy({ by: ["documentTypeId"], _count: true, where: createdWhere }),
  ]);

  const [crExpired, cr30, companies] = await Promise.all([
    prisma.company.count({ where: { ...companyScope, crExpiry: { lt: today } } }),
    prisma.company.count({ where: { ...companyScope, crExpiry: { gte: today, lte: inDays(30) } } }),
    prisma.company.count({ where: companyScope }),
  ]);

  const [iqamaExpired, iqama30, passportExpired, passport30, insuranceExpired, insurance30, employees] = await Promise.all([
    prisma.employee.count({ where: { ...scope, iqamaExpiry: { lt: today } } }),
    prisma.employee.count({ where: { ...scope, iqamaExpiry: { gte: today, lte: inDays(30) } } }),
    prisma.employee.count({ where: { ...scope, passportExpiry: { lt: today } } }),
    prisma.employee.count({ where: { ...scope, passportExpiry: { gte: today, lte: inDays(30) } } }),
    prisma.employee.count({ where: { ...scope, insuranceExpiry: { lt: today } } }),
    prisma.employee.count({ where: { ...scope, insuranceExpiry: { gte: today, lte: inDays(30) } } }),
    prisma.employee.count({ where: scope }),
  ]);

  const types = await prisma.documentType.findMany();
  const typeBreakdown = byType.map((t) => {
    const type = types.find((x) => x.id === t.documentTypeId);
    return { documentTypeId: t.documentTypeId, name: type?.nameAr ?? "أخرى", count: t._count };
  });

  res.json({
    success: true,
    data: {
      employeesCreated,
      documentsCreated,
      expiredCount: expiredDocs,
      expiredDocs,
      docs30,
      docs60,
      crExpired,
      cr30,
      iqamaExpired,
      iqama30,
      passportExpired,
      passport30,
      insuranceExpired,
      insurance30,
      companies,
      employees,
      typeBreakdown,
    },
  });
});

export const employeesByStatus = asyncHandler(async (_req: Request, res: Response) => {
  const byStatus = await prisma.employee.groupBy({
    by: ["status"],
    _count: true,
  });
  res.json({ success: true, data: byStatus.map((s) => ({ status: s.status, count: s._count })) });
});