const pool = require('../config/db');
const asyncHandler = require('../middlewares/asyncHandler');
const {
  getAllTickets,
  getTicketById,
  createTicket,
  updateTicket,
  deleteTicket
} = require('../repositories/ticketsRepository');
const { buildTicketMailBody, buildCloseTicketMailBody, sendTicketEmail } = require('../services/emailService');

// Get all tickets
exports.getAllTickets = asyncHandler(async (req, res) => {
    const rows = await getAllTickets();
    res.status(200).json({ success: true, data: rows });
});

// Get ticket by ID
exports.getTicketById = asyncHandler(async (req, res) => {
    const { id } = req.params;
    const ticket = await getTicketById(id);
    
    if (!ticket) {
        return res.status(404).json({ success: false, message: 'Ticket not found' });
    }
    
    res.status(200).json({ success: true, data: ticket });
});

// Create ticket (form data → save → auto-generate mail body and send to receiver; optional file attachments sent with email)
exports.createTicket = asyncHandler(async (req, res) => {
    const user_id = req.body.user_id ?? req.user?.userId;
    const ticket_type_id = req.body.ticket_type_id;
    const description = req.body.description;
    const subject = req.body.subject;
    const recipient_email = req.body.recipient_email;
    const extra_fields = req.body.extra_fields;
    const status_id = 1; // Open

    if (!user_id || !ticket_type_id) {
        return res.status(400).json({ success: false, message: 'user_id and ticket_type_id are required' });
    }

    const connection = await pool.getConnection();
    try {
        await connection.beginTransaction();
        const ticketData = { user_id, ticket_type_id, status_id, description, subject, recipient_email };
        const ticketId = await createTicket(ticketData, connection);
        await connection.commit();

        const ticket = await getTicketById(ticketId);
        const to = ticket.recipient_email || recipient_email || process.env.SUPPORT_EMAIL || 'eframeinterns@gmail.com';
        const senderDisplay = process.env.SMTP_FROM || process.env.SMTP_USER || 'SAT Support';
        const formDataForEmail = {
            subject: ticket.subject || subject || 'Support Request',
            ticket_type_name: ticket.ticket_type_name,
            description: ticket.description,
            user_name: ticket.user_name,
            user_email: ticket.user_email,
            created_at: ticket.created_at,
            recipient_email_display: to,
            sender_email_display: senderDisplay,
            extra_fields: extra_fields || null
        };
        const htmlBody = buildTicketMailBody(formDataForEmail);
        const emailOpts = {
            to,
            subject: formDataForEmail.subject,
            htmlBody
        };
        if (req.files && req.files.length > 0) {
            emailOpts.attachments = req.files.map((f) => ({
                filename: f.originalname || 'attachment',
                content: f.buffer
            }));
        }
        let emailResult = { skipped: true };
        if (to) {
            emailResult = await sendTicketEmail(emailOpts);
        }
        const emailSent = Boolean(emailResult.sent);
        const message = emailSent
            ? 'Ticket created successfully. Notification email sent.'
            : emailResult.skipped
                ? 'Ticket created successfully.'
                : 'Ticket created successfully, but the notification email could not be sent.';
        res.status(201).json({
            success: true,
            message,
            data: {
                ticket_id: ticketId,
                email: emailResult
            }
        });
    } catch (error) {
        await connection.rollback();
        throw error;
    } finally {
        connection.release();
    }
});

// Update ticket
exports.updateTicket = asyncHandler(async (req, res) => {
    const { id } = req.params;
    const { user_id, ticket_type_id, status_id, description, closed_at, subject, recipient_email } = req.body;
    
    const updateData = {};
    if (user_id !== undefined) updateData.user_id = user_id;
    if (ticket_type_id !== undefined) updateData.ticket_type_id = ticket_type_id;
    if (status_id !== undefined) updateData.status_id = status_id;
    if (description !== undefined) updateData.description = description;
    if (closed_at !== undefined) updateData.closed_at = closed_at;
    if (subject !== undefined) updateData.subject = subject;
    if (recipient_email !== undefined) updateData.recipient_email = recipient_email;
    
    const connection = await pool.getConnection();
    try {
        await connection.beginTransaction();
        
        const updated = await updateTicket(id, updateData, connection);
        
        if (!updated) {
            await connection.rollback();
            return res.status(404).json({ success: false, message: 'Ticket not found' });
        }
        
        await connection.commit();
        res.status(200).json({ success: true, message: 'Ticket updated successfully' });
    } catch (error) {
        await connection.rollback();
        throw error;
    } finally {
        connection.release();
    }
});

// Resolve ticket (set status to Resolved and closed_at to now); generates and sends resolve-ticket email
exports.closeTicket = asyncHandler(async (req, res) => {
    const { id } = req.params;
    const connection = await pool.getConnection();
    try {
        await connection.beginTransaction();
        const updated = await updateTicket(id, { status_id: 3, closed_at: new Date() }, connection);
        if (!updated) {
            await connection.rollback();
            connection.release();
            return res.status(404).json({ success: false, message: 'Ticket not found' });
        }
        await connection.commit();
        // Fetch updated ticket and send resolve-ticket email
        const ticket = await getTicketById(id);
        const to = ticket?.recipient_email || process.env.SUPPORT_EMAIL || 'eframeinterns@gmail.com';
        if (to && ticket) {
            const emailResult = await sendTicketEmail({
                to,
                subject: `Ticket resolved: ${ticket.subject || '#' + id}`,
                htmlBody: buildCloseTicketMailBody(ticket)
            });
            if (!emailResult.sent && !emailResult.skipped) {
                console.error('[tickets] Failed to send resolve-ticket email:', emailResult.error);
            }
        }
        res.status(200).json({ success: true, message: 'Ticket resolved successfully' });
    } catch (error) {
        await connection.rollback();
        throw error;
    } finally {
        connection.release();
    }
});

// Delete ticket
exports.deleteTicket = asyncHandler(async (req, res) => {
    const { id } = req.params;
    const connection = await pool.getConnection();
    try {
        await connection.beginTransaction();
        
        const deleted = await deleteTicket(id, connection);
        
        if (!deleted) {
            await connection.rollback();
            return res.status(404).json({ success: false, message: 'Ticket not found' });
        }
        
        await connection.commit();
        res.status(200).json({ success: true, message: 'Ticket deleted successfully' });
    } catch (error) {
        await connection.rollback();
        throw error;
    } finally {
        connection.release();
    }
});

