<?php

namespace App\Services;

use App\Models\Incident;
use App\Models\MaintenanceWindow;
use App\Models\Server;

/**
 * Produces channel-appropriate message bodies for each event type.
 *
 * Each event has a few representations:
 *   - subject (one line, used for email subject / push notification title)
 *   - text   (plain text, used by SMS, WhatsApp, Telegram)
 *   - markdown (Telegram MarkdownV2-friendly with bold/code)
 *   - html   (used by email and webhook payloads)
 *   - structured (used by Discord/Slack embeds)
 *
 * The notification dispatcher picks the right one based on which channel
 * it's sending to.
 */
class NotificationTemplate
{
    public static function forIncident(Incident $i, string $kind = 'opened'): array
    {
        $sevIcon = ['critical' => '🔴', 'high' => '🟠', 'medium' => '🟡', 'low' => '🔵'][$i->severity] ?? '⚪';
        $kindLabel = match ($kind) {
            'opened' => 'opened',
            'acknowledged' => 'acknowledged',
            'resolved' => 'resolved',
            'updated' => 'updated',
            default => $kind,
        };

        $subjectLine = match ($kind) {
            'opened' => "{$sevIcon} [{$i->severity}] {$i->title}",
            'acknowledged' => "✓ Acknowledged: {$i->title}",
            'resolved' => "✅ Resolved: {$i->title}",
            'updated' => "↻ Updated: {$i->title}",
            default => $i->title,
        };

        $subjectName = $i->subject?->name ?? ($i->subject_type . '#' . $i->subject_id);

        // Plain text — short enough for SMS, readable in WhatsApp.
        $text = "{$subjectLine}\n"
              . "ID: {$i->public_id}\n"
              . "Subject: {$subjectName}\n"
              . "Detected: " . ($i->detected_at?->format('Y-m-d H:i T') ?? '-') . "\n"
              . ($kind === 'resolved' && $i->resolved_at ? "Resolved: " . $i->resolved_at->format('Y-m-d H:i T') . "\n" : '')
              . ($i->description ? "\n{$i->description}\n" : '')
              . "\nDashboard: " . url("/incidents/{$i->id}");

        // Markdown for Telegram — uses code blocks for IDs to avoid escaping pain.
        $markdown = "*{$subjectLine}*\n"
                  . "ID: `{$i->public_id}`\n"
                  . "Subject: `{$subjectName}`\n"
                  . "Severity: *" . strtoupper($i->severity) . "*\n"
                  . ($kind === 'resolved' ? "Status: *RESOLVED*\n" : '')
                  . ($i->description ? "\n" . self::escapeMarkdown($i->description) . "\n" : '')
                  . "\n[Open in dashboard](" . url("/incidents/{$i->id}") . ")";

        // Email HTML — single-table layout, dark background.
        $html = self::renderEmailHtml(
            title: $subjectLine,
            severity: $i->severity,
            rows: [
                'Incident ID' => $i->public_id,
                'Subject' => $subjectName,
                'Status' => strtoupper($i->status),
                'Severity' => strtoupper($i->severity),
                'Detected at' => $i->detected_at?->format('Y-m-d H:i:s T') ?? '-',
                'Resolved at' => $i->resolved_at?->format('Y-m-d H:i:s T') ?? null,
            ],
            description: $i->description,
            actionLabel: 'View incident',
            actionUrl: url("/incidents/{$i->id}"),
        );

        return [
            'subject' => $subjectLine,
            'text' => $text,
            'markdown' => $markdown,
            'html' => $html,
            'structured' => self::structuredForIncident($i, $kind),
        ];
    }

    public static function forMaintenance(MaintenanceWindow $w, string $kind = 'scheduled'): array
    {
        $kindLabel = ['scheduled' => '🔧 Scheduled', 'started' => '▶️ Started', 'completed' => '✅ Completed', 'cancelled' => '✕ Cancelled'][$kind] ?? $kind;
        $subject = "{$kindLabel}: {$w->title}";
        $servers = is_array($w->servers) ? implode(', ', $w->servers) : (string) $w->servers;

        $text = "{$subject}\n"
              . "Window: " . $w->starts_at->format('Y-m-d H:i') . " → " . $w->ends_at->format('Y-m-d H:i') . "\n"
              . "Impact: " . strtoupper($w->impact) . "\n"
              . "Servers: {$servers}\n"
              . ($w->notes ? "\n{$w->notes}\n" : '');

        return [
            'subject' => $subject,
            'text' => $text,
            'markdown' => "*{$subject}*\nWindow: `{$w->starts_at->format('M j H:i')}` → `{$w->ends_at->format('M j H:i')}`\nImpact: *" . strtoupper($w->impact) . "*\nServers: `{$servers}`",
            'html' => self::renderEmailHtml(
                title: $subject,
                severity: $w->impact,
                rows: [
                    'Window start' => $w->starts_at->format('Y-m-d H:i T'),
                    'Window end' => $w->ends_at->format('Y-m-d H:i T'),
                    'Type' => $w->type,
                    'Impact' => strtoupper($w->impact),
                    'Affected servers' => $servers,
                ],
                description: $w->notes,
                actionLabel: 'View maintenance window',
                actionUrl: url("/maintenance/{$w->id}"),
            ),
            'structured' => null,
        ];
    }

