import { Body, Controller, Get, Post, Query, Res } from "@nestjs/common";
import { Response } from "express";
import * as PDFDocument from "pdfkit";
import { ReportFilters, ReportsService } from "./reports.service";

@Controller("reports")
export class ReportsController {
  constructor(private readonly reportsService: ReportsService) {}

  @Get("transactions")
  getTransactions(
    @Query("warehouses") warehouses?: string,
    @Query("type") type?: string,
    @Query("fromDate") fromDate?: string,
    @Query("toDate") toDate?: string,
  ) {
    const filters: ReportFilters = {
      warehouseNames: warehouses ? warehouses.split(",").map((w) => w.trim()).filter(Boolean) : undefined,
      type: (type as ReportFilters["type"]) ?? "all",
      fromDate,
      toDate,
    };
    return this.reportsService.getTransactionReport(filters);
  }

  @Get("summary")
  getSummary(
    @Query("warehouses") warehouses?: string,
    @Query("type") type?: string,
    @Query("fromDate") fromDate?: string,
    @Query("toDate") toDate?: string,
  ) {
    const filters: ReportFilters = {
      warehouseNames: warehouses ? warehouses.split(",").map((w) => w.trim()).filter(Boolean) : undefined,
      type: (type as ReportFilters["type"]) ?? "all",
      fromDate,
      toDate,
    };
    return this.reportsService.getSummaryByWarehouse(filters);
  }

