<?php
namespace App\Services;

use App\Models\NexusNotification;
use App\Models\Ticket;
use App\Models\User;
use Illuminate\Mail\Message;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;

class NotificationService
{
    // ── Correos del equipo técnico (configurar en .env: SERVICEDESK_ADMIN_EMAILS) ─────
    private function getSoporteEmails(): array
    {
        $raw = env('SERVICEDESK_ADMIN_EMAILS', '');
        if (empty($raw)) return [];

        $emails = array_filter(array_map('trim', explode(',', $raw)));
        return array_map(fn($e) => ['email' => $e, 'name' => 'Soporte'], $emails);
    }

    // ── Helper: enviar email con HTML corporativo ─────────────────────────────
    private function sendMail(
        array  $to,
        string $subject,
        string $bodyHtml
    ): void {
        try {
            Mail::send([], [], function (Message $mail) use ($to, $subject, $bodyHtml) {
                $msg = $mail->subject($subject);
                foreach ($to as $recipient) {
                    $msg->to($recipient['email'], $recipient['name']);
                }
                $mail->html($this->wrapHtml($bodyHtml));
            });
        } catch (\Throwable $e) {
            Log::warning('[Service Desk Email] Falló envío: ' . $e->getMessage());
        }
    }

    // ── Helper: plantilla HTML base ───────────────────────────────────────────
    private function wrapHtml(string $content): string
    {
        $brandName = env('SERVICEDESK_BRAND_NAME', config('app.name', 'Service Desk'));
        $tagline   = env('SERVICEDESK_BRAND_TAGLINE', 'Sistema de soporte');
        $portalUrl = config('app.url', '');

        return "
        <div style='font-family:Arial,sans-serif;max-width:620px;margin:0 auto;
                    background:#f8fafc;padding:0;border-radius:12px;overflow:hidden'>
            <!-- Header -->
            <div style='background:#1d4ed8;padding:24px 32px;text-align:center'>
                <h1 style='color:#ffffff;margin:0;font-size:22px;font-weight:700;
                           letter-spacing:2px'>{$brandName}</h1>
                <p style='color:#bfdbfe;margin:4px 0 0;font-size:13px'>{$tagline}</p>
            </div>
            <!-- Body -->
            <div style='background:#ffffff;padding:32px'>
                {$content}
            </div>
            <!-- Footer -->
            <div style='background:#f1f5f9;padding:16px 32px;text-align:center'>
                <p style='color:#94a3b8;font-size:11px;margin:0'>
                    Este es un mensaje automático de {$brandName}<br>
                    Por favor no responda directamente a este correo.
                    Ingrese al portal: <a href='{$portalUrl}'
                    style='color:#1d4ed8'>{$portalUrl}</a>
                </p>
            </div>
        </div>";
    }

    // ── Helper: botón HTML ────────────────────────────────────────────────────
    private function btn(string $url, string $label): string
    {
        return "<div style='margin:24px 0'>
            <a href='{$url}'
               style='display:inline-block;background:#1d4ed8;color:#ffffff;
                      padding:12px 28px;border-radius:8px;text-decoration:none;
                      font-weight:700;font-size:14px'>{$label}</a>
        </div>";
    }

    // ── Helper: caja de datos del ticket ─────────────────────────────────────
    private function ticketBox(Ticket $ticket): string
    {
        $priority  = $ticket->priority->name  ?? '—';
        $status    = $ticket->status->name    ?? '—';
        $category  = $ticket->category->name  ?? '—';
        $requester = $ticket->requester->name ?? '—';

        return "<div style='background:#f1f5f9;border-left:4px solid #1d4ed8;
                            border-radius:0 8px 8px 0;padding:16px 20px;margin:16px 0'>
            <table style='width:100%;border-collapse:collapse;font-size:13px'>
                <tr><td style='color:#64748b;padding:3px 0;width:120px'>Número</td>
                    <td style='font-weight:700;color:#1d4ed8'>{$ticket->number}</td></tr>
                <tr><td style='color:#64748b;padding:3px 0'>Asunto</td>
                    <td style='color:#1e293b'>{$ticket->title}</td></tr>
                <tr><td style='color:#64748b;padding:3px 0'>Solicitante</td>
                    <td style='color:#1e293b'>{$requester}</td></tr>
                <tr><td style='color:#64748b;padding:3px 0'>Prioridad</td>
                    <td style='color:#1e293b'>{$priority}</td></tr>
                <tr><td style='color:#64748b;padding:3px 0'>Estado</td>
                    <td style='color:#1e293b'>{$status}</td></tr>
                <tr><td style='color:#64748b;padding:3px 0'>Categoría</td>
                    <td style='color:#1e293b'>{$category}</td></tr>
            </table>
        </div>";
    }

