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');

/**
 * Business Partner Report
 *
 * Query params:
 * - companyId (optional; defaults to user's company for non-superadmin)
 * - status (optional; ACTIVE/INACTIVE/BLOCKED/BLACKLISTED/ALL)
 * - approvalStatus (optional; PENDING/APPROVED/REJECTED/ALL)
 * - bpType (optional; CUSTOMER/VENDOR/BOTH/ALL)
 * - vendorCategoryId (optional)
 * - search (optional; bp number/name/pan/phone)
 * - page, limit (optional; default 1/25)
 * - export=true (optional; returns up to 50000 rows)
 */
exports.getBusinessPartnerReport = asyncHandler(async (req, res) => {
  try {
    const {
      page = 1,
      limit = 25,
      export: exportFlag,
      search,
      status,
      approvalStatus,
      bpType,
      vendorCategoryId,
      companyId,
      company_id,
    } = 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 = {};

    // Company filtering (same policy as other controllers)
    const companyIdValue = companyId || company_id;
    const isSuperAdmin = req.user && (req.user.isSuperAdmin || req.user.is_super_admin);
    if (!isSuperAdmin) {
      if (req.user?.companyId) {
        where.company_id = req.user.companyId;
      } else if (companyIdValue) {
        const companyIdNum = parseInt(companyIdValue, 10);
        if (!isNaN(companyIdNum)) where.company_id = companyIdNum;
      }
    } else if (companyIdValue && companyIdValue !== 'null' && companyIdValue !== 'undefined' && companyIdValue !== '') {
      const companyIdNum = parseInt(companyIdValue, 10);
      if (!isNaN(companyIdNum)) where.company_id = companyIdNum;
    }

    // Status
    if (status && status !== 'ALL') {
      where.status = status;
    } else {
      where.status = { [Op.ne]: 'DELETED' };
    }

    // Approval status
    if (approvalStatus && approvalStatus !== 'ALL') {
      where.approval_status = approvalStatus;
    }

    // BP Type
    if (bpType && bpType !== 'ALL') {
      where.bp_type = bpType;
    }

    // Vendor Category (main field)
    if (vendorCategoryId && vendorCategoryId !== 'null' && vendorCategoryId !== 'undefined' && vendorCategoryId !== '') {
      const catIdNum = parseInt(vendorCategoryId, 10);
      if (!isNaN(catIdNum)) where.vendor_category_id = catIdNum;
    }

    // Search
    if (search && String(search).trim()) {
      const q = String(search).trim();
      where[Op.or] = [
        { bp_number: { [Op.like]: `%${q}%` } },
        { name: { [Op.like]: `%${q}%` } },
        { legal_name: { [Op.like]: `%${q}%` } },
        { vendor_name: { [Op.like]: `%${q}%` } },
        { pan: { [Op.like]: `%${q}%` } },
        { phone_numbers: { [Op.like]: `%${q}%` } },
      ];
    }

    const include = [
      { model: db.Company, as: 'company', attributes: ['id', 'code', 'name'], required: false },
      { model: db.VendorCategory, as: 'vendorCategory', attributes: ['id', 'category_code', 'category_name'], required: false },
      { model: db.Currency, as: 'currency', attributes: ['id', 'currency_code', 'currency_name'], required: false },
    ];

    const records = await db.BusinessPartner.findAndCountAll({
      where,
      include,
      order: [['bp_number', 'ASC']],
      limit: limitNum,
      offset,
    });

    const items = (records.rows || []).map((r) => (r?.toJSON ? r.toJSON() : r));
    const response = getPagingData({ count: records.count || 0, rows: items }, effectivePage, limitNum);

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

