"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SupportTicketService = void 0;
class SupportTicketService {
    ticketRepository;
    messageRepository;
    settingsRepository;
    logger;
    constructor(ticketRepository, messageRepository, settingsRepository, logger) {
        this.ticketRepository = ticketRepository;
        this.messageRepository = messageRepository;
        this.settingsRepository = settingsRepository;
        this.logger = logger;
    }
    async createTicket(userId, initialMessage, category, priority = "NORMAL") {
        const settings = await this.settingsRepository.get();
        const maxTicketsPerUser = settings?.maxTicketsPerUser ?? 3;
        const userTickets = await this.ticketRepository.findByUserId(userId);
        const openTickets = userTickets.filter((t) => !["CLOSED", "RESOLVED"].includes(t.status));
        if (openTickets.length >= maxTicketsPerUser) {
            throw new Error(`Maximum open tickets per user reached (${maxTicketsPerUser}).`);
        }
        const existingOpen = await this.ticketRepository.findOpenByUserId(userId);
        if (existingOpen) {
            this.logger.info("User already has an open ticket; reusing.", {
                userId,
                ticketId: existingOpen.id
            });
            return existingOpen;
        }
        const ticketNumber = await this.generateTicketNumber();
        const ticket = await this.ticketRepository.create({
            ticketNumber,
            userId,
            status: "OPEN",
            priority,
            category,
            lastMessage: initialMessage,
            lastActivity: new Date()
        });
        this.logger.info("Support ticket created.", { ticketId: ticket.id, ticketNumber });
        return ticket;
    }
    async getById(id) {
        return this.ticketRepository.findById(id);
    }
    async getByTicketNumber(ticketNumber) {
        return this.ticketRepository.findByTicketNumber(ticketNumber);
    }
    async getOpenTicketByUserId(userId) {
        return this.ticketRepository.findOpenByUserId(userId);
    }
    async listTickets(filters) {
        const page = Math.max(1, filters?.page ?? 1);
        const limit = Math.min(100, Math.max(1, filters?.limit ?? 20));
        const skip = (page - 1) * limit;
        const [tickets, total] = await Promise.all([
            this.ticketRepository.findAll(filters, filters?.sort, skip, limit),
            this.ticketRepository.count(filters)
        ]);
        return { tickets, total, page, pages: Math.ceil(total / limit) };
    }
    async assignTicket(ticketId, agentId) {
        const ticket = await this.ticketRepository.updateAtomic(ticketId, { assignedAgent: agentId, status: "ACTIVE" }, undefined);
        if (ticket) {
            this.logger.info("Ticket assigned.", { ticketId, agentId });
        }
        return ticket;
    }
    async updateStatus(ticketId, status, agentId) {
        const update = { status };
        if (agentId)
            update.assignedAgent = agentId;
        if (status === "CLOSED" || status === "RESOLVED") {
            update.closedAt = new Date();
        }
        const ticket = await this.ticketRepository.update(ticketId, update);
        if (ticket) {
            this.logger.info("Ticket status updated.", { ticketId, status, agentId });
        }
        return ticket;
    }
    async updatePriority(ticketId, priority) {
        return this.ticketRepository.update(ticketId, { priority });
    }
    async updateCategory(ticketId, category) {
        return this.ticketRepository.update(ticketId, { category });
    }
    async updateLastActivity(ticketId, message) {
        return this.ticketRepository.update(ticketId, { lastMessage: message, lastActivity: new Date() });
    }
    async getTicketStats() {
        const today = new Date();
        today.setHours(0, 0, 0, 0);
        const [open, waitingAgent, active, resolvedToday, closedToday] = await Promise.all([
            this.ticketRepository.count({ status: "OPEN" }),
            this.ticketRepository.count({ status: "WAITING_AGENT" }),
            this.ticketRepository.count({ status: "ACTIVE" }),
            this.ticketRepository.count({ status: "RESOLVED" }),
            this.ticketRepository.count({ status: "CLOSED" })
        ]);
        return { open, waitingAgent, active, resolvedToday, closedToday };
    }
    async generateTicketNumber() {
        const count = await this.ticketRepository.count();
        const next = count + 1;
        return `SUP-${String(next).padStart(6, "0")}`;
    }
}
exports.SupportTicketService = SupportTicketService;