    // ─────────────────────────────────────────────────────────────────────────
    // [1] TICKET CREADO
    //     → Campanita: admins/jefes + agente asignado
    //     → Email: admins configurados en SERVICEDESK_ADMIN_EMAILS
    // ─────────────────────────────────────────────────────────────────────────
    public function onTicketCreated(Ticket $ticket): void
    {
        $url   = route('tickets.show', $ticket);
        $title = "Nuevo ticket {$ticket->number}";
        $body  = $ticket->title;

        // ── Campanita (sin cambios) ───────────────────────────────────────────
        User::role(['admin', 'superadmin', 'jefe_soporte'])
            ->where('id', '!=', $ticket->requester_id)
            ->get()
            ->each(fn($u) => NexusNotification::send(
                $u->id, 'ticket_created', $title, $body, $url
            ));

        if ($ticket->assignee_id && $ticket->assignee_id !== $ticket->requester_id) {
            NexusNotification::send(
                $ticket->assignee_id, 'ticket_assigned',
                "Se te asignó el ticket {$ticket->number}", $body, $url
            );
        }

        // ── Email al equipo técnico ───────────────────────────────────────────
        $requester = $ticket->requester->name ?? 'Un colaborador';
        $priority  = $ticket->priority->name  ?? '—';
        $category  = $ticket->category->name  ?? '—';
        $portalUrl = $url;

        $content = "
            <h2 style='color:#1e293b;margin:0 0 8px'>🎫 Nueva solicitud de soporte</h2>
            <p style='color:#475569;margin:0 0 16px'>
                <strong>{$requester}</strong> ha creado una nueva solicitud que requiere atención.
            </p>
            {$this->ticketBox($ticket)}
            {$this->btn($portalUrl, 'Ver y atender ticket')}
            <p style='color:#94a3b8;font-size:12px'>
                Ingresa al sistema para asignar y gestionar esta solicitud.
            </p>";

        $this->sendMail(
            $this->getSoporteEmails(),
            "🎫 Nuevo ticket {$ticket->number} — {$ticket->title}",
            $content
        );
    }

