import type { Request, Response } from "express";
import { PurchaseReturnService } from "../services/PurchaseReturnService.js";
import { SupplierReturnsPdf } from "../utils/pdf/SupplierReturnsPdf.js";
import { generateSupplierReturnsExcel } from "../utils/excel/SupplierReturnsExcelExport.js";

const purchaseReturnService = new PurchaseReturnService();

export const createPurchaseReturn = async (req: Request, res: Response): Promise<void> => {
  try {
    const data = {
      ...req.body,
      createdBy: req.user?.id ? BigInt(req.user.id) : undefined,
    };
    const purchaseReturn = await purchaseReturnService.createPurchaseReturn(data);
    res.status(201).json({
      success: true,
      message: "Purchase return created successfully",
      data: purchaseReturn,
    });
  } catch (error: any) {
    const message = error instanceof Error ? error.message : "Failed to create purchase return";
    res.status(400).json({ message });
  }
};

export const getPurchaseReturns = async (req: Request, res: Response): Promise<void> => {
  try {
    const { supplierId, startDate, endDate, page, limit, search } = req.query;

    const filters = {
      supplierId: supplierId as string,
      startDate: startDate as string,
      endDate: endDate as string,
      search: search as string,
    };

    const parsedPage = page ? parseInt(page as string, 10) : 1;
    const parsedLimit = limit ? parseInt(limit as string, 10) : 20;

    const result = await purchaseReturnService.getPurchaseReturns(filters, parsedPage, parsedLimit);

    res.status(200).json({
      success: true,
      message: "Purchase returns fetched successfully",
      result,
    });
  } catch (error: any) {
    const message = error instanceof Error ? error.message : "Failed to fetch purchase returns";
    res.status(400).json({ message });
  }
};

export const getPurchaseReturnById = async (req: Request, res: Response): Promise<void> => {
  try {
    const id = BigInt(req.params.id as string);
    const purchaseReturn = await purchaseReturnService.getPurchaseReturnById(id);

    if (!purchaseReturn) {
      res.status(404).json({ success: false, message: "Purchase return not found" });
      return;
    }

    res.status(200).json({
      success: true,
      message: "Purchase return fetched successfully",
      result: purchaseReturn,
    });
  } catch (error: any) {
    const message = error instanceof Error ? error.message : "Failed to fetch purchase return";
    res.status(400).json({ message });
  }
};

export const deletePurchaseReturn = async (req: Request, res: Response): Promise<void> => {
  try {
    const id = BigInt(req.params.id as string);
    await purchaseReturnService.deletePurchaseReturn(id);
    res.status(200).json({
      success: true,
      message: "Purchase return deleted successfully",
    });
  } catch (error: any) {
    const message = error instanceof Error ? error.message : "Failed to delete purchase return";
    res.status(400).json({ message });
  }
};

export const exportPurchaseReturnsExcel = async (req: Request, res: Response): Promise<void> => {
  try {
    const { supplierId, startDate, endDate, search } = req.query;

    const filters = {
      supplierId: supplierId as string,
      startDate: startDate as string,
      endDate: endDate as string,
      search: search as string,
    };

    const returns = await purchaseReturnService.getAllForExport(filters);
    if (!returns || returns.length === 0) {
      res.status(400).json({ message: "No data available to export" });
      return;
    }
    const workbook = await generateSupplierReturnsExcel(returns);

    res.setHeader("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    res.setHeader("Content-Disposition", `attachment; filename=supplier-returns-${Date.now()}.xlsx`);
    res.setHeader("Access-Control-Expose-Headers", "Content-Disposition");

    await workbook.xlsx.write(res);
    res.end();
  } catch (error: any) {
    if (!res.headersSent) {
      const message = error instanceof Error ? error.message : "Failed to export Excel";
      res.status(500).json({ message });
    }
  }
};

export const exportPurchaseReturnsPdf = async (req: Request, res: Response): Promise<void> => {
  try {
    const { supplierId, startDate, endDate, search } = req.query;

    const filters = {
      supplierId: supplierId as string,
      startDate: startDate as string,
      endDate: endDate as string,
      search: search as string,
    };

    const returns = await purchaseReturnService.getAllForExport(filters);
    if (!returns || returns.length === 0) {
      res.status(400).json({ message: "No data available to export" });
      return;
    }
    await SupplierReturnsPdf.generate(returns, res, filters);
  } catch (error: any) {
    if (!res.headersSent) {
      const message = error instanceof Error ? error.message : "Failed to export PDF";
      res.status(500).json({ message });
    }
  }
};
