<?php

namespace App\Domains\Notification\Services;

use App\Domains\Auth\Models\ResetPasswordAttempt;
use App\Domains\Auth\Models\User;
use App\Domains\Integration\Services\MailService;
use App\Domains\Purchase\Models\Purchase;
use App\Domains\Tenant\Models\Tenant;
use App\Domains\Ticket\Models\Ticket;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;

class NotificationMailService
{
    public function __construct(
        private readonly MailService $mailService,
    ) {}

    public function sendWelcome(int $userId, string $tenantCode): void
    {
        $tenant = Tenant::query()->where('codigo', $tenantCode)->firstOrFail();
        $user = User::query()->findOrFail($userId);

        $this->mailService
            ->forTenant($tenantCode)
            ->send(
                $user->email,
                "Bienvenido a {$tenant->nombre}",
                view('mail.notifications.welcome', compact('tenant', 'user'))->render(),
            );
    }

    public function sendPasswordResetCode(int $attemptId, string $tenantCode): void
    {
        $tenant = Tenant::query()->where('codigo', $tenantCode)->firstOrFail();
        $attempt = ResetPasswordAttempt::query()
            ->with('user')
            ->findOrFail($attemptId);

        if ($attempt->status !== ResetPasswordAttempt::STATUS_PENDING) {
            Log::warning('Password reset email was skipped because the attempt is no longer pending.', [
                'attempt_id' => $attemptId,
                'tenant_code' => $tenantCode,
                'attempt_status' => $attempt->status,
            ]);

            return;
        }

        $this->mailService
            ->forTenant($tenantCode)
            ->send(
                $attempt->user->email,
                "Código para recuperar tu contraseña - {$tenant->nombre}",
                view('mail.notifications.password-reset', compact('tenant', 'attempt'))->render(),
            );
    }

    public function sendPurchasePaid(int $purchaseId): void
    {
        $purchase = Purchase::query()
            ->with(['tenant', 'user', 'items'])
            ->findOrFail($purchaseId);

        $this->mailService
            ->forTenant($purchase->tenant_codigo)
            ->send(
                $this->recipientFor($purchase),
                "Pago confirmado - Compra #{$purchase->getKey()}",
                view('mail.notifications.purchase-paid', compact('purchase'))->render(),
            );
    }

    /** @param array<int, int> $ticketIds */
    public function sendTicketsAvailable(int $purchaseId, array $ticketIds): void
    {
        $purchase = Purchase::query()->with(['tenant', 'user'])->findOrFail($purchaseId);
        /** @var Collection<int, Ticket> $tickets */
        $tickets = Ticket::query()
            ->where('tenant_code', $purchase->tenant_codigo)
            ->where('user_id', $purchase->user_id)
            ->whereKey($ticketIds)
            ->get();

        if ($tickets->isEmpty()) {
            return;
        }

        $this->mailService
            ->forTenant($purchase->tenant_codigo)
            ->send(
                $this->recipientFor($purchase),
                'Tus tickets ya están disponibles',
                view('mail.notifications.tickets-available', compact('purchase', 'tickets'))->render(),
            );
    }

    private function recipientFor(Purchase $purchase): string
    {
        return (string) ($purchase->email ?: $purchase->user?->email);
    }
}