    // ─────────────────────────────────────────────────────────────────────────
    // [2] ESTADO CAMBIADO
    //     → Campanita: solicitante
    //     → Email: solicitante (ya existía, conservado y mejorado)
    // ─────────────────────────────────────────────────────────────────────────
    public function onStatusChanged(
        Ticket $ticket,
        string $oldStatus,
        string $newStatus
    ): void {
        $url = route('tickets.show', $ticket);

        // ── Campanita (sin cambios) ───────────────────────────────────────────
        NexusNotification::send(
            $ticket->requester_id,
            'ticket_status_changed',
            "Ticket {$ticket->number} actualizado",
            "Estado cambiado de '{$oldStatus}' a '{$newStatus}'",
            $url
        );

        if ($ticket->status->is_final ?? false) {
            NexusNotification::send(
                $ticket->requester_id,
                'ticket_closed',
                "Ticket {$ticket->number} resuelto",
                "Tu solicitud ha sido resuelta. ¿Puedes calificar la atención?",
                $url
            );
        }

        // ── Email al solicitante ──────────────────────────────────────────────
        $requester = $ticket->requester;
        if (!$requester || !$requester->email) return;

        $portalUrl = route('portal.show', $ticket);
        $isFinal   = $ticket->status->is_final ?? false;

        $emoji   = $isFinal ? '✅' : '🔄';
        $heading = $isFinal
            ? '¡Tu solicitud ha sido resuelta!'
            : 'Tu solicitud ha sido actualizada';

        $finalMsg = $isFinal
            ? "<p style='color:#059669;background:#d1fae5;border-radius:8px;
                         padding:12px 16px;font-size:13px'>
                  ✅ Tu solicitud fue marcada como <strong>{$newStatus}</strong>.
                  Si el problema persiste, puedes reabrir la solicitud desde el portal.
               </p>"
            : '';

        $content = "
            <h2 style='color:#1e293b;margin:0 0 8px'>{$emoji} {$heading}</h2>
            <p style='color:#475569;margin:0 0 16px'>
                Hola <strong>{$requester->name}</strong>, hay novedades sobre tu solicitud:
            </p>
            <div style='background:#f1f5f9;border-radius:8px;padding:16px;margin:16px 0'>
                <p style='margin:0;font-size:13px;color:#64748b'>Cambio de estado</p>
                <p style='margin:4px 0 0;font-size:15px;color:#1e293b'>
                    <span style='text-decoration:line-through;color:#94a3b8'>{$oldStatus}</span>
                    &nbsp;→&nbsp;
                    <strong style='color:#1d4ed8'>{$newStatus}</strong>
                </p>
            </div>
            {$this->ticketBox($ticket)}
            {$finalMsg}
            {$this->btn($portalUrl, 'Ver mi solicitud')}";

        $this->sendMail(
            [['email' => $requester->email, 'name' => $requester->name]],
            "{$emoji} Tu solicitud {$ticket->number} — {$newStatus}",
            $content
        );
    }

    // ─────────────────────────────────────────────────────────────────────────
    // [3] NUEVO COMENTARIO
    //     → Si lo hace el usuario → campanita + email al equipo técnico
    //     → Si lo hace el agente → campanita + email al solicitante
    //     → Notas internas: solo campanita al agente (sin email)
    // ─────────────────────────────────────────────────────────────────────────
    public function onComment(
        Ticket $ticket,
        int    $commenterId,
        bool   $isInternal
    ): void {
        $url       = route('tickets.show', $ticket);
        $commenter = User::find($commenterId);
        $isAgent   = $commenter?->hasAnyRole(['admin','superadmin','jefe_soporte','agente']);

        // ── Campanita ─────────────────────────────────────────────────────────
        if ($isInternal) {
            // Nota interna → solo al equipo, sin email
            User::role(['admin', 'superadmin', 'jefe_soporte'])
                ->where('id', '!=', $commenterId)
                ->get()
                ->each(fn($u) => NexusNotification::send(
                    $u->id, 'ticket_comment',
                    "Nota interna en {$ticket->number}",
                    "{$commenter->name}: {$ticket->title}",
                    $url
                ));
            return;
        }

        // Comentario público → notificar a las partes
        $notifyIds = collect([$ticket->requester_id, $ticket->assignee_id])
            ->filter()
            ->unique()
            ->reject(fn($id) => $id === $commenterId);

        foreach ($notifyIds as $uid) {
            NexusNotification::send(
                $uid, 'ticket_comment',
                "Nuevo comentario en {$ticket->number}",
                "{$commenter->name} comentó en: {$ticket->title}",
                $url
            );
        }

        // ── Email según quién comentó ─────────────────────────────────────────
        if ($isAgent) {
            // Agente comentó → email al solicitante
            $requester = $ticket->requester;
            if (!$requester || !$requester->email) return;

            $portalUrl = route('portal.show', $ticket);
            $content = "
                <h2 style='color:#1e293b;margin:0 0 8px'>💬 El equipo técnico te respondió</h2>
                <p style='color:#475569;margin:0 0 16px'>
                    Hola <strong>{$requester->name}</strong>,
                    el equipo de soporte ha agregado una respuesta a tu solicitud.
                </p>
                {$this->ticketBox($ticket)}
                {$this->btn($portalUrl, 'Ver respuesta')}
                <p style='color:#94a3b8;font-size:12px'>
                    Ingresa al portal para ver el mensaje completo y responder si es necesario.
                </p>";

            $this->sendMail(
                [['email' => $requester->email, 'name' => $requester->name]],
                "💬 Respuesta en tu solicitud {$ticket->number} " . " — " . config('app.name', 'Service Desk') . "",
                $content
            );

        } else {
            // Usuario comentó → email al equipo técnico
            $requester = $ticket->requester;
            $content = "
                <h2 style='color:#1e293b;margin:0 0 8px'>💬 El usuario respondió en un ticket</h2>
                <p style='color:#475569;margin:0 0 16px'>
                    <strong>{$commenter->name}</strong> ha agregado un comentario
                    en la solicitud <strong>{$ticket->number}</strong>.
                </p>
                {$this->ticketBox($ticket)}
                {$this->btn($url, 'Ver comentario y responder')}";

            $this->sendMail(
                $this->getSoporteEmails(),
                "💬 Respuesta del usuario en {$ticket->number} — {$ticket->title}",
                $content
            );
        }
    }

