const db = require('../models');
const { Op } = require('sequelize');
const { generateNextNumber } = require('./numberFormatService');

const generateProductionQCNumber = async (companyId, fiscalYearId = null, transaction = null) => {
  try {
    return await generateNextNumber(companyId, 'PRODUCTION_QC', fiscalYearId, transaction);
  } catch (err) {
    const year = new Date().getFullYear();
    const prefix = `PQC${year}`;
    const last = await db.ProductionQC.findOne({
      where: {
        company_id: companyId,
        production_qc_number: { [Op.like]: `${prefix}%` }
      },
      order: [['production_qc_number', 'DESC']],
      ...(transaction ? { transaction } : {})
    });
    let sequence = 1;
    if (last?.production_qc_number) {
      const lastSequence = parseInt(String(last.production_qc_number).slice(-4), 10) || 0;
      sequence = lastSequence + 1;
    }
    return `${prefix}${String(sequence).padStart(4, '0')}`;
  }
};

/**
 * Creates a Production QC row for a completed route card operation when none exists yet.
 * Used by Route Card "complete operation" (auto) and by the manual move-to-QC API.
 *
 * @returns {Promise<import('sequelize').Model|null>} Created record, or existing if already present
 */
exports.createFromRouteCardOperationIfNeeded = async ({ routeCardOperationId, userId, transaction }) => {
  const operation = await db.RouteCardOperation.findByPk(routeCardOperationId, {
    include: [
      {
        model: db.RouteCard,
        as: 'routeCard',
        attributes: ['id', 'company_id', 'plant_id', 'fiscal_year_id', 'work_order_id', 'production_order_id', 'route_card_number']
      }
    ],
    transaction
  });

  if (!operation) {
    throw new Error('Route Card operation not found');
  }
  if (operation.status !== 'COMPLETED') {
    throw new Error('Only COMPLETED operations can be moved to QC');
  }

  const routeCard = operation.routeCard;
  if (!routeCard) {
    throw new Error('Route Card not found for this operation');
  }

  const existing = await db.ProductionQC.findOne({
    where: { route_card_operation_id: operation.id },
    transaction
  });
  if (existing) {
    return existing;
  }

  const totalQty = parseFloat(operation.planned_qty || 0);
  const acceptedQty = parseFloat(operation.completed_qty || 0);
  const frRejectedQty = parseFloat(operation.fr_rejected_qty || 0);
  const mrRejectedQty = parseFloat(operation.mr_rejected_qty || 0);
  const rejectedQty = parseFloat(operation.rejected_qty || (frRejectedQty + mrRejectedQty) || 0);

  return db.ProductionQC.create(
    {
      production_qc_number: await generateProductionQCNumber(routeCard.company_id, routeCard.fiscal_year_id, transaction),
      company_id: routeCard.company_id,
      plant_id: routeCard.plant_id,
      fiscal_year_id: routeCard.fiscal_year_id,
      route_card_id: routeCard.id,
      route_card_operation_id: operation.id,
      work_order_id: routeCard.work_order_id || null,
      production_order_id: routeCard.production_order_id || null,
      operation_sequence_no: operation.operation_sequence_no,
      operation_code: operation.operation_code || null,
      operation_name: operation.operation_name || null,
      total_qty: totalQty,
      accepted_qty: acceptedQty,
      fr_rejected_qty: frRejectedQty,
      mr_rejected_qty: mrRejectedQty,
      rejected_qty: rejectedQty,
      rejection_remarks: operation.remarks || null,
      status: 'PENDING',
      moved_to_qc_by: userId
    },
    { transaction }
  );
};
