const { Quote, QuoteItem } = require('../models/billing');
const { Client } = require('../models/client');
const { logAction } = require('../utils/logger');
const { sequelize } = require('../config/db');

exports.createQuote = async (data, userId) => {
    const transaction = await sequelize.transaction();
    try {
        const count = await Quote.count();
        const quoteNumber = `QUO-${(count + 1).toString().padStart(4, '0')}`;

        const quote = await Quote.create({
            ...data,
            quoteNumber,
            createdBy: userId
        }, { transaction });

        if (data.items && data.items.length > 0) {
            const items = data.items.map(item => ({ ...item, quoteId: quote.id }));
            await QuoteItem.bulkCreate(items, { transaction });
        }

        await transaction.commit();
        await logAction(userId, 'CREATE', 'QUOTE', { id: quote.id, number: quoteNumber }, null);
        return quote;
    } catch (err) {
        await transaction.rollback();
        throw err;
    }
};

exports.getAllQuotes = async (filters = {}) => {
    const where = {};
    if (filters.clientId) where.clientId = filters.clientId;
    if (filters.status) where.status = filters.status;

    return await Quote.findAll({
        where,
        include: [Client, 'items'],
        order: [['issueDate', 'DESC'], ['createdAt', 'DESC']]
    });
};

exports.getQuoteById = async (id, clientId = null) => {
    const where = { id };
    if (clientId) where.clientId = clientId;
    return await Quote.findOne({ where, include: [Client, 'items'] });
};

exports.updateQuoteStatus = async (id, status, userId) => {
    const quote = await Quote.findByPk(id);
    if (!quote) throw new Error('Quote not found');

    quote.status = status;
    await quote.save();
    await logAction(userId, 'UPDATE_STATUS', 'QUOTE', { id, status }, null);
    return quote;
};

exports.updateQuote = async (id, data, userId) => {
    const transaction = await sequelize.transaction();
    try {
        const quote = await Quote.findByPk(id);
        if (!quote) throw new Error('Quote not found');

        await quote.update(data, { transaction });

        if (data.items) {
            await QuoteItem.destroy({ where: { quoteId: id }, transaction });
            const items = data.items.map(item => ({ ...item, quoteId: id }));
            await QuoteItem.bulkCreate(items, { transaction });
        }

        await transaction.commit();
        await logAction(userId, 'UPDATE', 'QUOTE', { id }, null);
        return quote;
    } catch (err) {
        await transaction.rollback();
        throw err;
    }
};

exports.deleteQuote = async (id, userId) => {
    const quote = await Quote.findByPk(id);
    if (!quote) throw new Error('Quote not found');

    await quote.destroy();
    await logAction(userId, 'DELETE', 'QUOTE', { id }, null);
    return true;
};
