import PDFDocument from "pdfkit";
import type { Response } from "express";
import { PdfHeader } from "./components/PdfHeader.js";

const COLORS = {
  primary: "#0F5132",
  accent: "#198754",
  text: "#212529",
  muted: "#6C757D",
  border: "#DEE2E6",
  rowAlt: "#F8F9FA",
  present: "#15803d",
  absent: "#b91c1c",
  halfDay: "#d97706",
};

const PAGE_MARGIN = 40;

export class AttendancePdf {
  static async generate(
    records: any[],
    res: Response,
    filters?: { startDate?: string; endDate?: string; status?: string }
  ) {
    const doc = new PDFDocument({
      size: "A4",
      margin: PAGE_MARGIN,
      bufferPages: true,
    });

    res.setHeader("Content-Type", "application/pdf");
    res.setHeader("Content-Disposition", `attachment; filename="attendance-report-${Date.now()}.pdf"`);
    res.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
    doc.pipe(res);

    const pageWidth = doc.page.width - PAGE_MARGIN * 2;

    await PdfHeader.draw(doc, pageWidth, PAGE_MARGIN, "ATTENDANCE REPORT");

    this.drawFilterLine(doc, pageWidth, filters);
    this.drawTable(doc, records, pageWidth);
    this.drawSummary(doc, records, pageWidth);
    this.drawFooter(doc, pageWidth);

    doc.end();
  }

  private static drawFilterLine(
    doc: PDFKit.PDFDocument,
    pageWidth: number,
    filters?: { startDate?: string; endDate?: string; status?: string }
  ) {
    const parts: string[] = [];
    if (filters?.startDate) parts.push(`From: ${filters.startDate}`);
    if (filters?.endDate) parts.push(`To: ${filters.endDate}`);
    if (filters?.status) parts.push(`Status: ${filters.status}`);

    if (parts.length) {
      doc
        .font("Helvetica")
        .fontSize(8.5)
        .fillColor(COLORS.muted)
        .text(parts.join("   |   "), PAGE_MARGIN, doc.y, {
          width: pageWidth,
          align: "right",
        });
      doc.y += 4;
    }

    doc.y += 10;
  }

  private static drawTable(doc: PDFKit.PDFDocument, records: any[], pageWidth: number) {
    const cols = {
      no: { x: PAGE_MARGIN, width: pageWidth * 0.06 },
      date: { x: PAGE_MARGIN + pageWidth * 0.06, width: pageWidth * 0.14 },
      code: { x: PAGE_MARGIN + pageWidth * 0.2, width: pageWidth * 0.12 },
      name: { x: PAGE_MARGIN + pageWidth * 0.32, width: pageWidth * 0.24 },
      status: { x: PAGE_MARGIN + pageWidth * 0.56, width: pageWidth * 0.16 },
      remarks: { x: PAGE_MARGIN + pageWidth * 0.72, width: pageWidth * 0.28 },
    };

    const rowHeight = 24;
    const headerH = 24;

    const drawTableHeader = () => {
      const y = doc.y;
      doc
        .font("Helvetica-Bold")
        .fontSize(8.5)
        .fillColor(COLORS.primary)
        .text("#", cols.no.x, y + 6, { width: cols.no.width, align: "center" })
        .text("DATE", cols.date.x, y + 6, { width: cols.date.width })
        .text("CODE", cols.code.x, y + 6, { width: cols.code.width })
        .text("EMPLOYEE", cols.name.x, y + 6, { width: cols.name.width })
        .text("STATUS", cols.status.x, y + 6, { width: cols.status.width })
        .text("REMARKS", cols.remarks.x, y + 6, { width: cols.remarks.width });

      doc.y = y + headerH;
      doc
        .moveTo(PAGE_MARGIN, doc.y)
        .lineTo(PAGE_MARGIN + pageWidth, doc.y)
        .strokeColor(COLORS.primary)
        .lineWidth(1)
        .stroke();

      doc.y += 4;
    };

    const ensureSpace = (needed: number) => {
      const bottomLimit = doc.page.height - PAGE_MARGIN - 60;
      if (doc.y + needed > bottomLimit) {
        doc.addPage();
        doc.y = PAGE_MARGIN;
        drawTableHeader();
      }
    };

    drawTableHeader();

    records.forEach((rec, i) => {
      ensureSpace(rowHeight);
      const y = doc.y;

      if (i % 2 === 1) {
        doc.rect(PAGE_MARGIN, y, pageWidth, rowHeight).fill(COLORS.rowAlt);
      }

      doc
        .font("Helvetica-Bold")
        .fontSize(8.5)
        .fillColor(COLORS.muted)
        .text(`${i + 1}`, cols.no.x, y + 5, { width: cols.no.width, align: "center" });

      doc.font("Helvetica").fontSize(8.5).fillColor(COLORS.text);
      doc.text(rec.date || "-", cols.date.x, y + 5, { width: cols.date.width });
      doc.text(rec.employeeCode || "-", cols.code.x, y + 5, { width: cols.code.width });
      doc.text(rec.employeeName || "-", cols.name.x, y + 5, { width: cols.name.width - 4, ellipsis: true });

      let statusColor = COLORS.text;
      if (rec.status === "PRESENT") statusColor = COLORS.present;
      else if (rec.status === "ABSENT") statusColor = COLORS.absent;
      else if (rec.status === "HALF_DAY") statusColor = COLORS.halfDay;

      doc.font("Helvetica-Bold").fontSize(8.5).fillColor(statusColor);
      doc.text(rec.status || "-", cols.status.x, y + 5, { width: cols.status.width });

      doc.font("Helvetica").fontSize(8.5).fillColor(COLORS.text);
      doc.text(rec.remarks || "-", cols.remarks.x, y + 5, { width: cols.remarks.width - 4, ellipsis: true });

      doc.y = y + rowHeight;
    });

    doc
      .moveTo(PAGE_MARGIN, doc.y)
      .lineTo(PAGE_MARGIN + pageWidth, doc.y)
      .strokeColor(COLORS.border)
      .lineWidth(0.5)
      .stroke();

    doc.y += 14;
  }

  private static drawSummary(doc: PDFKit.PDFDocument, records: any[], pageWidth: number) {
    let present = 0, absent = 0, halfDay = 0;
    records.forEach((r) => {
      if (r.status === "PRESENT") present++;
      else if (r.status === "ABSENT") absent++;
      else if (r.status === "HALF_DAY") halfDay++;
    });

    const total = records.length;
    const rate = total > 0 ? Math.round(((present + halfDay * 0.5) / total) * 100) : 0;

    doc.font("Helvetica-Bold").fontSize(9.5).fillColor(COLORS.primary);
    doc.text(`TOTAL RECORDS: ${total}   |   PRESENT: ${present}   |   ABSENT: ${absent}   |   HALF DAY: ${halfDay}   |   ATTENDANCE RATE: ${rate}%`, PAGE_MARGIN, doc.y, {
      width: pageWidth,
      align: "center",
    });
  }

  private static drawFooter(doc: PDFKit.PDFDocument, pageWidth: number) {
    const y = doc.page.height - PAGE_MARGIN - 20;
    doc
      .font("Helvetica-Oblique")
      .fontSize(8.5)
      .fillColor(COLORS.muted)
      .text("This is a computer-generated attendance report.", PAGE_MARGIN, y, {
        width: pageWidth,
        align: "center",
      });
  }
}
