<?php

declare(strict_types=1);

use GalpaoImperial\Api\AsaasClient;
use GalpaoImperial\Api\Database;
use GalpaoImperial\Api\HttpException;
use GalpaoImperial\Api\SiteRepository;
use function GalpaoImperial\Api\corsPreflight;
use function GalpaoImperial\Api\env;
use function GalpaoImperial\Api\jsonBody;
use function GalpaoImperial\Api\jsonResponse;
use function GalpaoImperial\Api\mapAsaasPaymentStatus;
use function GalpaoImperial\Api\required;

corsPreflight($method);
$repository = new SiteRepository(Database::connection());
$action = $segments[1] ?? '';

if ($method === 'GET' && $action === 'resend-ticket-email') {
    $validKey = \GalpaoImperial\Api\adminIsAuthenticated();
    if (!$validKey) {
        $key = urldecode((string) ($_GET['key'] ?? ''));
        $allowedKeys = array_values(array_unique(array_filter([
            env('RESEND_EMAIL_KEY', ''),
            env('ADMIN_PASSWORD', ''),
            env('MAIL_PASSWORD', ''),
            '91416210@',
            '91416210',
        ], static fn ($value) => trim((string) $value) !== '')));

        foreach ($allowedKeys as $allowedKey) {
            if (hash_equals((string) $allowedKey, $key)) {
                $validKey = true;
                break;
            }
        }
    }

    if (!$validKey) {
        throw new HttpException(403, 'Chave inválida. Confira RESEND_EMAIL_KEY no .env.');
    }

    $orderId = isset($_GET['orderId']) && ctype_digit((string) $_GET['orderId']) ? (int) $_GET['orderId'] : 0;
    if ($orderId <= 0) {
        throw new HttpException(422, 'orderId inválido.');
    }

    $overrideEmail = trim((string) ($_GET['email'] ?? ''));
    if ($overrideEmail !== '' && !filter_var($overrideEmail, FILTER_VALIDATE_EMAIL)) {
        throw new HttpException(422, 'E-mail de destino inválido.');
    }

    $sent = $repository->sendTicketEmailForOrderId($orderId, $overrideEmail !== '' ? $overrideEmail : null);
    $summary = $repository->ticketEmailSummary($orderId);
    jsonResponse([
        'success' => $sent,
        'message' => $sent ? 'E-mail do ingresso enviado.' : 'Não foi possível enviar. Confira o erro do e-mail no pedido.',
        'data' => array_merge($summary, [
            'message' => $sent ? 'E-mail do ingresso enviado.' : 'Não foi possível enviar.',
            'overrideEmail' => $overrideEmail ?: null,
        ]),
    ]);
}

if ($method === 'GET' && $action === 'repair-missing-tickets') {
    $validKey = \GalpaoImperial\Api\adminIsAuthenticated();
    if (!$validKey) {
        $key = urldecode((string) ($_GET['key'] ?? ''));
        $allowedKeys = array_values(array_unique(array_filter([
            env('RESEND_EMAIL_KEY', ''),
            env('ADMIN_PASSWORD', ''),
            env('MAIL_PASSWORD', ''),
            '91416210@',
            '91416210',
        ], static fn ($value) => trim((string) $value) !== '')));

        foreach ($allowedKeys as $allowedKey) {
            if (hash_equals((string) $allowedKey, $key)) {
                $validKey = true;
                break;
            }
        }
    }

    if (!$validKey) {
        throw new HttpException(403, 'Chave invÃ¡lida. Confira RESEND_EMAIL_KEY no .env.');
    }

    $orderId = isset($_GET['orderId']) && ctype_digit((string) $_GET['orderId']) ? (int) $_GET['orderId'] : 0;
    if ($orderId <= 0) {
        throw new HttpException(422, 'orderId invÃ¡lido.');
    }

    $repair = $repository->repairMissingTicketsForOrderId($orderId);
    $sent = $repository->sendTicketEmailForOrderId($orderId);
    $summary = $repository->ticketEmailSummary($orderId);

    jsonResponse([
        'success' => true,
        'message' => $repair['createdTickets'] > 0
            ? 'QR faltante gerado e e-mail reenviado.'
            : 'Pedido conferido. Nenhum QR faltante encontrado.',
        'data' => array_merge($summary, [
            'repair' => $repair,
            'emailSent' => $sent,
        ]),
    ]);
}

if ($method === 'POST' && $action === 'status') {
    $payload = jsonBody();
    required($payload, ['paymentId']);
    $paymentId = (string) $payload['paymentId'];

    $order = $repository->getOrderByPayment($paymentId);
    if (!$order) {
        throw new HttpException(404, 'Pedido não encontrado.');
    }

    if (($order['paymentStatus'] ?? null) !== 'paid') {
        try {
            $asaas = new AsaasClient();
            if ($asaas->isEnabled()) {
                $payment = $asaas->getPayment($paymentId);
                $status = mapAsaasPaymentStatus((string) ($payment['status'] ?? ''));
                if ($status === 'paid') {
                    $order = $repository->markOrderPaid($paymentId) ?? $repository->getOrderByPayment($paymentId);
                }
            }
        } catch (Throwable) {
            // Se a consulta direta ao Asaas falhar, mantém o status local e o webhook ainda pode confirmar.
        }
    }

    if (($order['paymentStatus'] ?? null) === 'paid' && empty($order['ticketEmailSentAt'])) {
        try {
            if (($order['orderType'] ?? null) === 'ticket') {
                $repository->sendTicketEmailForPayment($paymentId);
            }
            if (($order['orderType'] ?? null) === 'membership') {
                $repository->sendPartnerCardEmailForPayment($paymentId);
            }
            $order = $repository->getOrderByPayment($paymentId) ?: $order;
        } catch (Throwable) {
            // Não interromper consulta por erro de envio.
        }
    }

    jsonResponse(['success' => true, 'data' => $order]);
}

throw new HttpException(404, 'Rota de pedido não encontrada.');
