<?php
/**
 * NIS2 Agile - Email Service
 *
 * Gestione notifiche email per compliance NIS2.
 * Utilizza mail() nativa con Postfix/sendmail su server Hetzner.
 *
 * Notifiche supportate:
 * - Early warning incidenti (24h, Art. 23 NIS2)
 * - Notifica incidenti (72h)
 * - Report finale incidenti (30 giorni)
 * - Assegnazione e promemoria formazione
 * - Avvisi scadenze generiche
 * - Benvenuto registrazione
 * - Invito organizzazione
 */

class EmailService
{
    private string $defaultFrom;
    private string $appName;
    private string $appUrl;

    public function __construct()
    {
        $this->appName     = APP_NAME;
        $this->appUrl      = APP_URL;
        $this->defaultFrom = 'noreply@' . parse_url($this->appUrl, PHP_URL_HOST);
    }

    // ═══════════════════════════════════════════════════════════════════════════
    // INVIO EMAIL
    // ═══════════════════════════════════════════════════════════════════════════

    /**
     * Invia una email HTML con template professionale
     *
     * @param string      $to       Indirizzo destinatario
     * @param string      $subject  Oggetto email
     * @param string      $htmlBody Contenuto HTML (inserito nel template)
     * @param string|null $from     Indirizzo mittente (opzionale)
     * @return bool true se mail() ha accettato il messaggio
     */
    public function send(string $to, string $subject, string $htmlBody, ?string $from = null): bool
    {
        $from = $from ?? $this->defaultFrom;

        $headers = implode("\r\n", [
            'From: ' . $this->appName . ' <' . $from . '>',
            'Reply-To: ' . $from,
            'MIME-Version: 1.0',
            'Content-Type: text/html; charset=UTF-8',
            'X-Mailer: NIS2 Agile',
        ]);

        $fullHtml = $this->wrapInTemplate($subject, $htmlBody);

        $result = @mail($to, '=?UTF-8?B?' . base64_encode($subject) . '?=', $fullHtml, $headers);

        $this->logEmail($to, $subject, $result);

        return $result;
    }

    // ═══════════════════════════════════════════════════════════════════════════
    // NOTIFICHE INCIDENTI (Art. 23 NIS2)
    // ═══════════════════════════════════════════════════════════════════════════

