const express = require('express');
const Requisition = require('../models/Requisition.cjs');
const Service = require('../models/Service.cjs');
const { auth } = require('../middleware/auth.cjs');
const router = express.Router();

// Get all requisitions
router.get('/', auth, async (req, res) => {
  try {
    const requisitions = await Requisition.find({ company: req.user.company._id })
      .populate('client', 'name email')
      .populate('items.service', 'name basePrice unit') // FIX: Populate within items array
      .sort({ createdAt: -1 });
    res.json(requisitions);
  } catch (error) {
    console.error('Fetch error:', error);
    res.status(500).json({ message: 'Error fetching requisitions' });
  }
});

// // Rota pública para o portal (Sem o middleware 'auth')
// router.post('/public', async (req, res) => {
//   try {
//     const { items, client, deliveryDate, notes, companyId } = req.body;

//     // 1. Validar se a empresa (companyId) foi enviada, já que não temos o req.user
//     if (!companyId) return res.status(400).json({ message: 'Target company is required' });

//     // 2. Processar itens e cálculos (Lógica idêntica à rota privada)
//     let subtotal = 0;
//     const processedItems = [];
      
//     let minAllowedInstallments = 99; 
//     let maxPenaltyRate = 0;

//     // Securely fetch prices and calculate totals on server
//     for (const item of items) {
//       const serviceDoc = await Service.findOne({ 
//         _id: item.serviceId, 
//         company: req.user.company._id 
//       });

//       if (!serviceDoc) {
//         return res.status(404).json({ message: `Service ${item.serviceId} not found` });
//       }

//       subtotal += serviceDoc.basePrice * item.quantity;
      
//       if (serviceDoc.allowedInstallments < minAllowedInstallments) {
//         minAllowedInstallments = serviceDoc.allowedInstallments;
//       }
//       if (serviceDoc.penaltyPercentagePerInstallment > maxPenaltyRate) {
//         maxPenaltyRate = serviceDoc.penaltyPercentagePerInstallment;
//       }

//       processedItems.push({
//         service: serviceDoc._id,
//         quantity: item.quantity,
//         priceAtTime: serviceDoc.basePrice
//       });
//     }

//     let finalTotal = subtotal;
//     if (requestedInstallments > minAllowedInstallments) {
//       const extra = requestedInstallments - minAllowedInstallments;
//       finalTotal += subtotal * (extra * (maxPenaltyRate / 100));
//     }

//     const count = await Requisition.countDocuments({ company: companyId });
//     const number = `EXT-${1000 + count + 1}`; // Prefixo diferenciado para rastreio

//     const requisition = new Requisition({
//       number,
//       company: companyId,
//       client, // O ID do cliente deve ser enviado pelo formulário público ou criado na hora
//       items: processedItems,
//       origin: 'external', // Diferenciação no banco [cite: 22]
//       status: 'pending',
//       deliveryDate,
//       notes
//     });

//     await requisition.save(); [cite: 23]
//     res.status(201).json({ message: 'Requisition submitted successfully', number });
//   } catch (error) {
//     res.status(400).json({ message: error.message });
//   }
// });

