import { ErrorInfo } from "react";
import { Ticket, createTicket, getAuthToken, sendTicketMessage } from "..";

let errorsQueue: ComponentError[] = [];
let timeoutId: ReturnType<typeof setTimeout>;

interface ComponentError {
  timestamp: number;
  message: string;
  callStack: string | undefined;
  componentStack: string | null | undefined;
}

function isErrorReportingAllowed(error?: Error): boolean {
    // Если ошибка помечена как debug-override — всегда отправлять
    if (error && (error as any).__forceSend) return true;
    // Проверяем домен
    const currentDomain = window.location.hostname;
    return currentDomain !== 'localhost';
}

// Новый API: getTickets — callback, возвращающий актуальные тикеты
export function handleComponentError(error: Error, info: ErrorInfo, getTickets: () => Ticket[]) {
    //репортим только о авторизонышах
    if (!getAuthToken()) return;
    // Проверяем разрешение на отправку ошибок (по домену)
    if (!isErrorReportingAllowed(error)) {
        console.log('❌ Отправка ошибки заблокирована:', error.message);
        return;
    }
    console.log(`✅ Обработка ошибки: ${error.message}`);
    // Копируем __forceSend если есть
    const componentError: ComponentError & { __forceSend?: boolean } = {
    timestamp: Math.floor(Date.now() / 1000),
    message: error.message,
    callStack: error.stack,
    componentStack: info.componentStack,
        ...(error && (error as any).__forceSend ? { __forceSend: true } : {})
  };
    queueErrorRequest(componentError, getTickets);
}

// Ставит ошибку в очередь для отправки, через 1 секунду вызывает sendErrorsToServer
export function queueErrorRequest(error: ComponentError, getTickets: () => Ticket[]) {
  errorsQueue.push(error);
  clearTimeout(timeoutId);
  timeoutId = setTimeout(() => {
        sendErrorsToServer(getTickets);
  }, 1000);
}

// Отправляет накопленные ошибки в тикеты, ищет существующий тикет с system: true или создает новый
export async function sendErrorsToServer(getTickets: () => Ticket[]) {
    if (errorsQueue.length === 0) return;
    // Проверяем разрешение на отправку ошибок (по домену и debug-override)
    // Если хотя бы одна ошибка в очереди с __forceSend, отправляем всё
    const forceSend = errorsQueue.some(e => (e as any).__forceSend);
    if (!forceSend && !isErrorReportingAllowed()) {
        console.log('❌ Отправка ошибок заблокирована, очищаем очередь');
        errorsQueue = [];
        return;
    }
    const tickets = getTickets();
    try {
        // Формируем сообщение об ошибке
        const errorMessage = errorsQueue.map(error => {
            return `[${new Date(error.timestamp * 1000).toISOString()}] ${error.message}\n\nCall Stack:\n${error.callStack || 'N/A'}\n\nComponent Stack:\n${error.componentStack || 'N/A'}`;
        }).join('\n\n---\n\n');
        // ВСЕГДА ищем тикет через API
        const existingSystemTicket = await findSystemTicket(tickets);
        if (existingSystemTicket) {
            sendTicketMessage({
                ticketId: existingSystemTicket,
                message: errorMessage,
                systemError: true,
            });
        } else {
            // Создаем новый тикет для ошибки
            createTicket({
                message: errorMessage,
                useToken: true,
                systemError: true,
            });
        }
    } catch (error) {
        console.error('Error in sendErrorsToServer:', error);
    } finally {
        // Очищаем очередь ошибок
        errorsQueue = [];
    }
}

// Ищет существующий тикет с system: true
export async function findSystemTicket(tickets: Ticket[]) {
    for (const ticket of tickets) {
        console.log("[findSystemTicket] Проверяем тикет:", ticket);
        if (!('messages' in ticket)) {
            if (ticket.top_message && ticket.top_message.system === true) {
                console.log("[findSystemTicket] Найден тикет по top_message.system:true:", ticket.id);
                return ticket.id;
            }
        }
    }
}

export function clearErrorHandlingConfig () {
    clearTimeout(timeoutId);
    errorsQueue = [];
} 