    /**
     * Notifica early warning 24h (Art. 23 par. 4 lett. a)
     *
     * @param array $incident     Dati incidente (title, incident_code, severity, detected_at, classification)
     * @param array $organization Dati organizzazione (name, sector)
     * @param array $recipients   Lista di indirizzi email destinatari
     */
    public function sendIncidentEarlyWarning(array $incident, array $organization, array $recipients): void
    {
        $severityLabel = $this->translateSeverity($incident['severity'] ?? 'medium');
        $detectedAt    = $this->formatDateTime($incident['detected_at'] ?? '');
        $deadline      = $this->formatDateTime($incident['early_warning_due'] ?? '');

        $html = <<<HTML
        <div style="background-color: #fef2f2; border-left: 4px solid #dc2626; padding: 16px; margin-bottom: 24px; border-radius: 4px;">
            <strong style="color: #dc2626; font-size: 16px;">EARLY WARNING - Preallarme 24 ore</strong><br>
            <span style="color: #991b1b;">Ai sensi dell'Art. 23, par. 4, lett. a) della Direttiva NIS2</span>
        </div>

        <p>Si comunica che l'organizzazione <strong>{$this->esc($organization['name'])}</strong> ha rilevato un incidente significativo che richiede la notifica obbligatoria al CSIRT nazionale (ACN).</p>

        <table style="width: 100%; border-collapse: collapse; margin: 20px 0;">
            <tr style="background-color: #f8fafc;">
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600; width: 200px;">Codice Incidente</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($incident['incident_code'] ?? '-')}</td>
            </tr>
            <tr>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Titolo</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($incident['title'] ?? '-')}</td>
            </tr>
            <tr style="background-color: #f8fafc;">
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Classificazione</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($incident['classification'] ?? '-')}</td>
            </tr>
            <tr>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Gravit&agrave;</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($severityLabel)}</td>
            </tr>
            <tr style="background-color: #f8fafc;">
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Rilevato il</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($detectedAt)}</td>
            </tr>
            <tr>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Scadenza Early Warning</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; color: #dc2626; font-weight: 600;">{$this->esc($deadline)}</td>
            </tr>
        </table>

        <div style="background-color: #fffbeb; border-left: 4px solid #f59e0b; padding: 14px; margin: 20px 0; border-radius: 4px;">
            <strong>Azione richiesta:</strong> Inviare il preallarme al CSIRT nazionale (ACN) entro 24 ore dalla rilevazione dell'incidente, indicando se l'incidente sia sospettato di essere causato da atti illegittimi o malevoli e se possa avere un impatto transfrontaliero.
        </div>

        <p style="margin-top: 20px;">
            <a href="{$this->esc($this->appUrl)}/dashboard/incidents" style="display: inline-block; background-color: #1e40af; color: #ffffff; padding: 12px 24px; text-decoration: none; border-radius: 6px; font-weight: 600;">Gestisci Incidente</a>
        </p>
        HTML;

        $incidentCode = $incident['incident_code'] ?? '';
        $subject = "[URGENTE] Early Warning Incidente {$incidentCode} - {$organization['name']}";

        foreach ($recipients as $email) {
            $this->send($email, $subject, $html);
        }
    }

    /**
     * Notifica incidente 72h (Art. 23 par. 4 lett. b)
     *
     * @param array $incident     Dati incidente
     * @param array $organization Dati organizzazione
     * @param array $recipients   Lista indirizzi email
     */
    public function sendIncidentNotification(array $incident, array $organization, array $recipients): void
    {
        $severityLabel = $this->translateSeverity($incident['severity'] ?? 'medium');
        $detectedAt    = $this->formatDateTime($incident['detected_at'] ?? '');
        $deadline      = $this->formatDateTime($incident['notification_due'] ?? '');

        $html = <<<HTML
        <div style="background-color: #fff7ed; border-left: 4px solid #ea580c; padding: 16px; margin-bottom: 24px; border-radius: 4px;">
            <strong style="color: #ea580c; font-size: 16px;">NOTIFICA INCIDENTE - Termine 72 ore</strong><br>
            <span style="color: #9a3412;">Ai sensi dell'Art. 23, par. 4, lett. b) della Direttiva NIS2</span>
        </div>

        <p>Si comunica la necessit&agrave; di inviare la notifica formale dell'incidente significativo al CSIRT nazionale (ACN) per l'organizzazione <strong>{$this->esc($organization['name'])}</strong>.</p>

        <table style="width: 100%; border-collapse: collapse; margin: 20px 0;">
            <tr style="background-color: #f8fafc;">
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600; width: 200px;">Codice Incidente</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($incident['incident_code'] ?? '-')}</td>
            </tr>
            <tr>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Titolo</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($incident['title'] ?? '-')}</td>
            </tr>
            <tr style="background-color: #f8fafc;">
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Gravit&agrave;</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($severityLabel)}</td>
            </tr>
            <tr>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Rilevato il</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($detectedAt)}</td>
            </tr>
            <tr style="background-color: #f8fafc;">
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Servizi Interessati</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($incident['affected_services'] ?? 'Non specificati')}</td>
            </tr>
            <tr>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Scadenza Notifica</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; color: #ea580c; font-weight: 600;">{$this->esc($deadline)}</td>
            </tr>
        </table>

        <div style="background-color: #fffbeb; border-left: 4px solid #f59e0b; padding: 14px; margin: 20px 0; border-radius: 4px;">
            <strong>Azione richiesta:</strong> Aggiornare la notifica al CSIRT nazionale (ACN) entro 72 ore dalla rilevazione, fornendo una valutazione iniziale dell'incidente, compresa la sua gravit&agrave; e il suo impatto, nonch&eacute; gli indicatori di compromissione, ove disponibili.
        </div>

        <p style="margin-top: 20px;">
            <a href="{$this->esc($this->appUrl)}/dashboard/incidents" style="display: inline-block; background-color: #1e40af; color: #ffffff; padding: 12px 24px; text-decoration: none; border-radius: 6px; font-weight: 600;">Gestisci Incidente</a>
        </p>
        HTML;

        $incidentCode = $incident['incident_code'] ?? '';
        $subject = "[NIS2] Notifica Incidente 72h {$incidentCode} - {$organization['name']}";

        foreach ($recipients as $email) {
            $this->send($email, $subject, $html);
        }
    }

    /**
     * Notifica report finale 30 giorni (Art. 23 par. 4 lett. d)
     *
     * @param array $incident     Dati incidente
     * @param array $organization Dati organizzazione
     * @param array $recipients   Lista indirizzi email
     */
    public function sendIncidentFinalReport(array $incident, array $organization, array $recipients): void
    {
        $detectedAt = $this->formatDateTime($incident['detected_at'] ?? '');
        $deadline   = $this->formatDateTime($incident['final_report_due'] ?? '');

        $html = <<<HTML
        <div style="background-color: #eff6ff; border-left: 4px solid #1e40af; padding: 16px; margin-bottom: 24px; border-radius: 4px;">
            <strong style="color: #1e40af; font-size: 16px;">REPORT FINALE - Termine 30 giorni</strong><br>
            <span style="color: #1e3a8a;">Ai sensi dell'Art. 23, par. 4, lett. d) della Direttiva NIS2</span>
        </div>

        <p>&Egrave; necessario predisporre e trasmettere il report finale dell'incidente al CSIRT nazionale (ACN) per l'organizzazione <strong>{$this->esc($organization['name'])}</strong>.</p>

        <table style="width: 100%; border-collapse: collapse; margin: 20px 0;">
            <tr style="background-color: #f8fafc;">
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600; width: 200px;">Codice Incidente</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($incident['incident_code'] ?? '-')}</td>
            </tr>
            <tr>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Titolo</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($incident['title'] ?? '-')}</td>
            </tr>
            <tr style="background-color: #f8fafc;">
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Rilevato il</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($detectedAt)}</td>
            </tr>
            <tr>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Causa Radice</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($incident['root_cause'] ?? 'Da determinare')}</td>
            </tr>
            <tr style="background-color: #f8fafc;">
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Azioni di Rimedio</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($incident['remediation_actions'] ?? 'Da documentare')}</td>
            </tr>
            <tr>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Scadenza Report Finale</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; color: #1e40af; font-weight: 600;">{$this->esc($deadline)}</td>
            </tr>
        </table>

        <div style="background-color: #fffbeb; border-left: 4px solid #f59e0b; padding: 14px; margin: 20px 0; border-radius: 4px;">
            <strong>Azione richiesta:</strong> Predisporre il report finale entro 30 giorni dalla notifica dell'incidente, contenente: descrizione dettagliata dell'incidente, tipo di minaccia o causa radice, misure di attenuazione applicate e in corso, eventuale impatto transfrontaliero.
        </div>

        <p style="margin-top: 20px;">
            <a href="{$this->esc($this->appUrl)}/dashboard/incidents" style="display: inline-block; background-color: #1e40af; color: #ffffff; padding: 12px 24px; text-decoration: none; border-radius: 6px; font-weight: 600;">Prepara Report Finale</a>
        </p>
        HTML;

        $incidentCode = $incident['incident_code'] ?? '';
        $subject = "[NIS2] Report Finale Incidente {$incidentCode} - {$organization['name']}";

        foreach ($recipients as $email) {
            $this->send($email, $subject, $html);
        }
    }

    // ═══════════════════════════════════════════════════════════════════════════
    // NOTIFICHE FORMAZIONE (Art. 20 NIS2)
    // ═══════════════════════════════════════════════════════════════════════════

    /**
     * Notifica assegnazione corso di formazione
     *
     * @param array $assignment Dati assegnazione (due_date)
     * @param array $user       Dati utente (full_name, email)
     * @param array $course     Dati corso (title, description, duration_minutes, is_mandatory)
     */
    public function sendTrainingAssignment(array $assignment, array $user, array $course): void
    {
        $dueDate       = $this->formatDate($assignment['due_date'] ?? '');
        $duration      = (int) ($course['duration_minutes'] ?? 0);
        $mandatoryText = !empty($course['is_mandatory']) ? 'Obbligatorio' : 'Facoltativo';

        $html = <<<HTML
        <div style="background-color: #f0fdf4; border-left: 4px solid #16a34a; padding: 16px; margin-bottom: 24px; border-radius: 4px;">
            <strong style="color: #16a34a; font-size: 16px;">Nuovo corso di formazione assegnato</strong><br>
            <span style="color: #166534;">Formazione cybersecurity ai sensi dell'Art. 20 della Direttiva NIS2</span>
        </div>

        <p>Gentile <strong>{$this->esc($user['full_name'])}</strong>,</p>

        <p>Le &egrave; stato assegnato un nuovo corso di formazione sulla sicurezza informatica nell'ambito del programma di conformit&agrave; NIS2 della Sua organizzazione.</p>

        <table style="width: 100%; border-collapse: collapse; margin: 20px 0;">
            <tr style="background-color: #f8fafc;">
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600; width: 200px;">Corso</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($course['title'] ?? '-')}</td>
            </tr>
            <tr>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Descrizione</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($course['description'] ?? '-')}</td>
            </tr>
            <tr style="background-color: #f8fafc;">
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Durata Stimata</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$duration} minuti</td>
            </tr>
            <tr>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Tipo</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($mandatoryText)}</td>
            </tr>
            <tr style="background-color: #f8fafc;">
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Scadenza</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">{$this->esc($dueDate)}</td>
            </tr>
        </table>

        <p style="margin-top: 20px;">
            <a href="{$this->esc($this->appUrl)}/dashboard/training" style="display: inline-block; background-color: #16a34a; color: #ffffff; padding: 12px 24px; text-decoration: none; border-radius: 6px; font-weight: 600;">Inizia il Corso</a>
        </p>
        HTML;

        $subject = "Formazione assegnata: {$course['title']}";

        $this->send($user['email'], $subject, $html);
    }

    /**
     * Promemoria scadenza formazione
     *
     * @param array $assignment Dati assegnazione (due_date)
     * @param array $user       Dati utente (full_name, email)
     * @param array $course     Dati corso (title, is_mandatory)
     */
    public function sendTrainingReminder(array $assignment, array $user, array $course): void
    {
        $dueDate  = $this->formatDate($assignment['due_date'] ?? '');
        $daysLeft = $this->daysUntil($assignment['due_date'] ?? '');

        $urgencyColor = match (true) {
            $daysLeft <= 1  => '#dc2626',
            $daysLeft <= 3  => '#ea580c',
            $daysLeft <= 7  => '#f59e0b',
            default         => '#1e40af',
        };

        $daysText = match (true) {
            $daysLeft < 0  => 'La scadenza &egrave; stata superata',
            $daysLeft === 0 => 'La scadenza &egrave; oggi',
            $daysLeft === 1 => 'Manca 1 giorno alla scadenza',
            default         => "Mancano {$daysLeft} giorni alla scadenza",
        };

        $html = <<<HTML
        <div style="background-color: #fffbeb; border-left: 4px solid {$urgencyColor}; padding: 16px; margin-bottom: 24px; border-radius: 4px;">
            <strong style="color: {$urgencyColor}; font-size: 16px;">Promemoria Formazione</strong><br>
            <span style="color: #92400e;">{$daysText}</span>
        </div>

        <p>Gentile <strong>{$this->esc($user['full_name'])}</strong>,</p>

        <p>Le ricordiamo che il corso di formazione <strong>{$this->esc($course['title'])}</strong> deve essere completato entro il <strong>{$this->esc($dueDate)}</strong>.</p>

        <p>Il completamento della formazione sulla sicurezza informatica &egrave; un requisito previsto dall'Art. 20 della Direttiva NIS2 e dal programma di compliance della Sua organizzazione.</p>

        <p style="margin-top: 20px;">
            <a href="{$this->esc($this->appUrl)}/dashboard/training" style="display: inline-block; background-color: {$urgencyColor}; color: #ffffff; padding: 12px 24px; text-decoration: none; border-radius: 6px; font-weight: 600;">Completa il Corso</a>
        </p>
        HTML;

        $subject = "Promemoria: {$course['title']} - scadenza {$dueDate}";

        $this->send($user['email'], $subject, $html);
    }

    // ═══════════════════════════════════════════════════════════════════════════
    // AVVISI SCADENZE
    // ═══════════════════════════════════════════════════════════════════════════

    /**
     * Avviso generico di scadenza
     *
     * @param string $type       Tipo scadenza (assessment, policy_review, training, incident_report, audit, ecc.)
     * @param string $title      Titolo descrittivo della scadenza
     * @param string $dueDate    Data di scadenza (Y-m-d o Y-m-d H:i:s)
     * @param array  $recipients Lista indirizzi email
     */
    public function sendDeadlineAlert(string $type, string $title, string $dueDate, array $recipients): void
    {
        $formattedDate = $this->formatDate($dueDate);
        $daysLeft      = $this->daysUntil($dueDate);
        $typeLabel     = $this->translateDeadlineType($type);

        $urgencyColor = match (true) {
            $daysLeft <= 1  => '#dc2626',
            $daysLeft <= 3  => '#ea580c',
            $daysLeft <= 7  => '#f59e0b',
            default         => '#1e40af',
        };

        $daysText = match (true) {
            $daysLeft < 0  => 'Scadenza superata',
            $daysLeft === 0 => 'Scade oggi',
            $daysLeft === 1 => 'Scade domani',
            default         => "Scade tra {$daysLeft} giorni",
        };

        $html = <<<HTML
        <div style="background-color: #f8fafc; border-left: 4px solid {$urgencyColor}; padding: 16px; margin-bottom: 24px; border-radius: 4px;">
            <strong style="color: {$urgencyColor}; font-size: 16px;">Avviso Scadenza - {$this->esc($typeLabel)}</strong><br>
            <span style="color: #64748b;">{$daysText}</span>
        </div>

        <p>Si segnala la seguente scadenza relativa al programma di conformit&agrave; NIS2:</p>

        <table style="width: 100%; border-collapse: collapse; margin: 20px 0;">
            <tr style="background-color: #f8fafc;">
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600; width: 200px;">Tipo</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($typeLabel)}</td>
            </tr>
            <tr>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Descrizione</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($title)}</td>
            </tr>
            <tr style="background-color: #f8fafc;">
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Scadenza</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; color: {$urgencyColor}; font-weight: 600;">{$this->esc($formattedDate)}</td>
            </tr>
        </table>

        <p style="margin-top: 20px;">
            <a href="{$this->esc($this->appUrl)}/dashboard" style="display: inline-block; background-color: #1e40af; color: #ffffff; padding: 12px 24px; text-decoration: none; border-radius: 6px; font-weight: 600;">Vai alla Dashboard</a>
        </p>
        HTML;

        $subject = "[Scadenza] {$typeLabel}: {$title} - {$formattedDate}";

        foreach ($recipients as $email) {
            $this->send($email, $subject, $html);
        }
    }

    // ═══════════════════════════════════════════════════════════════════════════
    // BENVENUTO E INVITI
    // ═══════════════════════════════════════════════════════════════════════════

    /**
     * Email reset password — link con token TTL 30 min (Fase 3 / G08).
     *
     * @param array  $user        Dati utente (id, email, full_name)
     * @param string $token       Token in chiaro (versione DB è SHA-256)
     * @param int    $ttlSeconds  Durata validità link
     */
    public function sendPasswordReset(array $user, string $token, int $ttlSeconds): bool
    {
        $resetUrl  = $this->appUrl . '/reset-password.html?token=' . urlencode($token);
        $ttlMin    = (int) round($ttlSeconds / 60);
        $fullName  = $this->esc($user['full_name'] ?? $user['email']);

        $html = <<<HTML
        <div style="text-align: center; margin-bottom: 30px;">
            <div style="font-size: 48px; margin-bottom: 10px;">&#128274;</div>
            <h2 style="color: #1e40af; margin: 0;">Reimposta la tua password</h2>
        </div>

        <p>Gentile <strong>{$fullName}</strong>,</p>

        <p>Abbiamo ricevuto una richiesta di reimpostazione password per il tuo account su <strong>{$this->esc($this->appName)}</strong>. Clicca sul pulsante qui sotto per impostare una nuova password.</p>

        <p style="text-align:center; margin: 32px 0;">
            <a href="{$this->esc($resetUrl)}" style="display: inline-block; background-color: #1e40af; color: #ffffff; padding: 14px 28px; text-decoration: none; border-radius: 6px; font-weight: 600; font-size: 16px;">Reimposta password</a>
        </p>

        <p style="font-size: 13px; color: #6b7280;">Il link è valido per <strong>{$ttlMin} minuti</strong> e può essere usato una sola volta. Se non hai richiesto tu il reset, ignora questa email: la tua password attuale resta valida.</p>

        <p style="font-size: 13px; color: #6b7280; word-break: break-all;">Se il pulsante non funziona, copia questo link nel browser:<br>{$this->esc($resetUrl)}</p>
        HTML;

        return $this->send($user['email'], 'Reimposta la tua password — ' . $this->appName, $html);
    }

    /**
     * Email di benvenuto dopo la registrazione
     *
     * @param array $user Dati utente (full_name, email)
     */
    public function sendWelcome(array $user): void
    {
        $html = <<<HTML
        <div style="text-align: center; margin-bottom: 30px;">
            <div style="font-size: 48px; margin-bottom: 10px;">&#128274;</div>
            <h2 style="color: #1e40af; margin: 0;">Benvenuto in {$this->esc($this->appName)}!</h2>
        </div>

        <p>Gentile <strong>{$this->esc($user['full_name'])}</strong>,</p>

        <p>La Sua registrazione su <strong>{$this->esc($this->appName)}</strong> &egrave; stata completata con successo.</p>

        <p>{$this->esc($this->appName)} &egrave; la piattaforma per la gestione della conformit&agrave; alla Direttiva NIS2 (EU 2022/2555) e al D.Lgs. 138/2024. Con questa piattaforma potr&agrave;:</p>

        <ul style="line-height: 1.8; color: #374151;">
            <li>Effettuare la <strong>Gap Analysis</strong> rispetto ai requisiti NIS2</li>
            <li>Gestire il <strong>Risk Assessment</strong> con matrice di rischio</li>
            <li>Gestire gli <strong>incidenti di sicurezza</strong> con i flussi di notifica Art. 23</li>
            <li>Generare <strong>policy di sicurezza</strong> personalizzate</li>
            <li>Monitorare la <strong>supply chain</strong> e i fornitori critici</li>
            <li>Gestire la <strong>formazione</strong> del personale (Art. 20)</li>
            <li>Preparare <strong>audit e documentazione</strong> per le autorit&agrave;</li>
        </ul>

        <p style="margin-top: 24px;">
            <a href="{$this->esc($this->appUrl)}/dashboard" style="display: inline-block; background-color: #1e40af; color: #ffffff; padding: 14px 28px; text-decoration: none; border-radius: 6px; font-weight: 600; font-size: 16px;">Accedi alla Piattaforma</a>
        </p>

        <p style="margin-top: 24px; color: #6b7280; font-size: 14px;">Se non ha effettuato questa registrazione, pu&ograve; ignorare questa email.</p>
        HTML;

        $subject = "Benvenuto in {$this->appName}";

        $this->send($user['email'], $subject, $html);
    }

    /**
     * Invito a unirsi a un'organizzazione
     *
     * @param array  $user         Dati utente invitato (full_name, email)
     * @param array  $organization Dati organizzazione (name)
     * @param string $role         Ruolo assegnato
     */
    public function sendMemberInvite(array $user, array $organization, string $role): void
    {
        $roleLabel = $this->translateRole($role);

        $html = <<<HTML
        <div style="background-color: #eff6ff; border-left: 4px solid #1e40af; padding: 16px; margin-bottom: 24px; border-radius: 4px;">
            <strong style="color: #1e40af; font-size: 16px;">Invito a collaborare</strong><br>
            <span style="color: #1e3a8a;">{$this->esc($organization['name'])}</span>
        </div>

        <p>Gentile <strong>{$this->esc($user['full_name'])}</strong>,</p>

        <p>&Egrave; stata invitata/o a unirsi all'organizzazione <strong>{$this->esc($organization['name'])}</strong> sulla piattaforma <strong>{$this->esc($this->appName)}</strong> per la gestione della conformit&agrave; NIS2.</p>

        <table style="width: 100%; border-collapse: collapse; margin: 20px 0;">
            <tr style="background-color: #f8fafc;">
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600; width: 200px;">Organizzazione</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($organization['name'])}</td>
            </tr>
            <tr>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Ruolo Assegnato</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($roleLabel)}</td>
            </tr>
        </table>

        <p style="margin-top: 20px;">
            <a href="{$this->esc($this->appUrl)}/dashboard" style="display: inline-block; background-color: #1e40af; color: #ffffff; padding: 12px 24px; text-decoration: none; border-radius: 6px; font-weight: 600;">Accetta Invito</a>
        </p>

        <p style="margin-top: 20px; color: #6b7280; font-size: 14px;">Se non riconosce questa richiesta, pu&ograve; ignorare questa email.</p>
        HTML;

        $subject = "Invito: unisciti a {$organization['name']} su {$this->appName}";

        $this->send($user['email'], $subject, $html);
    }

    // ═══════════════════════════════════════════════════════════════════════════
    // FEEDBACK & SEGNALAZIONI
    // ═══════════════════════════════════════════════════════════════════════════

    /**
     * Broadcast risoluzione segnalazione a un membro dell'org
     *
     * @param string $to         Email destinatario
     * @param string $reportTitle Titolo breve della segnalazione
     * @param string $resolution  Testo risoluzione (nota admin o risposta AI)
     */
    public function sendFeedbackResolved(string $to, string $reportTitle, string $resolution): bool
    {
        $html = <<<HTML
        <div style="background-color: #f0fdf4; border-left: 4px solid #16a34a; padding: 16px; margin-bottom: 24px; border-radius: 4px;">
            <strong style="color: #16a34a; font-size: 16px;">&#10003; Segnalazione Risolta</strong><br>
            <span style="color: #166534;">Il problema segnalato &egrave; stato risolto</span>
        </div>

        <p>Una segnalazione nella tua organizzazione &egrave; stata risolta:</p>

        <table style="width: 100%; border-collapse: collapse; margin: 20px 0;">
            <tr style="background-color: #f8fafc;">
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600; width: 160px;">Segnalazione</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0;">{$this->esc($reportTitle)}</td>
            </tr>
            <tr>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; font-weight: 600;">Risoluzione</td>
                <td style="padding: 10px 14px; border: 1px solid #e2e8f0; line-height: 1.6;">{$this->esc($resolution)}</td>
            </tr>
        </table>

        <p style="margin-top: 20px;">
            <a href="{$this->esc($this->appUrl)}/dashboard" style="display: inline-block; background-color: #ef4444; color: #ffffff; padding: 12px 24px; text-decoration: none; border-radius: 6px; font-weight: 600;">Vai alla Dashboard</a>
        </p>
        HTML;

        $subject = "&#10003; Risolto: {$reportTitle}";

        return $this->send($to, $subject, $html);
    }

    // ═══════════════════════════════════════════════════════════════════════════
    // TEMPLATE HTML
    // ═══════════════════════════════════════════════════════════════════════════

    /**
     * Avvolge il contenuto HTML nel template email professionale
     */
    private function wrapInTemplate(string $subject, string $bodyHtml): string
    {
        $year = date('Y');

        return <<<HTML
        <!DOCTYPE html>
        <html lang="it">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>{$this->esc($subject)}</title>
        </head>
        <body style="margin: 0; padding: 0; background-color: #f1f5f9; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; -webkit-font-smoothing: antialiased;">
            <table role="presentation" cellpadding="0" cellspacing="0" width="100%" style="background-color: #f1f5f9;">
                <tr>
                    <td align="center" style="padding: 30px 15px;">
                        <table role="presentation" cellpadding="0" cellspacing="0" width="600" style="max-width: 600px; width: 100%;">

                            <!-- Header -->
                            <tr>
                                <td style="background-color: #1e40af; padding: 28px 32px; border-radius: 8px 8px 0 0; text-align: center;">
                                    <h1 style="margin: 0; color: #ffffff; font-size: 22px; font-weight: 700; letter-spacing: 0.5px;">{$this->esc($this->appName)}</h1>
                                    <p style="margin: 6px 0 0; color: #bfdbfe; font-size: 13px; font-weight: 400;">Piattaforma di Conformit&agrave; NIS2</p>
                                </td>
                            </tr>

                            <!-- Content -->
                            <tr>
                                <td style="background-color: #ffffff; padding: 32px; border-left: 1px solid #e2e8f0; border-right: 1px solid #e2e8f0; color: #1e293b; font-size: 15px; line-height: 1.6;">
                                    {$bodyHtml}
                                </td>
                            </tr>

                            <!-- Footer -->
                            <tr>
                                <td style="background-color: #f8fafc; padding: 24px 32px; border-radius: 0 0 8px 8px; border: 1px solid #e2e8f0; border-top: none;">
                                    <p style="margin: 0 0 12px; color: #64748b; font-size: 13px; line-height: 1.5; text-align: center;">
                                        Questa &egrave; una notifica automatica inviata da <strong>{$this->esc($this->appName)}</strong>.<br>
                                        Piattaforma di gestione della conformit&agrave; alla Direttiva NIS2 (EU 2022/2555).
                                    </p>
                                    <p style="margin: 0 0 12px; text-align: center;">
                                        <a href="{$this->esc($this->appUrl)}" style="color: #1e40af; text-decoration: none; font-size: 13px;">{$this->esc($this->appUrl)}</a>
                                    </p>
                                    <hr style="border: none; border-top: 1px solid #e2e8f0; margin: 16px 0;">
                                    <p style="margin: 0; color: #94a3b8; font-size: 11px; line-height: 1.5; text-align: center;">
                                        Questa email e i suoi allegati sono riservati e destinati esclusivamente ai destinatari indicati.
                                        Se ha ricevuto questa comunicazione per errore, La preghiamo di contattare il mittente e cancellare il messaggio.
                                        La informiamo che il trattamento dei dati personali avviene in conformit&agrave; al Regolamento (UE) 2016/679 (GDPR).
                                    </p>
                                    <p style="margin: 12px 0 0; color: #94a3b8; font-size: 11px; text-align: center;">
                                        &copy; {$year} {$this->esc($this->appName)} - Tutti i diritti riservati
                                    </p>
                                </td>
                            </tr>

                        </table>
                    </td>
                </tr>
            </table>
        </body>
        </html>
        HTML;
    }

    // ═══════════════════════════════════════════════════════════════════════════
    // LOGGING
    // ═══════════════════════════════════════════════════════════════════════════

    /**
     * Registra l'invio email nel database per audit
     */
    private function logEmail(string $to, string $subject, bool $success): void
    {
        try {
            Database::insert('email_log', [
                'recipient'  => $to,
                'subject'    => mb_substr($subject, 0, 255),
                'status'     => $success ? 'sent' : 'failed',
            ]);
        } catch (\Throwable $e) {
            error_log('[EmailService] Errore log email: ' . $e->getMessage());
        }
    }

    // ═══════════════════════════════════════════════════════════════════════════
    // UTILITA'
    // ═══════════════════════════════════════════════════════════════════════════

    /**
     * Escape HTML per prevenire XSS nei contenuti dinamici
     */
    private function esc(string $value): string
    {
        return htmlspecialchars($value, ENT_QUOTES | ENT_HTML5, 'UTF-8');
    }

    /**
     * Formatta data e ora in formato italiano
     */
    private function formatDateTime(string $datetime): string
    {
        if (empty($datetime)) {
            return '-';
        }

        $ts = strtotime($datetime);
        if ($ts === false) {
            return $datetime;
        }

        return date('d/m/Y H:i', $ts);
    }

    /**
     * Formatta solo la data in formato italiano
     */
    private function formatDate(string $date): string
    {
        if (empty($date)) {
            return '-';
        }

        $ts = strtotime($date);
        if ($ts === false) {
            return $date;
        }

        return date('d/m/Y', $ts);
    }

    /**
     * Calcola i giorni rimanenti fino a una data
     */
    private function daysUntil(string $date): int
    {
        if (empty($date)) {
            return 0;
        }

        $target = strtotime(date('Y-m-d', strtotime($date)));
        $today  = strtotime(date('Y-m-d'));

        if ($target === false) {
            return 0;
        }

        return (int) (($target - $today) / 86400);
    }

    /**
     * Traduce il livello di gravita' in italiano
     */
    private function translateSeverity(string $severity): string
    {
        return match ($severity) {
            'low'      => 'Bassa',
            'medium'   => 'Media',
            'high'     => 'Alta',
            'critical' => 'Critica',
            default    => ucfirst($severity),
        };
    }

    /**
     * Traduce il tipo di scadenza in italiano
     */
    private function translateDeadlineType(string $type): string
    {
        return match ($type) {
            'assessment'      => 'Gap Analysis',
            'policy_review'   => 'Revisione Policy',
            'training'        => 'Formazione',
            'incident_report' => 'Report Incidente',
            'audit'           => 'Audit',
            'risk_review'     => 'Revisione Rischi',
            'supply_chain'    => 'Valutazione Supply Chain',
            default           => ucfirst(str_replace('_', ' ', $type)),
        };
    }

    /**
     * Traduce il ruolo organizzativo in italiano
     */
    private function translateRole(string $role): string
    {
        return match ($role) {
            'org_admin'          => 'Amministratore Organizzazione',
            'compliance_manager' => 'Compliance Manager',
            'risk_manager'       => 'Risk Manager',
            'it_manager'         => 'IT Manager',
            'employee'           => 'Collaboratore',
            'auditor'            => 'Auditor',
            'viewer'             => 'Osservatore',
            default              => ucfirst(str_replace('_', ' ', $role)),
        };
    }
}