    // ─────────────────────────────────────────────────────────────────────────
    // [4] TICKET ASIGNADO
    //     → Campanita: agente asignado (sin cambios)
    //     → Email: al agente asignado
    // ─────────────────────────────────────────────────────────────────────────
    public function onAssigned(Ticket $ticket, ?int $oldAssigneeId): void
    {
        if (!$ticket->assignee_id) return;

        $url     = route('tickets.show', $ticket);
        $assignee = User::find($ticket->assignee_id);

        // ── Campanita (sin cambios) ───────────────────────────────────────────
        NexusNotification::send(
            $ticket->assignee_id,
            'ticket_assigned',
            "Se te asignó el ticket {$ticket->number}",
            $ticket->title,
            $url
        );

        // ── Email al agente ───────────────────────────────────────────────────
        if (!$assignee || !$assignee->email) return;

        $content = "
            <h2 style='color:#1e293b;margin:0 0 8px'>📋 Se te asignó una solicitud</h2>
            <p style='color:#475569;margin:0 0 16px'>
                Hola <strong>{$assignee->name}</strong>,
                se te ha asignado la siguiente solicitud de soporte:
            </p>
            {$this->ticketBox($ticket)}
            {$this->btn($url, 'Ver y gestionar ticket')}
            <p style='color:#94a3b8;font-size:12px'>
                Recuerda atender este ticket dentro del tiempo de SLA establecido.
            </p>";

        $this->sendMail(
            [['email' => $assignee->email, 'name' => $assignee->name]],
            "📋 Ticket asignado: {$ticket->number} — {$ticket->title}",
            $content
        );
    }

    // ─────────────────────────────────────────────────────────────────────────
    // [5] SLA POR VENCER
    //     → Campanita: agente + admins (sin cambios)
    //     → Email: al equipo técnico
    // ─────────────────────────────────────────────────────────────────────────
    public function onSlaWarning(Ticket $ticket): void
    {
        $url     = route('tickets.show', $ticket);
        $notify  = collect([$ticket->assignee_id])
            ->filter()
            ->merge(User::role(['admin', 'jefe_soporte'])->pluck('id'));

        // ── Campanita (sin cambios) ───────────────────────────────────────────
        foreach ($notify->unique() as $uid) {
            NexusNotification::send(
                $uid, 'sla_warning',
                "SLA por vencer — {$ticket->number}",
                "Quedan menos de 2 horas para vencer el SLA de resolución",
                $url
            );
        }

        // ── Email al equipo técnico ───────────────────────────────────────────
        $remaining = $ticket->sla_remaining ?? 'menos de 2 horas';

        $content = "
            <h2 style='color:#b45309;margin:0 0 8px'>⏰ Alerta de SLA por vencer</h2>
            <div style='background:#fef3c7;border-left:4px solid #f59e0b;
                        border-radius:0 8px 8px 0;padding:12px 16px;margin:0 0 16px'>
                <p style='margin:0;color:#92400e;font-size:13px'>
                    ⚠️ Este ticket tiene <strong>{$remaining}</strong>
                    antes de que venza el SLA de resolución.
                </p>
            </div>
            {$this->ticketBox($ticket)}
            {$this->btn($url, 'Atender ticket ahora')}";

        $this->sendMail(
            $this->getSoporteEmails(),
            "⏰ SLA por vencer — Ticket {$ticket->number}",
            $content
        );
    }
}