    /**
     * Used for Slack/Discord rich embeds. Returns a generic structured payload
     * that channel-specific senders can transform.
     */
    private static function structuredForIncident(Incident $i, string $kind): array
    {
        return [
            'title' => $i->title,
            'kind' => $kind,
            'fields' => [
                ['name' => 'Incident', 'value' => $i->public_id, 'inline' => true],
                ['name' => 'Severity', 'value' => strtoupper($i->severity), 'inline' => true],
                ['name' => 'Status', 'value' => strtoupper($i->status), 'inline' => true],
                ['name' => 'Subject', 'value' => $i->subject?->name ?? '—', 'inline' => false],
                ['name' => 'Detected', 'value' => $i->detected_at?->format('Y-m-d H:i T'), 'inline' => true],
            ],
            'url' => url("/incidents/{$i->id}"),
        ];
    }

    /**
     * Telegram MarkdownV2 reserves several characters; this helper escapes
     * just the ones that matter in user-supplied descriptions.
     */
    private static function escapeMarkdown(string $s): string
    {
        return str_replace(['_', '*', '`', '['], ['\_', '\*', '\`', '\['], $s);
    }

    private static function renderEmailHtml(string $title, string $severity, array $rows, ?string $description, string $actionLabel, string $actionUrl): string
    {
        $color = ['critical' => '#E5484D', 'high' => '#FF7849', 'medium' => '#F59E0B', 'low' => '#5B9BFF'][$severity] ?? '#94A1A8';
        $rowsHtml = '';
        foreach ($rows as $k => $v) {
            if ($v === null || $v === '') continue;
            $kEsc = htmlspecialchars((string) $k, ENT_QUOTES);
            $vEsc = htmlspecialchars((string) $v, ENT_QUOTES);
            $rowsHtml .= "<tr><td style=\"padding:6px 12px;color:#94A1A8;font-size:12px;\">{$kEsc}</td><td style=\"padding:6px 12px;color:#E6E8EA;font-size:12px;font-family:JetBrains Mono,monospace;\">{$vEsc}</td></tr>";
        }
        $descHtml = $description
            ? '<div style="margin:16px 0;padding:12px;background:#0E1419;border:1px solid #1F262C;border-radius:4px;color:#E6E8EA;font-size:13px;line-height:1.5;">' . nl2br(htmlspecialchars($description, ENT_QUOTES)) . '</div>'
            : '';

        return <<<HTML
<!doctype html>
<html><body style="margin:0;padding:0;background:#0A0E12;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Inter,sans-serif;">
<table width="100%" cellpadding="0" cellspacing="0" style="background:#0A0E12;padding:24px;">
  <tr><td align="center">
    <table width="100%" style="max-width:560px;background:#0E1419;border:1px solid #1F262C;border-radius:6px;overflow:hidden;">
      <tr>
        <td style="background:{$color};height:4px;"></td>
      </tr>
      <tr><td style="padding:20px 24px 8px;">
        <div style="font-size:11px;color:#94A1A8;letter-spacing:0.05em;text-transform:uppercase;margin-bottom:6px;">HostSeba NOC</div>
        <div style="font-size:18px;color:#E6E8EA;font-weight:600;">{$title}</div>
      </td></tr>
      {$descHtml}
      <tr><td style="padding:0 12px 12px;">
        <table width="100%" cellpadding="0" cellspacing="0">{$rowsHtml}</table>
      </td></tr>
      <tr><td style="padding:16px 24px 24px;border-top:1px solid #1F262C;">
        <a href="{$actionUrl}" style="display:inline-block;background:#1CC0D6;color:#0A0E12;padding:8px 14px;border-radius:4px;text-decoration:none;font-size:12px;font-weight:600;">{$actionLabel} &rarr;</a>
      </td></tr>
    </table>
    <div style="margin-top:16px;font-size:10px;color:#5C6770;">Sent by HostSeba NOC · You're receiving this because you're configured for incident notifications.</div>
  </td></tr>
</table>
</body></html>
HTML;
    }
}
