package handlers

import (
	"github.com/gin-gonic/gin"
	"github.com/jackc/pgx/v5/pgxpool"
	"ticketing-backend/internal/services"
	"ticketing-backend/internal/utils"
)

type TicketHandler struct {
	pool          *pgxpool.Pool
	ticketService *services.TicketService
}

func NewTicketHandler(pool *pgxpool.Pool, ticketService *services.TicketService) *TicketHandler {
	return &TicketHandler{pool: pool, ticketService: ticketService}
}

// ListTickets - GET /api/tickets/list
func (h *TicketHandler) ListTickets(c *gin.Context) {
	userID, _ := c.Get("userId")

	rows, err := h.pool.Query(c.Request.Context(),
		`SELECT t.id, t.booking_code, t.qr_code, t.ticket_class_name, t.buyer_name,
		        t.buyer_email, t.event_name, t.event_date, t.status, t.used_at, t.created_at,
		        o.event_id
		 FROM tickets t
		 JOIN orders o ON t.order_id = o.id
		 WHERE o.buyer_id = $1
		 ORDER BY t.created_at DESC`, userID,
	)
	if err != nil {
		utils.InternalError(c, "Failed to fetch tickets")
		return
	}
	defer rows.Close()

	var tickets []gin.H
	for rows.Next() {
		var id, bookingCode, qrCode, tcName, bName, bEmail, eventName, status, eventID string
		var eventDate, createdAt string
		var usedAt *string
		rows.Scan(&id, &bookingCode, &qrCode, &tcName, &bName, &bEmail, &eventName, &eventDate, &status, &usedAt, &createdAt, &eventID)
		tickets = append(tickets, gin.H{
			"id": id, "booking_code": bookingCode, "qr_code": qrCode,
			"ticket_class_name": tcName, "buyer_name": bName, "buyer_email": bEmail,
			"event_name": eventName, "event_date": eventDate, "status": status,
			"used_at": usedAt, "created_at": createdAt, "event_id": eventID,
		})
	}

	utils.Success(c, gin.H{"tickets": tickets})
}

// GenerateTickets - POST /api/tickets/generate
func (h *TicketHandler) GenerateTickets(c *gin.Context) {
	var req struct {
		OrderID string `json:"orderId" binding:"required"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		utils.BadRequest(c, "orderId is required")
		return
	}

	var eventID, ticketClassID, buyerID string
	var quantity int
	err := h.pool.QueryRow(c.Request.Context(),
		`SELECT event_id, ticket_class_id, buyer_id, quantity FROM orders WHERE id = $1 AND status = 'completed'`,
		req.OrderID,
	).Scan(&eventID, &ticketClassID, &buyerID, &quantity)

	if err != nil {
		utils.BadRequest(c, "Order not found or not completed")
		return
	}

	tickets, err := h.ticketService.GenerateTickets(req.OrderID, &buyerID, eventID, ticketClassID, quantity)
	if err != nil {
		utils.InternalError(c, "Failed to generate tickets")
		return
	}

	utils.Created(c, gin.H{"tickets": tickets})
}

// ValidateTicket - GET /api/tickets/validate?code=xxx
func (h *TicketHandler) ValidateTicket(c *gin.Context) {
	code := c.Query("code")
	if code == "" {
		utils.BadRequest(c, "code is required")
		return
	}

	ticket, err := h.ticketService.ValidateTicket(code)
	if err != nil {
		utils.NotFound(c, "Invalid ticket code")
		return
	}

	utils.Success(c, gin.H{"ticket": ticket})
}