// Em requisitions.cjs - Adicionar ANTES do module.exports
router.post('/public-submit', async (req, res) => {
  try {
    const { clientData, requisitionData, companyId } = req.body;

    // 1. Criar ou atualizar o Cliente Externo
    const Client = require('../models/Client.cjs');
    let client = await Client.findOne({ email: clientData.email, company: companyId, origin: 'external', contactPerson: clientData.contactPerson, taxId: clientData.taxId, vatNumber: clientData.vatNumber, name: clientData.name });
    
    if (!client) {
      client = new Client({
        ...clientData,
        company: companyId,
        taxId: clientData.taxId,
        vatNumber: clientData.vatNumber,
        name: clientData.name,
        contactPerson: clientData.contactPerson,
        origin: 'external' // Badge de cliente externo
      });
      await client.save();
    }

    // 2. Processar itens da requisição (Lógica similar ao POST interno [cite: 72, 73])
    const Service = require('../models/Service.cjs');
    let subtotal = 0;
    const processedItems = [];

    for (const item of requisitionData.items) {
      const serviceDoc = await Service.findById(item.service);
      if (serviceDoc) {
        subtotal += serviceDoc.basePrice * item.quantity;
        processedItems.push({
          service: serviceDoc._id,
          quantity: item.quantity,
          priceAtTime: serviceDoc.basePrice
        });
      }
    }

    // 3. Gerar número e salvar requisição
    const count = await Requisition.countDocuments({ company: companyId });
    const requisition = new Requisition({
      number: `EXT-${2000 + count + 1}`,
      company: companyId,
      client: client._id,
      items: processedItems,
      origin: 'external',
      requestedInstallments: requisitionData.requestedInstallments || 1,
      deliveryDate: requisitionData.deliveryDate,
      notes: requisitionData.notes,
      // Novos campos / lógica
      requestIntent: requisitionData.requestIntent || 'quotation', // fallback seguro
      // Opcional: definir status inicial de acordo com a intenção
      status: requisitionData.requestIntent === 'invoice' 
        ? 'invoice_requested' 
        : 'quotation_requested'   // ou manter 'pending' se preferires
   
    });

    await requisition.save();

    // Resposta (podes incluir requestIntent na resposta se quiseres)
    res.status(201).json({
      success: true,
      requisitionId: requisition._id,
      number: requisition.number,
      message: requisition.requestIntent === 'invoice'
        ? 'Solicitação para fatura submetida com sucesso'
        : 'Pedido de cotação submetido com sucesso'
    });
  } catch (error) {
    res.status(400).json({ message: error.message });
  }
});

// Create a requisition
router.post('/', auth, async (req, res) => {
  try {
    const { items, requestedInstallments, client, deliveryDate, notes } = req.body;

    if (!items || !items.length) {
      return res.status(400).json({ message: 'At least one service item is required' });
    }

    let subtotal = 0;
    const processedItems = [];
    let minAllowedInstallments = 99; 
    let maxPenaltyRate = 0;

    // Securely fetch prices and calculate totals on server
    for (const item of items) {
      const serviceDoc = await Service.findOne({ 
        _id: item.serviceId, 
        company: req.user.company._id 
      });

      if (!serviceDoc) {
        return res.status(404).json({ message: `Service ${item.serviceId} not found` });
      }

      subtotal += serviceDoc.basePrice * item.quantity;
      
      if (serviceDoc.allowedInstallments < minAllowedInstallments) {
        minAllowedInstallments = serviceDoc.allowedInstallments;
      }
      if (serviceDoc.penaltyPercentagePerInstallment > maxPenaltyRate) {
        maxPenaltyRate = serviceDoc.penaltyPercentagePerInstallment;
      }

      processedItems.push({
        service: serviceDoc._id,
        quantity: item.quantity,
        priceAtTime: serviceDoc.basePrice
      });
    }

    let finalTotal = subtotal;
    if (requestedInstallments > minAllowedInstallments) {
      const extra = requestedInstallments - minAllowedInstallments;
      finalTotal += subtotal * (extra * (maxPenaltyRate / 100));
    }

    const count = await Requisition.countDocuments({ company: req.user.company._id });
    const number = `REQ-${1000 + count + 1}`;

    const requisition = new Requisition({
      number,
      company: req.user.company._id,
      client,
      origin: 'internal',
      items: processedItems,
      requestedInstallments,
      deliveryDate,
      notes,
      finalTotal
    });

    await requisition.save();
    
    const populatedReq = await Requisition.findById(requisition._id)
      .populate('client', 'name email')
      .populate('items.service', 'name unit');

    res.status(201).json(populatedReq);
  } catch (error) {
    res.status(400).json({ message: error.message });
  }
});

