const db = require('../models');
const { sendResponse, sendError } = require('../utils/response');
const asyncHandler = require('../middlewares/asyncHandler');
const { getPagination, getPagingData } = require('../utils/pagination');
const { Op } = require('sequelize');

/**
 * Purchase Order Register Report
 *
 * Query params:
 * - companyId, plantId, vendorId, status, search
 * - dateFrom, dateTo (DATEONLY for po_date)
 * - page, limit (default 1, 25)
 * - export=true (up to 50000 rows)
 */
exports.getPurchaseOrderRegisterReport = asyncHandler(async (req, res) => {
  try {
    const {
      page = 1,
      limit = 25,
      export: exportFlag,
      search,
      status,
      companyId,
      plantId,
      vendorId,
      dateFrom,
      dateTo,
    } = req.query;

    const isExport = exportFlag === 'true' || exportFlag === true || exportFlag === 1 || exportFlag === '1';
    const effectiveLimit = isExport ? 50000 : parseInt(limit, 10) || 25;
    const effectivePage = isExport ? 1 : parseInt(page, 10) || 1;
    const { limit: limitNum, offset } = getPagination(effectivePage, effectiveLimit);

    const where = {};

    if (companyId) {
      where.company_id = companyId;
    } else if (req.user && !req.user.isSuperAdmin) {
      where.company_id = req.user.companyId;
    }

    if (plantId) where.plant_id = plantId;
    if (vendorId) where.vendor_id = vendorId;
    if (status && status !== 'ALL') where.status = status;

    if (dateFrom || dateTo) {
      where.po_date = {};
      if (dateFrom) where.po_date[Op.gte] = dateFrom;
      if (dateTo) where.po_date[Op.lte] = dateTo;
    }

    if (search && String(search).trim()) {
      where[Op.or] = [{ po_number: { [Op.like]: `%${String(search).trim()}%` } }];
    }

    const include = [
      { model: db.Company, as: 'company', attributes: ['id', 'code', 'name'], required: false },
      { model: db.Plant, as: 'plant', attributes: ['id', 'code', 'name'], required: false },
      { model: db.BusinessPartner, as: 'vendor', attributes: ['id', 'bp_number', 'name', 'legal_name'], required: false },
    ];

    const records = await db.PurchaseOrder.findAndCountAll({
      where,
      include,
      order: [['po_date', 'DESC'], ['po_number', 'DESC'], ['id', 'DESC']],
      limit: limitNum,
      offset,
    });

    const items = (records.rows || [])
      .map((r) => {
        const row = r?.toJSON ? r.toJSON() : r;
        if (!row) return null;
        return {
          ...row,
          id: row.id != null ? row.id : row.po_number,
          company_name: row.company?.name ?? row.company?.code ?? '',
          plant_name: row.plant?.name ?? row.plant?.code ?? '',
          vendor_name: row.vendor?.name ?? row.vendor?.bp_number ?? row.vendor?.legal_name ?? '',
        };
      })
      .filter(Boolean);
    const response = getPagingData({ count: records.count || 0, rows: items }, effectivePage, limitNum);

    return sendResponse(res, 200, true, 'Purchase Order Register generated successfully', response);
  } catch (error) {
    console.error('Purchase Order Register Report error:', error);
    return sendError(res, error.message || 'Failed to generate Purchase Order Register', 500);
  }
});
