{% extends "admin/change_form.html" %}
{% load i18n %}

{% block extrahead %}
    {{ block.super }}
    <script>
    (() => {
        const html = document.documentElement;
        const isDark = () => {
            const theme = html.getAttribute('data-theme');
            if (theme) return theme === 'dark';
            return matchMedia('(prefers-color-scheme: dark)').matches;
        };
        const apply = () => html.classList.toggle('dark', isDark());
        apply();
        new MutationObserver(apply).observe(html, { attributes: true, attributeFilter: ['data-theme'] });
        matchMedia('(prefers-color-scheme: dark)').addEventListener('change', apply);
    })();
    </script>
    <script src="https://cdn.tailwindcss.com"></script>
    <script>tailwind.config = { darkMode: 'class' }</script>
    <style>
        .exception-detail {
            max-width: 95%;
            margin: 0 auto;
            overflow: hidden;
        }
        .exception-detail table {
            table-layout: fixed;
            width: 100%;
        }
        .exception-detail table td {
            overflow: hidden;
            text-overflow: ellipsis;
        }
        .monaco-section {
            border-radius: 8px;
            overflow: hidden;
        }
        .editor-btn {
            padding: 4px 12px;
            font-size: 13px;
            border-radius: 8px;
            border: none;
            cursor: pointer;
            background: #f3f4f6;
            color: #4b5563;
            transition: background 0.15s;
        }
        .editor-btn:hover { background: #e5e7eb; }
        .dark .editor-btn { background: #374151; color: #d1d5db; }
        .dark .editor-btn:hover { background: #4b5563; }
        .action-btn {
            display: inline-flex;
            align-items: center;
            gap: 6px;
            padding: 6px 14px;
            font-size: 13px;
            font-weight: 500;
            border-radius: 8px;
            border: 1px solid;
            cursor: pointer;
            transition: all 0.15s;
            text-decoration: none !important;
        }
        .action-btn:disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }
        .action-btn--resolve { border-color: #16a34a; color: #16a34a; background: transparent; }
        .action-btn--resolve:hover { background: #16a34a; color: #fff; }
        .action-btn--ignore { border-color: #9ca3af; color: #6b7280; background: transparent; }
        .action-btn--ignore:hover { background: #6b7280; color: #fff; }
        .action-btn--seen { border-color: #7c3aed; color: #7c3aed; background: transparent; }
        .action-btn--seen:hover { background: #7c3aed; color: #fff; }
        .action-btn--resend { border-color: #2563eb; color: #2563eb; background: transparent; }
        .action-btn--resend:hover { background: #2563eb; color: #fff; }
        .dark .action-btn--resolve { border-color: #4ade80; color: #4ade80; }
        .dark .action-btn--resolve:hover { background: #16a34a; color: #fff; }
        .dark .action-btn--ignore { border-color: #9ca3af; color: #9ca3af; }
        .dark .action-btn--ignore:hover { background: #6b7280; color: #fff; }
        .dark .action-btn--seen { border-color: #a78bfa; color: #a78bfa; }
        .dark .action-btn--seen:hover { background: #7c3aed; color: #fff; }
        .dark .action-btn--resend { border-color: #60a5fa; color: #60a5fa; }
        .dark .action-btn--resend:hover { background: #2563eb; color: #fff; }
        .nav-btn {
            display: inline-flex;
            align-items: center;
            gap: 6px;
            padding: 8px 16px;
            font-size: 13px;
            font-weight: 500;
            border-radius: 8px;
            text-decoration: none !important;
            border: 1px solid #d1d5db;
            background: #fff;
            color: #374151 !important;
            transition: all 0.15s;
        }
        .nav-btn:hover { background: #f3f4f6; border-color: #9ca3af; }
        .nav-btn--disabled { opacity: 0.35; pointer-events: none; }
        .dark .nav-btn { background: #1f2937; border-color: #4b5563; color: #d1d5db !important; }
        .dark .nav-btn:hover { background: #374151; border-color: #6b7280; }
        .copy-tooltip {
            position: absolute;
            bottom: 100%;
            left: 50%;
            translate: -50% 0;
            margin-bottom: 6px;
            padding: 4px 10px;
            font-size: 12px;
            font-weight: 500;
            white-space: nowrap;
            border-radius: 6px;
            background: #1f2937;
            color: #fff;
            pointer-events: none;
            opacity: 0;
            transition: opacity 0.15s;
        }
        .copy-tooltip.show { opacity: 1; }
        .copy-tooltip::after {
            content: '';
            position: absolute;
            top: 100%;
            left: 50%;
            translate: -50% 0;
            border: 5px solid transparent;
            border-top-color: #1f2937;
        }
    </style>
{% endblock %}

{% block content %}
<div class="exception-detail">

    <!-- Prev / Next Navigation -->
    <div class="flex items-center justify-between mb-4">
        <a href="{% if prev_url %}{{ prev_url }}{% else %}#{% endif %}"
           class="nav-btn {% if not prev_url %}nav-btn--disabled{% endif %}">
            <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7"/></svg>
            Newer
        </a>
        <span class="text-sm text-gray-500 dark:text-gray-400">
            {{ time_ago }}
        </span>
        <a href="{% if next_url %}{{ next_url }}{% else %}#{% endif %}"
           class="nav-btn {% if not next_url %}nav-btn--disabled{% endif %}">
            Older
            <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"/></svg>
        </a>
    </div>

    <!-- Header -->
    <div class="flex flex-wrap items-center gap-3 mb-4">
        {% if original.level == "critical" or original.level == "error" %}
            <span class="inline-flex items-center justify-center w-10 h-10 rounded-full bg-red-100 dark:bg-red-900/40 text-red-600 dark:text-red-400 text-xl shrink-0">
                {% if original.level == "critical" %}&#9940;{% else %}&#128308;{% endif %}
            </span>
        {% elif original.level == "warning" %}
            <span class="inline-flex items-center justify-center w-10 h-10 rounded-full bg-yellow-100 dark:bg-yellow-900/40 text-yellow-600 dark:text-yellow-400 text-xl shrink-0">&#128993;</span>
        {% else %}
            <span class="inline-flex items-center justify-center w-10 h-10 rounded-full bg-blue-100 dark:bg-blue-900/40 text-blue-600 dark:text-blue-400 text-xl shrink-0">&#128309;</span>
        {% endif %}
        <div class="min-w-0 flex-1">
            <h2 class="text-2xl font-bold text-gray-800 dark:text-gray-100 truncate">{{ original.exception_class }}</h2>
            <p class="text-gray-500 dark:text-gray-400 text-sm">{{ original.created_at|date:"Y-m-d H:i:s" }} &middot; {{ original.environment|default:"unknown" }}</p>
        </div>
        <div class="flex flex-wrap gap-2">
            <span class="px-3 py-1 rounded-full text-xs font-semibold
                {% if original.severity == 'critical' %}bg-red-100 text-red-700 dark:bg-red-900/50 dark:text-red-300
                {% elif original.severity == 'high' %}bg-orange-100 text-orange-700 dark:bg-orange-900/50 dark:text-orange-300
                {% elif original.severity == 'moderate' %}bg-yellow-100 text-yellow-700 dark:bg-yellow-900/50 dark:text-yellow-300
                {% else %}bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-300{% endif %}">
                {{ original.severity|upper }}
            </span>
            <span id="status-badge" class="px-3 py-1 rounded-full text-xs font-semibold
                {% if original.status == 'new' %}bg-blue-100 text-blue-700 dark:bg-blue-900/50 dark:text-blue-300
                {% elif original.status == 'seen' %}bg-purple-100 text-purple-700 dark:bg-purple-900/50 dark:text-purple-300
                {% elif original.status == 'resolved' %}bg-green-100 text-green-700 dark:bg-green-900/50 dark:text-green-300
                {% else %}bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-300{% endif %}">
                {{ original.status|upper }}
            </span>
            <span id="sent-badge" class="px-3 py-1 rounded-full text-xs font-semibold
                {% if original.is_sent %}bg-green-100 text-green-700 dark:bg-green-900/50 dark:text-green-300{% else %}bg-red-100 text-red-700 dark:bg-red-900/50 dark:text-red-300{% endif %}">
                {% if original.is_sent %}Sent to Telegram{% else %}Not Sent{% endif %}
            </span>
        </div>
    </div>

    <!-- Occurrence Stats -->
    <div class="flex flex-wrap items-center gap-4 mb-4 px-1">
        <a href="../?exception_class={{ original.exception_class|urlencode }}"
           class="text-sm text-gray-500 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-400 transition"
           style="text-decoration:none">
            <span class="font-semibold text-gray-700 dark:text-gray-200">{{ occurrence_24h }}</span> in 24h
            &middot;
            <span class="font-semibold text-gray-700 dark:text-gray-200">{{ occurrence_7d }}</span> in 7d
            &middot;
            <span class="font-semibold text-gray-700 dark:text-gray-200">{{ occurrence_total }}</span> total
        </a>
    </div>

    <!-- Action Toolbar -->
    <div class="flex flex-wrap items-center gap-2 mb-6 p-3 bg-gray-50 dark:bg-gray-800/50 border border-gray-200 dark:border-gray-700 rounded-xl">
        <span class="text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide mr-1">Actions</span>
        <button class="action-btn action-btn--resolve" data-action="resolved">
            <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg>
            Resolve
        </button>
        <button class="action-btn action-btn--seen" data-action="seen">
            <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/><path stroke-linecap="round" stroke-linejoin="round" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"/></svg>
            Mark Seen
        </button>
        <button class="action-btn action-btn--ignore" data-action="ignored">
            <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728L5.636 5.636"/></svg>
            Ignore
        </button>
        <span class="w-px h-6 bg-gray-300 dark:bg-gray-600 mx-1"></span>
        <button class="action-btn action-btn--resend" data-action="resend">
            <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"/></svg>
            Resend to Telegram
        </button>
        <span id="action-feedback" class="text-sm font-medium ml-2" style="display:none"></span>
    </div>

    <!-- Error Message -->
    <div class="bg-red-50 dark:bg-red-900/30 border-l-4 border-red-400 dark:border-red-600 p-4 rounded-r-lg mb-6">
        <p class="text-red-800 dark:text-red-200 font-mono text-sm break-all">{{ original.message }}</p>
    </div>

    <!-- Grid: Request + Server Info -->
    <div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
        <div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 shadow-sm dark:shadow-gray-900/50 rounded-xl p-5">
            <h3 class="text-lg font-semibold text-gray-700 dark:text-gray-200 mb-4 flex items-center gap-2">
                <span class="text-blue-500 dark:text-blue-400">&#128463;</span> Request
            </h3>
            <table class="w-full text-sm">
                <tbody>
                    <tr class="border-b border-gray-100 dark:border-gray-700">
                        <td class="py-2 font-medium text-gray-500 dark:text-gray-400 w-1/3">Method</td>
                        <td class="py-2">
                            <span class="px-2 py-0.5 rounded text-xs font-bold
                                {% if original.method == 'GET' %}bg-green-100 text-green-700 dark:bg-green-900/50 dark:text-green-300
                                {% elif original.method == 'POST' %}bg-blue-100 text-blue-700 dark:bg-blue-900/50 dark:text-blue-300
                                {% elif original.method == 'PUT' or original.method == 'PATCH' %}bg-yellow-100 text-yellow-700 dark:bg-yellow-900/50 dark:text-yellow-300
                                {% elif original.method == 'DELETE' %}bg-red-100 text-red-700 dark:bg-red-900/50 dark:text-red-300
                                {% else %}bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-300{% endif %}">
                                {{ original.method|default:"-" }}
                            </span>
                        </td>
                    </tr>
                    <tr class="border-b border-gray-100 dark:border-gray-700">
                        <td class="py-2 font-medium text-gray-500 dark:text-gray-400">Path</td>
                        <td class="py-2 font-mono text-sm text-gray-900 dark:text-gray-100 break-all">{{ original.path|default:"-" }}</td>
                    </tr>
                    <tr class="border-b border-gray-100 dark:border-gray-700">
                        <td class="py-2 font-medium text-gray-500 dark:text-gray-400">User</td>
                        <td class="py-2 text-gray-900 dark:text-gray-100">{{ original.user_info|default:"-" }}</td>
                    </tr>
                    <tr class="border-b border-gray-100 dark:border-gray-700">
                        <td class="py-2 font-medium text-gray-500 dark:text-gray-400">IP Address</td>
                        <td class="py-2 font-mono text-gray-900 dark:text-gray-100">{{ original.ip_address|default:"-" }}</td>
                    </tr>
                    <tr>
                        <td class="py-2 font-medium text-gray-500 dark:text-gray-400">View</td>
                        <td class="py-2 font-mono text-sm text-gray-900 dark:text-gray-100 break-all">{{ original.view_name|default:"-" }}</td>
                    </tr>
                </tbody>
            </table>
        </div>

        <div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 shadow-sm dark:shadow-gray-900/50 rounded-xl p-5">
            <h3 class="text-lg font-semibold text-gray-700 dark:text-gray-200 mb-4 flex items-center gap-2">
                <span class="text-purple-500 dark:text-purple-400">&#128421;</span> Server
            </h3>
            <table class="w-full text-sm">
                <tbody>
                    <tr class="border-b border-gray-100 dark:border-gray-700">
                        <td class="py-2 font-medium text-gray-500 dark:text-gray-400 w-1/3">Hostname</td>
                        <td class="py-2 font-mono text-gray-900 dark:text-gray-100">{{ original.hostname|default:"-" }}</td>
                    </tr>
                    <tr class="border-b border-gray-100 dark:border-gray-700">
                        <td class="py-2 font-medium text-gray-500 dark:text-gray-400">Environment</td>
                        <td class="py-2">
                            <span class="px-2 py-0.5 rounded text-xs font-semibold
                                {% if original.environment == 'production' %}bg-red-100 text-red-700 dark:bg-red-900/50 dark:text-red-300
                                {% else %}bg-green-100 text-green-700 dark:bg-green-900/50 dark:text-green-300{% endif %}">
                                {{ original.environment|default:"unknown" }}
                            </span>
                        </td>
                    </tr>
                    <tr class="border-b border-gray-100 dark:border-gray-700">
                        <td class="py-2 font-medium text-gray-500 dark:text-gray-400">Level</td>
                        <td class="py-2 text-gray-900 dark:text-gray-100">{{ original.level|upper }}</td>
                    </tr>
                    <tr>
                        <td class="py-2 font-medium text-gray-500 dark:text-gray-400">Timestamp</td>
                        <td class="py-2 text-gray-900 dark:text-gray-100">{{ original.created_at|date:"Y-m-d H:i:s T" }}</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>

    <!-- Query Params -->
    {% if original.query_params %}
    <div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 shadow-sm dark:shadow-gray-900/50 rounded-xl p-5 mb-6">
        <div class="flex items-center justify-between mb-3">
            <h3 class="text-lg font-semibold text-gray-700 dark:text-gray-200">Query Parameters</h3>
            <div class="flex gap-1">
                <button id="mc-query-params-copy" class="editor-btn relative">Copy</button>
                <button id="mc-query-params-fmt" class="editor-btn relative">Format</button>
                <button id="mc-query-params-min" class="editor-btn relative">Minify</button>
            </div>
        </div>
        <div class="monaco-section" id="mc-query-params" style="height:200px;"></div>
    </div>
    {% endif %}

    <!-- Request Body -->
    {% if original.body %}
    <div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 shadow-sm dark:shadow-gray-900/50 rounded-xl p-5 mb-6">
        <div class="flex items-center justify-between mb-3">
            <h3 class="text-lg font-semibold text-gray-700 dark:text-gray-200">Request Body</h3>
            <div class="flex gap-1">
                <button id="mc-body-copy" class="editor-btn relative">Copy</button>
                <button id="mc-body-fmt" class="editor-btn relative">Format</button>
                <button id="mc-body-min" class="editor-btn relative">Minify</button>
            </div>
        </div>
        <div class="monaco-section" id="mc-body" style="height:250px;"></div>
    </div>
    {% endif %}

    <!-- Headers -->
    {% if original.headers %}
    <div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 shadow-sm dark:shadow-gray-900/50 rounded-xl p-5 mb-6">
        <div class="flex items-center justify-between mb-3">
            <h3 class="text-lg font-semibold text-gray-700 dark:text-gray-200 cursor-pointer" id="headers-toggle">
                <span id="headers-arrow">&#9660;</span> Request Headers
            </h3>
            <div class="flex gap-1">
                <button id="mc-headers-copy" class="editor-btn relative">Copy</button>
                <button id="mc-headers-fmt" class="editor-btn relative">Format</button>
                <button id="mc-headers-min" class="editor-btn relative">Minify</button>
            </div>
        </div>
        <div class="monaco-section" id="mc-headers" style="height:300px;"></div>
    </div>
    {% endif %}

    <!-- Traceback -->
    <div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 shadow-sm dark:shadow-gray-900/50 rounded-xl p-5 mb-6">
        <div class="flex items-center justify-between mb-3">
            <h3 class="text-lg font-semibold text-gray-700 dark:text-gray-200 flex items-center gap-2">
                <span class="text-red-500 dark:text-red-400">&#128027;</span> Traceback
            </h3>
            <div class="flex gap-1">
                <button id="mc-traceback-copy" class="editor-btn relative">Copy</button>
            </div>
        </div>
        <div class="monaco-section" id="mc-traceback" style="height:400px;"></div>
    </div>

    <!-- Bottom Navigation -->
    <div class="flex items-center justify-between mt-8 mb-4">
        <a href="{{ list_url }}" class="nav-btn">
            <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M10 19l-7-7m0 0l7-7m-7 7h18"/></svg>
            Back to List
        </a>
        <div class="flex gap-2">
            <a href="{% if prev_url %}{{ prev_url }}{% else %}#{% endif %}"
               class="nav-btn {% if not prev_url %}nav-btn--disabled{% endif %}">
                <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7"/></svg>
                Newer
            </a>
            <a href="{% if next_url %}{{ next_url }}{% else %}#{% endif %}"
               class="nav-btn {% if not next_url %}nav-btn--disabled{% endif %}">
                Older
                <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"/></svg>
            </a>
        </div>
    </div>
</div>

{{ original.traceback|json_script:"data-traceback" }}

<script>
(() => {
    const MONACO_CDN = 'https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs';
    const editors = {};
    const ACTION_URL = '{{ action_url }}';
    const CSRF = document.querySelector('[name=csrfmiddlewaretoken]')?.value
        || '{{ csrf_token }}';

    // --- Theme ---
    const getTheme = () => document.documentElement.classList.contains('dark') ? 'vs-dark' : 'vs';

    new MutationObserver(() => {
        if (globalThis.monaco) monaco.editor.setTheme(getTheme());
    }).observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });

    // --- Tooltip ---
    const showTooltip = (btn, text) => {
        let tip = btn.querySelector('.copy-tooltip');
        if (!tip) {
            tip = document.createElement('span');
            tip.className = 'copy-tooltip';
            btn.appendChild(tip);
        }
        tip.textContent = text;
        tip.classList.add('show');
        setTimeout(() => tip.classList.remove('show'), 1200);
    };

    // --- Action Toolbar ---
    const STATUS_STYLES = {
        new: ['bg-blue-100', 'text-blue-700', 'dark:bg-blue-900/50', 'dark:text-blue-300'],
        seen: ['bg-purple-100', 'text-purple-700', 'dark:bg-purple-900/50', 'dark:text-purple-300'],
        resolved: ['bg-green-100', 'text-green-700', 'dark:bg-green-900/50', 'dark:text-green-300'],
        ignored: ['bg-gray-100', 'text-gray-600', 'dark:bg-gray-700', 'dark:text-gray-300'],
    };

    const feedback = document.getElementById('action-feedback');
    const statusBadge = document.getElementById('status-badge');
    const sentBadge = document.getElementById('sent-badge');

    const showFeedback = (msg, ok) => {
        feedback.textContent = msg;
        feedback.style.display = '';
        feedback.style.color = ok ? '#16a34a' : '#dc2626';
        setTimeout(() => { feedback.style.display = 'none'; }, 2500);
    };

    const updateStatusBadge = (status) => {
        // Remove all status classes
        Object.values(STATUS_STYLES).flat().forEach(c => statusBadge.classList.remove(c));
        // Add new ones
        (STATUS_STYLES[status] || []).forEach(c => statusBadge.classList.add(c));
        statusBadge.textContent = status.toUpperCase();
    };

    const updateSentBadge = (sent) => {
        sentBadge.className = 'px-3 py-1 rounded-full text-xs font-semibold ' +
            (sent
                ? 'bg-green-100 text-green-700 dark:bg-green-900/50 dark:text-green-300'
                : 'bg-red-100 text-red-700 dark:bg-red-900/50 dark:text-red-300');
        sentBadge.textContent = sent ? 'Sent to Telegram' : 'Not Sent';
    };

    document.querySelectorAll('[data-action]').forEach(btn => {
        btn.addEventListener('click', async () => {
            btn.disabled = true;
            try {
                const res = await fetch(ACTION_URL, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'X-CSRFToken': CSRF,
                    },
                    body: JSON.stringify({ action: btn.dataset.action }),
                });
                const data = await res.json();
                if (data.ok) {
                    if (data.status) {
                        updateStatusBadge(data.status);
                        showFeedback(`Status: ${data.status}`, true);
                    }
                    if (data.is_sent !== undefined) {
                        updateSentBadge(data.is_sent);
                        showFeedback(data.is_sent ? 'Sent!' : 'Send failed', data.is_sent);
                    }
                } else {
                    showFeedback(data.error || 'Failed', false);
                }
            } catch (e) {
                showFeedback('Network error', false);
            }
            btn.disabled = false;
        });
    });

    // --- Monaco loader ---
    const loadMonaco = () => new Promise(resolve => {
        if (globalThis.monaco) return resolve();
        const s = document.createElement('script');
        s.src = `${MONACO_CDN}/loader.min.js`;
        s.onload = () => {
            require.config({ paths: { vs: MONACO_CDN } });
            require(['vs/editor/editor.main'], resolve);
        };
        document.head.appendChild(s);
    });

    // --- Editor factory ---
    const createEditor = (id, content, language) => {
        const el = document.getElementById(id);
        if (!el) return null;
        const editor = monaco.editor.create(el, {
            value: content,
            language,
            theme: getTheme(),
            readOnly: true,
            minimap: { enabled: false },
            fontSize: 13,
            lineNumbers: 'on',
            scrollBeyondLastLine: false,
            wordWrap: 'on',
            tabSize: 2,
            automaticLayout: true,
        });
        editors[id] = editor;
        return editor;
    };

    // --- Button wiring ---
    const bindButtons = (id) => {
        const editor = () => editors[id];

        document.getElementById(`${id}-copy`)?.addEventListener('click', (e) => {
            navigator.clipboard.writeText(editor().getValue())
                .then(() => showTooltip(e.currentTarget, 'Copied!'));
        });

        document.getElementById(`${id}-fmt`)?.addEventListener('click', (e) => {
            try {
                editor().setValue(JSON.stringify(JSON.parse(editor().getValue()), null, 2));
                showTooltip(e.currentTarget, 'Formatted!');
            } catch {}
        });

        document.getElementById(`${id}-min`)?.addEventListener('click', (e) => {
            try {
                editor().setValue(JSON.stringify(JSON.parse(editor().getValue())));
                showTooltip(e.currentTarget, 'Minified!');
            } catch {}
        });
    };

    // --- Headers toggle ---
    const toggle = document.getElementById('headers-toggle');
    const arrow = document.getElementById('headers-arrow');
    if (toggle) {
        toggle.addEventListener('click', () => {
            const section = toggle.closest('.rounded-xl').querySelector('.monaco-section');
            const hidden = section.style.display === 'none';
            section.style.display = hidden ? '' : 'none';
            arrow.textContent = hidden ? '\u25BC' : '\u25B6';
        });
    }

    // --- JSON formatter ---
    const toJson = (data) => {
        try {
            return JSON.stringify(typeof data === 'string' ? JSON.parse(data) : data, null, 2);
        } catch {
            return typeof data === 'string' ? data : JSON.stringify(data);
        }
    };

    // --- Init ---
    loadMonaco().then(() => {
        const tb = JSON.parse(document.getElementById('data-traceback').textContent);
        createEditor('mc-traceback', tb, 'python');
        bindButtons('mc-traceback');

        {% if original.query_params %}
        createEditor('mc-query-params', toJson({{ original.query_params|safe }}), 'json');
        bindButtons('mc-query-params');
        {% endif %}

        {% if original.body %}
        try {
            createEditor('mc-body', toJson({{ original.body|safe }}), 'json');
        } catch {
            createEditor('mc-body', {{ original.body|safe|default:"''" }}, 'plaintext');
        }
        bindButtons('mc-body');
        {% endif %}

        {% if original.headers %}
        createEditor('mc-headers', toJson({{ original.headers|safe }}), 'json');
        bindButtons('mc-headers');
        {% endif %}
    });
})();
</script>
{% endblock %}