// Get single requisition details
router.get('/:id', auth, async (req, res) => {
  try {
    const requisition = await Requisition.findOne({ 
      _id: req.params.id, 
      company: req.user.company._id 
    })
    .populate('client')
    .populate('items.service'); // CHANGE THIS: Populate from items array
    
    if (!requisition) return res.status(404).json({ message: 'Requisition not found' });
    res.json(requisition);
  } catch (error) {
    res.status(500).json({ message: error.message });
  }
});
// Update status specifically
// Update status specifically
// Update status specifically
router.patch('/:id/status', auth, async (req, res) => {
  const { status } = req.body;
  // Updated to match frontend/model enum
  const allowedStatuses = ['pending', 'approved', 'rejected', 'converted_to_invoice'];

  if (!allowedStatuses.includes(status)) {
    return res.status(400).json({ message: 'Invalid status value' });
  }

  try {
    const requisition = await Requisition.findOneAndUpdate(
      { _id: req.params.id, company: req.user.company._id },
      { status },
      { new: true, runValidators: true, lean: true } // lean for perf
    )
      .populate('client', 'name email') // Direct client populate
      .populate('items.service', 'name unit basePrice'); // Nested for multi-items

    if (!requisition) {
      return res.status(404).json({ message: 'Requisition not found' });
    }

    res.json(requisition);
  } catch (error) {
    console.error('Status update error:', error); // Log for debugging
    res.status(400).json({ message: error.message || 'Failed to update status' });
  }
});

// Replace your current router.put('/:id', ...) with this:
router.put('/:id', auth, async (req, res) => {
  try {
    const { items, requestedInstallments, client, deliveryDate, notes } = req.body;
    
    const requisition = await Requisition.findOne({
      _id: req.params.id,
      company: req.user.company._id
    });

    if (!requisition) {
      return res.status(404).json({ message: 'Requisition not found' });
    }

    // If items are being updated, we must recalculate totals (same logic as POST)
    if (items) {
      let subtotal = 0;
      const processedItems = [];
      let minAllowedInstallments = 99; 
      let maxPenaltyRate = 0;

      for (const item of items) {
        const serviceDoc = await Service.findOne({ 
          _id: item.serviceId || item.service, // Handle both naming conventions
          company: req.user.company._id 
        });

        if (!serviceDoc) {
          return res.status(404).json({ message: `Service ${item.serviceId} not found` });
        }

        subtotal += serviceDoc.basePrice * item.quantity;
        if (serviceDoc.allowedInstallments < minAllowedInstallments) minAllowedInstallments = serviceDoc.allowedInstallments;
        if (serviceDoc.penaltyPercentagePerInstallment > maxPenaltyRate) maxPenaltyRate = serviceDoc.penaltyPercentagePerInstallment;

        processedItems.push({
          service: serviceDoc._id,
          quantity: item.quantity,
          priceAtTime: serviceDoc.basePrice
        });
      }

      let finalTotal = subtotal;
      const inst = requestedInstallments || requisition.requestedInstallments;
      if (inst > minAllowedInstallments) {
        const extra = inst - minAllowedInstallments;
        finalTotal += subtotal * (extra * (maxPenaltyRate / 100));
      }

      requisition.items = processedItems;
      requisition.finalTotal = finalTotal;
    }

    // Update other basic fields
    if (client) requisition.client = client;
    if (requestedInstallments) requisition.requestedInstallments = requestedInstallments;
    if (deliveryDate) requisition.deliveryDate = deliveryDate;
    if (notes) requisition.notes = notes;

    await requisition.save();
    
    const updatedReq = await Requisition.findById(requisition._id)
      .populate('client', 'name email')
      .populate('items.service', 'name unit');
      
    res.json(updatedReq);
  } catch (error) {
    res.status(400).json({ message: error.message });
  }
});
// Add to requisitions.cjs
router.delete('/:id', auth, async (req, res) => {
  try {
    const requisition = await Requisition.findOneAndDelete({
      _id: req.params.id,
      company: req.user.company._id
    });
    if (!requisition) return res.status(404).json({ message: 'Not found' });
    res.json({ message: 'Deleted successfully' });
  } catch (error) {
    res.status(500).json({ message: error.message });
  }
});
module.exports = router;