const { StaffPayment } = require('../models/staffPayment');
const { Staff } = require('../models/staff');
const { logAction } = require('../utils/logger');

const { sequelize } = require('../config/db');
const { Expense, ExpenseCategory } = require('../models/expense');
const { recordToDefaultBank } = require('../services/bankService');

exports.createPayment = async (req, res) => {
    const transaction = await sequelize.transaction();
    try {
        const payment = await StaffPayment.create(req.body, { transaction });

        // If created as 'Paid', record finance entries immediately
        if (payment.status === 'Paid') {
            let category = await ExpenseCategory.findOne({ where: { name: 'Commissions & Bonuses' }, transaction });
            if (!category) {
                category = await ExpenseCategory.create({ name: 'Commissions & Bonuses' }, { transaction });
            }

            const expense = await Expense.create({
                amount: payment.amount,
                expenseCategoryId: category.id,
                description: `Staff Payment: ${payment.paymentType || 'Misc'}`,
                paymentMethod: payment.paymentMethod || 'Cash',
                expenseDate: payment.paymentDate || new Date(),
                reference: `SP-${payment.id.split('-')[0]}`,
                notes: `Payment for Staff ID: ${payment.staffId}`,
                createdBy: req.user.id,
                status: 'PAID'
            }, { transaction });

            await recordToDefaultBank({
                type: 'Debit',
                amount: payment.amount,
                description: `Staff Payout: ${payment.paymentType}`,
                reference: `SP-${payment.id.split('-')[0]}`,
                module: 'StaffPayment',
                referenceId: payment.id
            }, transaction);
        }

        await transaction.commit();
        await logAction(req.user.id, 'CREATE', 'STAFF_PAYMENT', { id: payment.id, staffId: payment.staffId, amount: payment.amount }, null);
        res.status(201).json(payment);
    } catch (err) {
        await transaction.rollback();
        res.status(400).json({ error: err.message });
    }
};

exports.getPayments = async (req, res) => {
    try {
        const payments = await StaffPayment.findAll({
            include: [{ model: Staff, attributes: ['fullName', 'staffType', 'payType'] }],
            order: [['createdAt', 'DESC']]
        });
        res.json(payments);
    } catch (err) {
        res.status(500).json({ error: err.message });
    }
};

exports.updatePaymentStatus = async (req, res) => {
    const transaction = await sequelize.transaction();
    try {
        const { id } = req.params;
        const { status, paymentDate, paymentMethod, paymentReference } = req.body;

        const payment = await StaffPayment.findByPk(id);
        if (!payment) {
            await transaction.rollback();
            return res.status(404).json({ error: 'Payment record not found' });
        }

        const oldStatus = payment.status;
        await payment.update({
            status,
            paymentDate,
            paymentMethod,
            paymentReference
        }, { transaction });

        // If transitioning to Paid, record finance entries
        if (status === 'Paid' && oldStatus !== 'Paid') {
            let category = await ExpenseCategory.findOne({ where: { name: 'Commissions & Bonuses' }, transaction });
            if (!category) {
                category = await ExpenseCategory.create({ name: 'Commissions & Bonuses' }, { transaction });
            }

            await Expense.create({
                amount: payment.amount,
                expenseCategoryId: category.id,
                description: `Staff Payment: ${payment.paymentType || 'Misc'}`,
                paymentMethod: paymentMethod || 'Cash',
                expenseDate: paymentDate || new Date(),
                reference: paymentReference || `SP-${payment.id.split('-')[0]}`,
                notes: `Payment for Staff ID: ${payment.staffId}`,
                createdBy: req.user.id,
                status: 'PAID'
            }, { transaction });

            await recordToDefaultBank({
                type: 'Debit',
                amount: payment.amount,
                description: `Staff Payout: ${payment.paymentType}`,
                reference: paymentReference || `SP-${payment.id.split('-')[0]}`,
                module: 'StaffPayment',
                referenceId: payment.id
            }, transaction);
        }

        await transaction.commit();
        await logAction(req.user.id, 'UPDATE_STATUS', 'STAFF_PAYMENT', { id, status }, null);
        res.json(payment);
    } catch (err) {
        await transaction.rollback();
        res.status(500).json({ error: err.message });
    }
};

exports.deletePayment = async (req, res) => {
    try {
        const { id } = req.params;
        const payment = await StaffPayment.findByPk(id);
        if (!payment) return res.status(404).json({ error: 'Payment record not found' });

        await payment.destroy();
        await logAction(req.user.id, 'DELETE', 'STAFF_PAYMENT', { id }, null);
        res.json({ message: 'Payment record deleted' });
    } catch (err) {
        res.status(500).json({ error: err.message });
    }
};