  @Post("export-pdf")
  async exportPdf(
    @Body()
    body: {
      warehouses?: string[];
      type?: string;
      fromDate?: string;
      toDate?: string;
      title?: string;
    },
    @Res() res: Response,
  ) {
    const filters: ReportFilters = {
      warehouseNames: body.warehouses?.length ? body.warehouses : undefined,
      type: (body.type as ReportFilters["type"]) ?? "all",
      fromDate: body.fromDate,
      toDate: body.toDate,
    };

    const rows = await this.reportsService.getTransactionReport(filters);
    const summary = await this.reportsService.getSummaryByWarehouse(filters);

    const today = new Date().toLocaleDateString("en-AE", {
      day: "2-digit", month: "long", year: "numeric",
    });

    const buffer = await new Promise<Buffer>((resolve, reject) => {
      const doc = new PDFDocument({ margin: 50, size: "A4" });
      const chunks: Buffer[] = [];
      doc.on("data", (c: Buffer) => chunks.push(c));
      doc.on("end", () => resolve(Buffer.concat(chunks)));
      doc.on("error", reject);

      // ── Header ──────────────────────────────────────────────────────────
      doc.fontSize(16).font("Helvetica-Bold")
        .text("ROYAL HORIZON GENERAL TRADING LLC", { align: "center" });
      doc.fontSize(12).font("Helvetica")
        .text(body.title ?? "Stock Movement Report", { align: "center" });
      doc.fontSize(9).fillColor("#79839a")
        .text(`Generated: ${today}`, { align: "center" });

      // Filter summary
      const filterParts: string[] = [];
      if (body.fromDate) filterParts.push(`From: ${body.fromDate}`);
      if (body.toDate) filterParts.push(`To: ${body.toDate}`);
      if (body.warehouses?.length) filterParts.push(`Warehouses: ${body.warehouses.join(", ")}`);
      if (body.type && body.type !== "all") filterParts.push(`Type: ${body.type}`);
      if (filterParts.length) {
        doc.fontSize(8).fillColor("#79839a").text(filterParts.join("  ·  "), { align: "center" });
      }

      doc.moveDown(0.5);
      doc.moveTo(50, doc.y).lineTo(545, doc.y).strokeColor("#dfe5f0").stroke();
      doc.moveDown(0.5);

      // ── Summary by warehouse ─────────────────────────────────────────────
      doc.fillColor("#1f2740").fontSize(10).font("Helvetica-Bold").text("Summary by Warehouse");
      doc.moveDown(0.3);

      const sc = { wh: 50, in: 260, out: 360, net: 460 };
      doc.fillColor("#79839a").fontSize(8).font("Helvetica-Bold");
      doc.text("WAREHOUSE", sc.wh, doc.y);
      doc.text("TOTAL IN (MT)", sc.in, doc.y - 10);
      doc.text("TOTAL OUT (MT)", sc.out, doc.y - 10);
      doc.text("NET (MT)", sc.net, doc.y - 10);
      doc.moveDown(0.2);
      doc.moveTo(50, doc.y).lineTo(545, doc.y).strokeColor("#dfe5f0").stroke();
      doc.moveDown(0.2);

      for (const s of summary) {
        if (doc.y > 720) { doc.addPage(); }
        doc.fillColor("#1f2740").fontSize(9).font("Helvetica");
        doc.text(s.warehouse, sc.wh, doc.y, { width: 200 });
        doc.text(s.totalInbound.toFixed(2), sc.in, doc.y - 11);
        doc.text(s.totalOutbound.toFixed(2), sc.out, doc.y - 11);
        doc.fillColor(s.net >= 0 ? "#3b5bdb" : "#d64545")
          .text(s.net.toFixed(2), sc.net, doc.y - 11);
        doc.moveDown(0.1);
        doc.moveTo(50, doc.y).lineTo(545, doc.y).strokeColor("#f0f4fa").stroke();
        doc.moveDown(0.1);
      }

      doc.moveDown(0.8);
      doc.moveTo(50, doc.y).lineTo(545, doc.y).strokeColor("#dfe5f0").stroke();
      doc.moveDown(0.5);

      // ── Transaction detail ───────────────────────────────────────────────
      doc.fillColor("#1f2740").fontSize(10).font("Helvetica-Bold").text("Transaction Detail");
      doc.moveDown(0.3);

      const tc = { date: 50, type: 120, wh: 175, item: 295, batch: 390, mt: 490 };
      doc.fillColor("#79839a").fontSize(8).font("Helvetica-Bold");
      doc.text("DATE", tc.date, doc.y);
      doc.text("TYPE", tc.type, doc.y - 10);
      doc.text("WAREHOUSE", tc.wh, doc.y - 10);
      doc.text("ITEM", tc.item, doc.y - 10);
      doc.text("BATCH", tc.batch, doc.y - 10);
      doc.text("MT", tc.mt, doc.y - 10);
      doc.moveDown(0.2);
      doc.moveTo(50, doc.y).lineTo(545, doc.y).strokeColor("#dfe5f0").stroke();
      doc.moveDown(0.2);

      for (const row of rows) {
        if (doc.y > 720) { doc.addPage(); }
        const isIn = row.type === "inbound";
        doc.fillColor("#1f2740").fontSize(8).font("Helvetica");
        doc.text(row.date, tc.date, doc.y, { width: 65 });
        doc.fillColor(isIn ? "#3b5bdb" : "#c97a18")
          .text(isIn ? "↑ IN" : "↓ OUT", tc.type, doc.y - 10, { width: 50 });
        doc.fillColor("#1f2740")
          .text(row.warehouse ?? "—", tc.wh, doc.y - 10, { width: 115 })
          .text(row.itemName ?? "—", tc.item, doc.y - 10, { width: 90 })
          .text(row.batchNumber ?? "—", tc.batch, doc.y - 10, { width: 90 })
          .text(row.quantityMt.toFixed(2), tc.mt, doc.y - 10, { width: 55 });
        doc.moveDown(0.1);
        doc.moveTo(50, doc.y).lineTo(545, doc.y).strokeColor("#f0f4fa").stroke();
        doc.moveDown(0.1);
      }

      if (rows.length === 0) {
        doc.fillColor("#79839a").fontSize(9).text("No transactions found for the selected filters.", { align: "center" });
      }

      doc.end();
    });

    const fileName = `stock-movement-report-${Date.now()}.pdf`;
    res.set({
      "Content-Type": "application/pdf",
      "Content-Disposition": `attachment; filename="${fileName}"`,
      "Content-Length": buffer.length,
    });
    res.end(buffer);
  }
}
