import { query } from '../utils/database.js'; import { sendEmail } from '../utils/email.js'; import { generateTicketPDF } from '../utils/pdf.js'; import path from 'path'; import fs from 'fs'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); export const createTicket = async (req, res) => { try { const { matchId, name, email, phone, selectedSeats, deliveryMethod } = req.body; // Start transaction await query('START TRANSACTION'); try { // Check if seats are available const seats = await query( 'SELECT * FROM seats WHERE matchId = ? AND seatNumber IN (?) AND status = "available"', [matchId, selectedSeats] ); if (seats.length !== selectedSeats.length) { throw new Error('Some selected seats are not available'); } // Create ticket const ticketResult = await query( `INSERT INTO tickets ( matchId, name, email, phone, seats, deliveryMethod ) VALUES (?, ?, ?, ?, ?, ?)`, [matchId, name, email, phone, selectedSeats.length, deliveryMethod] ); const ticketId = ticketResult.insertId; // Update seats status await query( 'UPDATE seats SET status = "booked", ticketId = ? WHERE matchId = ? AND seatNumber IN (?)', [ticketId, matchId, selectedSeats] ); // Update match available seats await query( 'UPDATE matches SET availableSeats = availableSeats - ? WHERE id = ?', [selectedSeats.length, matchId] ); // Generate PDF const pdfFileName = `${Date.now()}-${name}-${selectedSeats.length}.pdf`; const pdfPath = path.join(__dirname, '..', '..', 'public', 'uploads', pdfFileName); const match = await query('SELECT * FROM matches WHERE id = ?', [matchId]); await generateTicketPDF({ ticketId, match: match[0], name, email, phone, seats: seats, pdfFile: pdfFileName }); // Update ticket with PDF path await query( 'UPDATE tickets SET pdfFile = ? WHERE id = ?', [`/uploads/${pdfFileName}`, ticketId] ); // Send email if requested if (deliveryMethod === 'email') { await sendEmail({ to: email, subject: `Your tickets for ${match[0].name}`, text: `Thank you for booking tickets for ${match[0].name}. Your seat numbers are: ${selectedSeats.join(', ')}`, attachments: [{ filename: pdfFileName, path: pdfPath }] }); } // Commit transaction await query('COMMIT'); res.status(201).json({ message: 'Ticket created successfully', ticketId, pdfUrl: `/uploads/${pdfFileName}` }); } catch (error) { // Rollback transaction on error await query('ROLLBACK'); throw error; } } catch (error) { console.error('Error creating ticket:', error); res.status(500).json({ message: 'Failed to create ticket', error: error.message }); } }; export const getMatchSeats = async (req, res) => { try { const { matchId } = req.params; const seats = await query(` SELECT s.*, t.name as bookedBy, t.email as bookedByEmail FROM seats s LEFT JOIN tickets t ON s.ticketId = t.id WHERE s.matchId = ? ORDER BY s.seatNumber `, [matchId]); res.status(200).json(seats); } catch (error) { console.error('Error fetching seats:', error); res.status(500).json({ message: 'Failed to fetch seats', error: error.message }); } }; export const getTicketStatus = async (req, res) => { try { const ticketId = req.params.ticketId || req; // If called as a controller (req, res), req.params.ticketId is used // If called as a service (just ticketId), req is the id const id = typeof ticketId === 'object' ? ticketId.ticketId : ticketId; const result = await query('SELECT * FROM tickets WHERE id = ?', [id]); if (!result || result.length === 0) { if (res) { return res.status(404).json({ message: 'Ticket not found' }); } else { return null; } } if (res) { res.json(result[0]); } else { return result[0]; } } catch (error) { console.error('Error getting ticket status:', error); if (res) { res.status(500).json({ message: 'Failed to get ticket status', error: error.message }); } else { throw error; } } };