const express = require('express');
const Document = require('../models/Document.cjs');
const Client = require('../models/Client.cjs');
const Supplier = require('../models/Supplier.cjs');
const { auth } = require('../middleware/auth.cjs');
const { v4: uuidv4 } = require('uuid');

const router = express.Router();

// Get all documents with filtering and pagination
router.get('/', auth, async (req, res) => {
  try {
    const {
      type,
      status,
      client,
      supplier,
      search,
      dateFrom,
      dateTo,
      page = 1,
      limit = 20
    } = req.query;

    const filter = { company: req.user.company._id };

    if (type) filter.type = type;
    if (status) filter.status = status;
    if (client) filter.client = client;
    if (supplier) filter.supplier = supplier;

    if (dateFrom || dateTo) {
      filter.issueDate = {};
      if (dateFrom) filter.issueDate.$gte = new Date(dateFrom);
      if (dateTo) filter.issueDate.$lte = new Date(dateTo);
    }

    if (search) {
      filter.$or = [
        { number: { $regex: search, $options: 'i' } },
        { notes: { $regex: search, $options: 'i' } }
      ];
    }

    const documents = await Document.find(filter)
      .populate('client', 'name email')
      .populate('supplier', 'name email')
      .populate('createdBy', 'firstName lastName')
      .sort({ createdAt: -1 })
      .limit(limit * 1)
      .skip((page - 1) * limit);

    const total = await Document.countDocuments(filter);

    res.json({
      documents,
      pagination: {
        current: page,
        pages: Math.ceil(total / limit),
        total
      }
    });
  } catch (error) {
    console.error('Get documents error:', error);
    res.status(500).json({ message: 'Server error' });
  }
});

// Get document by ID
router.get('/:id', auth, async (req, res) => {
  try {
    const document = await Document.findOne({
      _id: req.params.id,
      company: req.user.company._id
    })
      .populate('client')
      .populate('supplier')
      .populate('template')
      .populate('createdBy', 'firstName lastName')
      .populate('auditTrail.user', 'firstName lastName')
      .populate('requisition', 'number client items');

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

    res.json(document);
  } catch (error) {
    console.error('Get document error:', error);
    res.status(500).json({ message: 'Server error' });
  }
});

// Create new document
router.post('/', auth, async (req, res) => {
  try {
    const {
      type,
      client,
      supplier,
      lineItems,
      dueDate,
      validUntil,
      currency,
      paymentTerms,
      notes,
      terms,
      template,
      requisition  // NEW: Accept requisition ID
    } = req.body;

    // Generate document number
    const company = req.user.company;
    let number, nextNumberField;
    
    switch (type) {
      case 'invoice':
        number = company.invoiceNumberPrefix + company.nextInvoiceNumber;
        nextNumberField = 'nextInvoiceNumber';
        break;
      case 'quotation':
        number = company.quotationNumberPrefix + company.nextQuotationNumber;
        nextNumberField = 'nextQuotationNumber';
        break;
      case 'worksheet':
        number = company.worksheetNumberPrefix + company.nextWorksheetNumber;
        nextNumberField = 'nextWorksheetNumber';
        break;
      case 'purchase_order':
        number = company.purchaseOrderNumberPrefix + company.nextPurchaseOrderNumber;
        nextNumberField = 'nextPurchaseOrderNumber';
        break;
    }

    const document = new Document({
      company: company._id,
      type,
      number,
      client: type === 'purchase_order' ? null : client,
      supplier: type === 'purchase_order' ? supplier : null,
      lineItems: lineItems || [],
      dueDate,
      validUntil,
      currency: currency || company.currency,
      paymentTerms: paymentTerms || company.paymentTerms,
      notes,
      terms,
      template,      
      requisition, // NEW: Link to requisition if provided
      createdBy: req.user._id,
      auditTrail: [{
        action: 'created',
        user: req.user._id,
        details: `Document created as ${type}`
      }]
    });

    await document.save();

    // Increment document number
    await company.updateOne({
      [nextNumberField]: company[nextNumberField] + 1
    });

    const populatedDocument = await Document.findById(document._id)
      .populate('client')
      .populate('supplier')
      .populate('template')
      .populate('requisition', 'number client items');  // NEW

    res.status(201).json(populatedDocument);
  } catch (error) {
    console.error('Create document error:', error);
    res.status(500).json({ message: 'Server error' });
  }
});

// Update document
router.put('/:id', auth, async (req, res) => {
  try {
    const document = await Document.findOne({
      _id: req.params.id,
      company: req.user.company._id
    });

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

    const updateData = { ...req.body };
    delete updateData.company;
    delete updateData.number;
    delete updateData.type;
    
    updateData.lastModifiedBy = req.user._id;
    
    // Add audit trail
    if (!document.auditTrail) document.auditTrail = [];
    document.auditTrail.push({
      action: 'updated',
      user: req.user._id,
      details: 'Document updated'
    });

    Object.assign(document, updateData);
    await document.save();

    const updatedDocument = await Document.findById(document._id)
      .populate('client')
      .populate('supplier')
      .populate('template')
      .populate('requisition', 'number client items');  // NEW

    res.json(updatedDocument);
  } catch (error) {
    console.error('Update document error:', error);
    res.status(500).json({ message: 'Server error' });
  }
});

// Update document status
router.patch('/:id/status', auth, async (req, res) => {
  try {
    const { status } = req.body;
    
    const document = await Document.findOne({
      _id: req.params.id,
      company: req.user.company._id
    });

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

    const oldStatus = document.status;
    document.status = status;
    document.lastModifiedBy = req.user._id;
    
    // Add audit trail
    document.auditTrail.push({
      action: 'status_changed',
      user: req.user._id,
      details: `Status changed from ${oldStatus} to ${status}`
    });

    await document.save();

    res.json({ message: 'Status updated successfully', document });
  } catch (error) {
    console.error('Update status error:', error);
    res.status(500).json({ message: 'Server error' });
  }
});

// Delete document
router.delete('/:id', auth, async (req, res) => {
  try {
    const document = await Document.findOneAndDelete({
      _id: req.params.id,
      company: req.user.company._id
    });

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

    res.json({ message: 'Document deleted successfully' });
  } catch (error) {
    console.error('Delete document error:', error);
    res.status(500).json({ message: 'Server error' });
  }
});

// Generate share link
router.post('/:id/share', auth, async (req, res) => {
  try {
    const document = await Document.findOne({
      _id: req.params.id,
      company: req.user.company._id
    });

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

    document.shareToken = uuidv4();
    document.shareExpiresAt = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000); // 30 days
    
    // Add audit trail
    document.auditTrail.push({
      action: 'share_link_generated',
      user: req.user._id,
      details: 'Share link generated'
    });

    await document.save();

    const shareUrl = `${process.env.CLIENT_URL}/share/${document.shareToken}`;
    
    res.json({
      message: 'Share link generated successfully',
      shareUrl,
      expiresAt: document.shareExpiresAt
    });
  } catch (error) {
    console.error('Generate share link error:', error);
    res.status(500).json({ message: 'Server error' });
  }
});

module.exports = router;