{# app/modules/dev_tools/templates/dev_tools/admin/platform-debug.html #}
{% extends "admin/base.html" %}
{% from 'shared/macros/headers.html' import page_header %}
{% from 'shared/macros/tables.html' import table_wrapper, table_header, table_empty_state %}

{% block title %}Diagnostics{% endblock %}

{% block alpine_data %}platformDebug(){% endblock %}

{% block content %}
{{ page_header('Diagnostics', back_url='/admin/dashboard', back_label='Back to Dashboard') }}

<div class="flex gap-6">
    <!-- ═══════════════════════════════════════════════════════════════════ -->
    <!-- Left sidebar — Diagnostic Tools explorer                          -->
    <!-- ═══════════════════════════════════════════════════════════════════ -->
    <div class="w-72 flex-shrink-0">
        <div class="bg-white dark:bg-gray-800 rounded-lg shadow p-4">
            <div class="text-sm font-semibold text-gray-700 dark:text-gray-300 uppercase tracking-wider mb-3 flex items-center gap-1.5">
                <span x-html="$icon('cog', 'w-4 h-4')"></span>
                Diagnostic Tools
            </div>
            <template x-for="group in toolGroups" :key="group.category">
                <div class="mb-1">
                    <button @click="toggleCategory(group.category)"
                            class="flex items-center justify-between w-full text-xs font-semibold text-gray-400 dark:text-gray-500 uppercase px-2 py-1 rounded hover:text-gray-600 dark:hover:text-gray-300 transition-colors">
                        <span x-text="group.category"></span>
                        <span class="text-[10px] font-mono leading-none" x-text="isCategoryExpanded(group.category) ? '−' : '+'"></span>
                    </button>
                    <ul x-show="isCategoryExpanded(group.category)" x-collapse class="space-y-0.5 mt-0.5">
                        <template x-for="tool in group.items" :key="tool.id">
                            <li @click="selectTool(tool.id)"
                                class="flex items-center gap-1.5 rounded-md px-2 py-1.5 text-sm cursor-pointer transition-colors"
                                :class="activeTool === tool.id
                                    ? 'bg-indigo-50 dark:bg-indigo-900/30 text-indigo-700 dark:text-indigo-300'
                                    : 'text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 hover:text-gray-900 dark:hover:text-gray-200'">
                                <span x-html="$icon(tool.icon, 'w-3.5 h-3.5 flex-shrink-0')"></span>
                                <span class="truncate" x-text="tool.label"></span>
                            </li>
                        </template>
                    </ul>
                </div>
            </template>
        </div>
    </div>

    <!-- ═══════════════════════════════════════════════════════════════════ -->
    <!-- Main area — tool content panels                                   -->
    <!-- ═══════════════════════════════════════════════════════════════════ -->
    <div class="flex-1 min-w-0">

        <!-- ─────────────────────────────────────────────────────────── -->
        <!-- Tool: Platform Trace (existing functionality, verbatim)    -->
        <!-- ─────────────────────────────────────────────────────────── -->
        <div x-show="activeTool === 'platform-trace'" x-cloak>
            <div class="mb-6">
                <h2 class="text-xl font-bold text-gray-900 dark:text-white">Platform Resolution Trace</h2>
                <p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
                    Simulates the middleware pipeline for each URL pattern to trace how platform &amp; store context are resolved.
                </p>
            </div>

            <!-- Controls -->
            <div class="mb-6 p-4 bg-white dark:bg-gray-800 rounded-lg shadow-xs">
                <div class="flex items-center gap-4 flex-wrap">
                    <button @click="runAllTests()" :disabled="running"
                        class="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 disabled:opacity-50">
                        <span x-show="!running">Run All Tests</span>
                        <span x-show="running">Running...</span>
                    </button>
                    <div class="flex gap-2">
                        <button @click="filterGroup = 'all'" :class="filterGroup === 'all' ? 'bg-gray-200 dark:bg-gray-600' : ''"
                            class="px-3 py-1 text-sm rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 dark:text-gray-300">All</button>
                        <button @click="filterGroup = 'dev'" :class="filterGroup === 'dev' ? 'bg-gray-200 dark:bg-gray-600' : ''"
                            class="px-3 py-1 text-sm rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 dark:text-gray-300">Dev Path-Based</button>
                        <button @click="filterGroup = 'prod-domain'" :class="filterGroup === 'prod-domain' ? 'bg-gray-200 dark:bg-gray-600' : ''"
                            class="px-3 py-1 text-sm rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 dark:text-gray-300">Prod Domain</button>
                        <button @click="filterGroup = 'prod-subdomain'" :class="filterGroup === 'prod-subdomain' ? 'bg-gray-200 dark:bg-gray-600' : ''"
                            class="px-3 py-1 text-sm rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 dark:text-gray-300">Prod Subdomain</button>
                        <button @click="filterGroup = 'prod-custom'" :class="filterGroup === 'prod-custom' ? 'bg-gray-200 dark:bg-gray-600' : ''"
                            class="px-3 py-1 text-sm rounded-lg hover:bg-gray-100 dark:hover:bg-gray-700 dark:text-gray-300">Prod Custom Domain</button>
                    </div>
                </div>
            </div>

            <!-- Custom test -->
            <div class="mb-6 p-4 bg-white dark:bg-gray-800 rounded-lg shadow-xs">
                <h3 class="text-sm font-semibold text-gray-700 dark:text-gray-300 mb-3">Custom Test</h3>
                <div class="flex gap-3 items-end flex-wrap">
                    <div>
                        <label class="block text-xs text-gray-500 dark:text-gray-400 mb-1">Host</label>
                        <input x-model="customHost" type="text" placeholder="localhost:8000"
                            class="px-3 py-2 border rounded-lg text-sm dark:bg-gray-700 dark:border-gray-600 dark:text-white w-56">
                    </div>
                    <div>
                        <label class="block text-xs text-gray-500 dark:text-gray-400 mb-1">Path</label>
                        <input x-model="customPath" type="text" placeholder="/platforms/loyalty/store/WIZATECH/login"
                            class="px-3 py-2 border rounded-lg text-sm dark:bg-gray-700 dark:border-gray-600 dark:text-white w-80">
                    </div>
                    <div>
                        <label class="block text-xs text-gray-500 dark:text-gray-400 mb-1">Body platform_code</label>
                        <input x-model="customPlatformCode" type="text" placeholder="(optional)"
                            class="px-3 py-2 border rounded-lg text-sm dark:bg-gray-700 dark:border-gray-600 dark:text-white w-40">
                    </div>
                    <button @click="runCustomTest()" class="px-4 py-2 bg-gray-600 text-white rounded-lg hover:bg-gray-700 text-sm">
                        Trace
                    </button>
                </div>
                <!-- Custom result -->
                <template x-if="customResult">
                    <div class="mt-4">
                        <div x-html="renderTrace(customResult)"></div>
                    </div>
                </template>
            </div>

            <!-- Test Results -->
            <div class="space-y-4">
                <template x-for="test in filteredTests" :key="test.id">
                    <div class="bg-white dark:bg-gray-800 rounded-lg shadow-xs overflow-hidden">
                        <!-- Header -->
                        <div class="px-4 py-3 border-b border-gray-200 dark:border-gray-700 cursor-pointer flex items-center justify-between"
                             @click="test.expanded = !test.expanded">
                            <div class="flex items-center gap-3">
                                <!-- Status indicator -->
                                <div class="w-3 h-3 rounded-full"
                                     :class="{
                                         'bg-gray-300 dark:bg-gray-600': !test.result,
                                         'bg-green-500': test.result && test.pass,
                                         'bg-red-500': test.result && !test.pass,
                                         'animate-pulse bg-yellow-400': test.running
                                     }"></div>
                                <span class="text-xs px-2 py-0.5 rounded-full font-medium"
                                      :class="{
                                          'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300': test.group === 'dev',
                                          'bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-300': test.group === 'prod-domain',
                                          'bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-300': test.group === 'prod-subdomain',
                                          'bg-pink-100 text-pink-800 dark:bg-pink-900 dark:text-pink-300': test.group === 'prod-custom'
                                      }" x-text="test.groupLabel"></span>
                                <div>
                                    <span class="font-mono text-sm text-gray-900 dark:text-white" x-text="test.label"></span>
                                    <span class="text-xs text-gray-500 dark:text-gray-400 ml-2" x-text="test.description"></span>
                                </div>
                            </div>
                            <div class="flex items-center gap-3">
                                <template x-if="test.result">
                                    <span class="text-xs font-mono px-2 py-1 rounded"
                                          :class="test.pass ? 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300' : 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-300'"
                                          x-text="'platform=' + (test.result.login_platform_code || 'null')"></span>
                                </template>
                                <template x-if="test.result">
                                    <button @click.stop="copyTrace(test)" title="Copy full trace"
                                        class="px-2 py-1 text-xs bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-300 rounded hover:bg-gray-200 dark:hover:bg-gray-600">
                                        Copy
                                    </button>
                                </template>
                                <span x-html="$icon('chevron-down', 'w-4 h-4 text-gray-400 transition-transform ' + (test.expanded ? 'rotate-180' : ''))"></span>
                            </div>
                        </div>
                        <!-- Detail -->
                        <div x-show="test.expanded" x-cloak class="px-4 py-3">
                            <template x-if="test.result">
                                <div x-html="renderTrace(test.result)"></div>
                            </template>
                            <template x-if="!test.result && !test.running">
                                <p class="text-sm text-gray-500 dark:text-gray-400">Click "Run All Tests" to trace this case.</p>
                            </template>
                            <template x-if="test.running">
                                <p class="text-sm text-yellow-600 dark:text-yellow-400">Running...</p>
                            </template>
                        </div>
                    </div>
                </template>
            </div>
        </div>

        <!-- ─────────────────────────────────────────────────────────── -->
        <!-- Tool: Domain Health                                        -->
        <!-- ─────────────────────────────────────────────────────────── -->
        <div x-show="activeTool === 'domain-health'" x-cloak>
            <div class="mb-6">
                <h2 class="text-xl font-bold text-gray-900 dark:text-white">Domain Health</h2>
                <p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
                    Simulates the middleware resolution pipeline for every active custom subdomain and custom domain to verify they resolve to the expected store.
                </p>
            </div>

            <!-- Run button -->
            <div class="mb-6">
                <button @click="runDomainHealth()" :disabled="domainHealthLoading"
                    class="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 disabled:opacity-50 text-sm font-medium">
                    <span x-show="!domainHealthLoading">Run Health Check</span>
                    <span x-show="domainHealthLoading">Running...</span>
                </button>
                <span x-show="domainHealthError" class="ml-3 text-sm text-red-600 dark:text-red-400" x-text="domainHealthError"></span>
            </div>

            <!-- Summary bar -->
            <template x-if="domainHealthResults">
                <div class="grid grid-cols-3 gap-4 mb-6">
                    <div class="bg-white dark:bg-gray-800 rounded-lg shadow-xs p-4 text-center">
                        <div class="text-2xl font-bold text-gray-900 dark:text-white" x-text="domainHealthResults.total"></div>
                        <div class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wider mt-1">Total Checked</div>
                    </div>
                    <div class="bg-white dark:bg-gray-800 rounded-lg shadow-xs p-4 text-center border-t-2 border-green-500">
                        <div class="text-2xl font-bold text-green-600 dark:text-green-400" x-text="domainHealthResults.passed"></div>
                        <div class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wider mt-1">Passed</div>
                    </div>
                    <div class="bg-white dark:bg-gray-800 rounded-lg shadow-xs p-4 text-center border-t-2 border-red-500">
                        <div class="text-2xl font-bold text-red-600 dark:text-red-400" x-text="domainHealthResults.failed"></div>
                        <div class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wider mt-1">Failed</div>
                    </div>
                </div>
            </template>

            <!-- Results table -->
            <template x-if="domainHealthResults && domainHealthResults.details.length > 0">
                {% call table_wrapper() %}
                    {{ table_header(['Status', 'Domain', 'Type', 'Platform', 'Expected Store', 'Resolved Store', 'Note']) }}
                    <tbody class="bg-white divide-y dark:divide-gray-700 dark:bg-gray-800">
                        <template x-for="entry in domainHealthResults.details" :key="entry.domain">
                            <tr class="text-gray-700 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-700 text-sm">
                                <td class="px-4 py-2.5">
                                    <span class="text-xs px-2 py-0.5 rounded-full font-medium"
                                          :class="entry.status === 'pass'
                                              ? 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300'
                                              : 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-300'"
                                          x-text="entry.status"></span>
                                </td>
                                <td class="px-4 py-2.5 font-mono text-xs" x-text="entry.domain"></td>
                                <td class="px-4 py-2.5 text-xs">
                                    <span class="px-2 py-0.5 rounded-full font-medium"
                                          :class="entry.type === 'subdomain'
                                              ? 'bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-300'
                                              : 'bg-pink-100 text-pink-800 dark:bg-pink-900 dark:text-pink-300'"
                                          x-text="entry.type"></span>
                                </td>
                                <td class="px-4 py-2.5 text-xs font-mono" x-text="entry.platform_code || '—'"></td>
                                <td class="px-4 py-2.5 text-xs font-mono" x-text="entry.expected_store || '—'"></td>
                                <td class="px-4 py-2.5 text-xs font-mono" x-text="entry.resolved_store || '—'"></td>
                                <td class="px-4 py-2.5 text-xs text-gray-500 dark:text-gray-400" x-text="entry.note || '—'"></td>
                            </tr>
                        </template>
                    </tbody>
                {% endcall %}
            </template>

            <template x-if="domainHealthResults && domainHealthResults.details.length === 0">
                <div class="bg-white dark:bg-gray-800 rounded-lg shadow-xs p-8 text-center">
                    <span x-html="$icon('globe', 'w-12 h-12 mx-auto text-gray-300 dark:text-gray-600')"></span>
                    <p class="mt-3 text-sm text-gray-500 dark:text-gray-400">No custom subdomains or custom domains configured.</p>
                </div>
            </template>
        </div>

        <!-- ─────────────────────────────────────────────────────────── -->
        <!-- Tool: Permissions Audit                                    -->
        <!-- ─────────────────────────────────────────────────────────── -->
        <div x-show="activeTool === 'permissions-audit'" x-cloak>
            <div class="mb-6">
                <h2 class="text-xl font-bold text-gray-900 dark:text-white">Permissions Audit</h2>
                <p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
                    Introspects all registered page routes and reports which have proper auth/permission enforcement.
                </p>
            </div>

            <!-- Run Audit button -->
            <div class="mb-6">
                <button @click="runPermissionsAudit()" :disabled="auditLoading"
                    class="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 disabled:opacity-50 text-sm font-medium">
                    <span x-show="!auditLoading">Run Audit</span>
                    <span x-show="auditLoading">Running...</span>
                </button>
                <span x-show="auditError" class="ml-3 text-sm text-red-600 dark:text-red-400" x-text="auditError"></span>
            </div>

            <!-- Summary cards -->
            <template x-if="auditSummary">
                <div class="grid grid-cols-4 gap-4 mb-6">
                    <div class="bg-white dark:bg-gray-800 rounded-lg shadow-xs p-4 text-center">
                        <div class="text-2xl font-bold text-gray-900 dark:text-white" x-text="auditSummary.total"></div>
                        <div class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wider mt-1">Total Routes</div>
                    </div>
                    <div class="bg-white dark:bg-gray-800 rounded-lg shadow-xs p-4 text-center border-t-2 border-green-500">
                        <div class="text-2xl font-bold text-green-600 dark:text-green-400" x-text="auditSummary.ok"></div>
                        <div class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wider mt-1">OK</div>
                    </div>
                    <div class="bg-white dark:bg-gray-800 rounded-lg shadow-xs p-4 text-center border-t-2 border-amber-500">
                        <div class="text-2xl font-bold text-amber-600 dark:text-amber-400" x-text="auditSummary.warnings"></div>
                        <div class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wider mt-1">Warnings</div>
                    </div>
                    <div class="bg-white dark:bg-gray-800 rounded-lg shadow-xs p-4 text-center border-t-2 border-red-500">
                        <div class="text-2xl font-bold text-red-600 dark:text-red-400" x-text="auditSummary.errors"></div>
                        <div class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wider mt-1">Errors</div>
                    </div>
                </div>
            </template>

            <!-- Filter bar -->
            <template x-if="auditRoutes.length > 0">
                <div class="mb-4 flex items-center gap-4">
                    <div>
                        <label class="block text-xs text-gray-500 dark:text-gray-400 mb-1">Frontend</label>
                        <select x-model="auditFilterFrontend"
                            class="px-3 py-1.5 text-sm border rounded-lg dark:bg-gray-700 dark:border-gray-600 dark:text-white">
                            <option value="all">All</option>
                            <option value="admin">Admin</option>
                            <option value="store">Store</option>
                            <option value="merchant">Merchant</option>
                            <option value="storefront">Storefront</option>
                        </select>
                    </div>
                    <div>
                        <label class="block text-xs text-gray-500 dark:text-gray-400 mb-1">Status</label>
                        <select x-model="auditFilterStatus"
                            class="px-3 py-1.5 text-sm border rounded-lg dark:bg-gray-700 dark:border-gray-600 dark:text-white">
                            <option value="all">All</option>
                            <option value="ok">OK</option>
                            <option value="warning">Warnings</option>
                            <option value="error">Errors</option>
                        </select>
                    </div>
                    <div class="ml-auto text-sm text-gray-500 dark:text-gray-400">
                        Showing <span class="font-medium text-gray-900 dark:text-white" x-text="filteredAuditRoutes.length"></span>
                        of <span x-text="auditRoutes.length"></span> routes
                    </div>
                </div>
            </template>

            <!-- Results table -->
            <template x-if="auditRoutes.length > 0">
                {% call table_wrapper() %}
                    {{ table_header(['Status', 'Frontend', 'Path', 'Endpoint', 'Auth', 'Issue']) }}
                    <tbody class="bg-white divide-y dark:divide-gray-700 dark:bg-gray-800">
                        {{ table_empty_state(6, title='No routes match your filters', icon='shield-check', show_condition='filteredAuditRoutes.length === 0') }}
                        <template x-for="route in filteredAuditRoutes" :key="route.path + route.methods.join()">
                            <tr class="text-gray-700 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-700 text-sm">
                                <td class="px-4 py-2.5">
                                    <span class="text-xs px-2 py-0.5 rounded-full font-medium"
                                          :class="{
                                              'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300': route.status === 'ok',
                                              'bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-300': route.status === 'warning',
                                              'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-300': route.status === 'error'
                                          }" x-text="route.status"></span>
                                </td>
                                <td class="px-4 py-2.5">
                                    <span class="text-xs px-2 py-0.5 rounded-full font-medium"
                                          :class="{
                                              'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300': route.frontend === 'admin',
                                              'bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-300': route.frontend === 'store',
                                              'bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-300': route.frontend === 'merchant',
                                              'bg-pink-100 text-pink-800 dark:bg-pink-900 dark:text-pink-300': route.frontend === 'storefront',
                                              'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300': !route.frontend
                                          }" x-text="route.frontend || 'other'"></span>
                                </td>
                                <td class="px-4 py-2.5 font-mono text-xs" x-text="route.path"></td>
                                <td class="px-4 py-2.5 text-xs text-gray-500 dark:text-gray-400" x-text="route.endpoint_name"></td>
                                <td class="px-4 py-2.5 text-xs">
                                    <span x-text="route.auth_dependency || '—'" class="font-mono"></span>
                                    <template x-if="route.auth_detail">
                                        <span class="text-gray-400 dark:text-gray-500 ml-1" x-text="'(' + route.auth_detail + ')'"></span>
                                    </template>
                                </td>
                                <td class="px-4 py-2.5 text-xs text-gray-500 dark:text-gray-400" x-text="route.issue || '—'"></td>
                            </tr>
                        </template>
                    </tbody>
                {% endcall %}
            </template>
        </div>

        <!-- ─────────────────────────────────────────────────────────── -->
        <!-- Tool: Tenant Isolation Audit                               -->
        <!-- ─────────────────────────────────────────────────────────── -->
        <div x-show="activeTool === 'tenant-isolation'" x-cloak>
            <div class="mb-6">
                <h2 class="text-xl font-bold text-gray-900 dark:text-white">Tenant Isolation Audit</h2>
                <p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
                    Scans all stores and reports where configuration values come from — flagging silent inheritance, missing data, and potential data commingling.
                </p>
            </div>

            <!-- Controls -->
            <div class="mb-6 flex flex-wrap items-end gap-4">
                <button @click="runIsolationAudit()" :disabled="isolationLoading"
                    class="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 disabled:opacity-50 text-sm font-medium">
                    <span x-show="!isolationLoading">Run Audit</span>
                    <span x-show="isolationLoading">Running...</span>
                </button>
                <div>
                    <label class="block text-xs text-gray-500 dark:text-gray-400 mb-1">Filter by store</label>
                    <input type="text" x-model="isolationFilterStore" placeholder="Store code or name..."
                        class="px-3 py-1.5 text-sm border rounded-lg dark:bg-gray-700 dark:border-gray-600 dark:text-white w-48">
                </div>
                <div>
                    <label class="block text-xs text-gray-500 dark:text-gray-400 mb-1">Risk level</label>
                    <select x-model="isolationFilterRisk"
                        class="px-3 py-1.5 text-sm border rounded-lg dark:bg-gray-700 dark:border-gray-600 dark:text-white">
                        <option value="all">All</option>
                        <option value="critical">Critical</option>
                        <option value="high">High</option>
                        <option value="medium">Medium</option>
                    </select>
                </div>
                <label class="flex items-center gap-2 text-sm text-gray-600 dark:text-gray-400 cursor-pointer">
                    <input type="checkbox" x-model="isolationShowClean" class="rounded border-gray-300 dark:border-gray-600">
                    Show clean stores
                </label>
                <span x-show="isolationError" class="text-sm text-red-600 dark:text-red-400" x-text="isolationError"></span>
            </div>

            <!-- Summary cards -->
            <template x-if="isolationResults">
                <div class="grid grid-cols-3 gap-4 mb-6">
                    <div class="bg-white dark:bg-gray-800 rounded-lg shadow-xs p-4 text-center border-t-2 border-red-500">
                        <div class="text-2xl font-bold text-red-600 dark:text-red-400" x-text="isolationResults.summary.critical"></div>
                        <div class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wider mt-1">Critical</div>
                    </div>
                    <div class="bg-white dark:bg-gray-800 rounded-lg shadow-xs p-4 text-center border-t-2 border-amber-500">
                        <div class="text-2xl font-bold text-amber-600 dark:text-amber-400" x-text="isolationResults.summary.high"></div>
                        <div class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wider mt-1">High</div>
                    </div>
                    <div class="bg-white dark:bg-gray-800 rounded-lg shadow-xs p-4 text-center border-t-2 border-blue-500">
                        <div class="text-2xl font-bold text-blue-600 dark:text-blue-400" x-text="isolationResults.summary.medium"></div>
                        <div class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wider mt-1">Medium</div>
                    </div>
                </div>
            </template>

            <!-- Info bar -->
            <template x-if="isolationResults">
                <div class="mb-4 text-sm text-gray-500 dark:text-gray-400">
                    Showing <span class="font-medium text-gray-900 dark:text-white" x-text="filteredIsolationStores.length"></span>
                    of <span x-text="isolationResults.total_stores"></span> stores
                    (<span x-text="isolationResults.stores_with_findings"></span> with findings)
                </div>
            </template>

            <!-- Per-store collapsible cards -->
            <div class="space-y-3">
                <template x-for="store in filteredIsolationStores" :key="store.store_code">
                    <div class="bg-white dark:bg-gray-800 rounded-lg shadow-xs border border-gray-200 dark:border-gray-700 overflow-hidden">
                        <!-- Card header -->
                        <button @click="store._expanded = !store._expanded"
                                class="w-full flex items-center justify-between px-4 py-3 text-left hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors">
                            <div class="flex items-center gap-3">
                                <span class="font-mono text-sm font-semibold text-gray-900 dark:text-white" x-text="store.store_code"></span>
                                <span class="text-sm text-gray-500 dark:text-gray-400" x-text="store.store_name"></span>
                                <span class="text-xs text-gray-400 dark:text-gray-500" x-text="store.merchant_name ? '(' + store.merchant_name + ')' : ''"></span>
                            </div>
                            <div class="flex items-center gap-2">
                                <template x-if="store.finding_counts.critical > 0">
                                    <span class="text-xs px-2 py-0.5 rounded-full font-medium bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-300"
                                          x-text="store.finding_counts.critical + ' critical'"></span>
                                </template>
                                <template x-if="store.finding_counts.high > 0">
                                    <span class="text-xs px-2 py-0.5 rounded-full font-medium bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-300"
                                          x-text="store.finding_counts.high + ' high'"></span>
                                </template>
                                <template x-if="store.finding_counts.medium > 0">
                                    <span class="text-xs px-2 py-0.5 rounded-full font-medium bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300"
                                          x-text="store.finding_counts.medium + ' medium'"></span>
                                </template>
                                <template x-if="store.findings.length === 0">
                                    <span class="text-xs px-2 py-0.5 rounded-full font-medium bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300">clean</span>
                                </template>
                                <span class="text-[10px] font-mono text-gray-400" x-text="store._expanded ? '−' : '+'"></span>
                            </div>
                        </button>

                        <!-- Findings table (collapsed by default) -->
                        <div x-show="store._expanded" x-cloak class="border-t border-gray-200 dark:border-gray-700">
                            <template x-if="visibleFindings(store).length > 0">
                                <table class="w-full text-sm">
                                    <thead>
                                        <tr class="bg-gray-50 dark:bg-gray-900 text-xs text-gray-500 dark:text-gray-400 uppercase">
                                            <th class="px-4 py-2 text-left">Risk</th>
                                            <th class="px-4 py-2 text-left">Check</th>
                                            <th class="px-4 py-2 text-left">Value</th>
                                            <th class="px-4 py-2 text-left">Source</th>
                                            <th class="px-4 py-2 text-left">Explicit?</th>
                                            <th class="px-4 py-2 text-left">Note</th>
                                        </tr>
                                    </thead>
                                    <tbody class="divide-y divide-gray-100 dark:divide-gray-700">
                                        <template x-for="f in visibleFindings(store)" :key="f.check">
                                            <tr class="text-gray-700 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-700/50">
                                                <td class="px-4 py-2">
                                                    <span class="text-xs px-2 py-0.5 rounded-full font-medium"
                                                          :class="{
                                                              'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-300': f.risk === 'critical',
                                                              'bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-300': f.risk === 'high',
                                                              'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300': f.risk === 'medium'
                                                          }" x-text="f.risk"></span>
                                                </td>
                                                <td class="px-4 py-2 text-xs font-medium" x-text="f.check_label"></td>
                                                <td class="px-4 py-2 text-xs font-mono" x-text="f.resolved_value || '—'"></td>
                                                <td class="px-4 py-2 text-xs" x-text="f.source_label"></td>
                                                <td class="px-4 py-2 text-xs">
                                                    <span :class="f.is_explicit ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400'"
                                                          x-text="f.is_explicit ? 'Yes' : 'No'"></span>
                                                </td>
                                                <td class="px-4 py-2 text-xs text-gray-500 dark:text-gray-400" x-text="f.note || '—'"></td>
                                            </tr>
                                        </template>
                                    </tbody>
                                </table>
                            </template>
                            <template x-if="visibleFindings(store).length === 0">
                                <div class="px-4 py-6 text-center text-sm text-gray-400 dark:text-gray-500">
                                    No findings at this risk level.
                                </div>
                            </template>
                        </div>
                    </div>
                </template>
            </div>

            <!-- Empty state -->
            <template x-if="isolationResults && filteredIsolationStores.length === 0 && !isolationLoading">
                <div class="bg-white dark:bg-gray-800 rounded-lg shadow-xs p-8 text-center">
                    <span x-html="$icon('lock-closed', 'w-12 h-12 mx-auto text-gray-300 dark:text-gray-600')"></span>
                    <p class="mt-3 text-sm text-gray-500 dark:text-gray-400">No stores match your filters. Try adjusting the risk level or enabling "Show clean stores".</p>
                </div>
            </template>
        </div>

    </div>
</div>

<script>
function platformDebug() {
    return {
        // Inherit base layout functionality
        ...data(),

        // Page identifier
        currentPage: 'platform-debug',

        // ── Sidebar / tool navigation ──
        activeTool: 'platform-trace',
        expandedCategories: ['Resolution', 'Security', 'Data Integrity'],
        toolGroups: [
            {
                category: 'Resolution',
                items: [
                    { id: 'platform-trace', label: 'Platform Trace', icon: 'search' },
                    { id: 'domain-health', label: 'Domain Health', icon: 'globe' },
                ],
            },
            {
                category: 'Security',
                items: [
                    { id: 'permissions-audit', label: 'Permissions Audit', icon: 'shield-check' },
                ],
            },
            {
                category: 'Data Integrity',
                items: [
                    { id: 'tenant-isolation', label: 'Tenant Isolation', icon: 'lock-closed' },
                ],
            },
        ],

        toggleCategory(cat) {
            const idx = this.expandedCategories.indexOf(cat);
            if (idx >= 0) this.expandedCategories.splice(idx, 1);
            else this.expandedCategories.push(cat);
        },
        isCategoryExpanded(cat) {
            return this.expandedCategories.includes(cat);
        },
        selectTool(toolId) {
            this.activeTool = toolId;
        },

        // ── Platform Trace (existing) ──
        running: false,
        filterGroup: 'all',
        customHost: 'localhost:8000',
        customPath: '/platforms/loyalty/store/WIZATECH/login',
        customPlatformCode: '',
        customResult: null,
        tests: [
            // ── Dev path-based ──
            {
                id: 'dev-1', group: 'dev', groupLabel: 'Dev',
                label: '/platforms/oms/store/ACME/login',
                description: 'Store login, OMS platform context',
                host: 'localhost:8000',
                path: '/platforms/oms/store/ACME/login',
                platform_code_body: null,
                expect_platform: 'oms',
                expanded: false, result: null, pass: null, running: false,
            },
            {
                id: 'dev-2', group: 'dev', groupLabel: 'Dev',
                label: '/platforms/loyalty/store/ACME/login',
                description: 'Store login, Loyalty platform context',
                host: 'localhost:8000',
                path: '/platforms/loyalty/store/ACME/login',
                platform_code_body: null,
                expect_platform: 'loyalty',
                expanded: false, result: null, pass: null, running: false,
            },
            {
                id: 'dev-3', group: 'dev', groupLabel: 'Dev',
                label: 'API: /api/v1/store/auth/login (no body platform)',
                description: 'What middleware sees for the login API call — no platform_code in body',
                host: 'localhost:8000',
                path: '/api/v1/store/auth/login',
                platform_code_body: null,
                expect_platform: null,
                expanded: false, result: null, pass: null, running: false,
            },
            {
                id: 'dev-4', group: 'dev', groupLabel: 'Dev',
                label: 'API: /api/v1/store/auth/login + body platform_code=loyalty',
                description: 'Login API with loyalty in body (Source 2)',
                host: 'localhost:8000',
                path: '/api/v1/store/auth/login',
                platform_code_body: 'loyalty',
                store_code_body: 'WIZATECH',
                expect_platform: 'loyalty',
                expanded: false, result: null, pass: null, running: false,
            },
            {
                id: 'dev-5', group: 'dev', groupLabel: 'Dev',
                label: 'API: /api/v1/store/auth/login + body platform_code=oms',
                description: 'Login API with oms in body (Source 2)',
                host: 'localhost:8000',
                path: '/api/v1/store/auth/login',
                platform_code_body: 'oms',
                store_code_body: 'WIZATECH',
                expect_platform: 'oms',
                expanded: false, result: null, pass: null, running: false,
            },
            {
                id: 'dev-6', group: 'dev', groupLabel: 'Dev',
                label: '/store/ACME/login (no /platforms/ prefix)',
                description: 'Store login without platform prefix on localhost',
                host: 'localhost:8000',
                path: '/store/ACME/login',
                platform_code_body: null,
                expect_platform: null,
                expanded: false, result: null, pass: null, running: false,
            },
            {
                id: 'dev-7', group: 'dev', groupLabel: 'Dev',
                label: '/platforms/oms/storefront/ACME/account/login',
                description: 'Customer login, OMS platform context',
                host: 'localhost:8000',
                path: '/platforms/oms/storefront/ACME/account/login',
                platform_code_body: null,
                expect_platform: 'oms',
                expanded: false, result: null, pass: null, running: false,
            },
            {
                id: 'dev-8', group: 'dev', groupLabel: 'Dev',
                label: '/platforms/loyalty/storefront/ACME/account/login',
                description: 'Customer login, Loyalty platform context',
                host: 'localhost:8000',
                path: '/platforms/loyalty/storefront/ACME/account/login',
                platform_code_body: null,
                expect_platform: 'loyalty',
                expanded: false, result: null, pass: null, running: false,
            },

            // ── Prod domain-based (path-based demo/trial) ──
            {
                id: 'prod-d-1', group: 'prod-domain', groupLabel: 'Prod Domain',
                label: 'omsflow.lu /store/ACME/login',
                description: 'OMS platform domain, store login',
                host: 'omsflow.lu',
                path: '/store/ACME/login',
                platform_code_body: null,
                expect_platform: 'oms',
                expanded: false, result: null, pass: null, running: false,
            },
            {
                id: 'prod-d-2', group: 'prod-domain', groupLabel: 'Prod Domain',
                label: 'rewardflow.lu /store/ACME/login',
                description: 'Loyalty platform domain, store login',
                host: 'rewardflow.lu',
                path: '/store/ACME/login',
                platform_code_body: null,
                expect_platform: 'loyalty',
                expanded: false, result: null, pass: null, running: false,
            },
            {
                id: 'prod-d-3', group: 'prod-domain', groupLabel: 'Prod Domain',
                label: 'omsflow.lu /api/v1/store/auth/login (API)',
                description: 'API call on OMS domain — middleware should detect platform',
                host: 'omsflow.lu',
                path: '/api/v1/store/auth/login',
                platform_code_body: null,
                expect_platform: 'oms',
                expanded: false, result: null, pass: null, running: false,
            },
            {
                id: 'prod-d-4', group: 'prod-domain', groupLabel: 'Prod Domain',
                label: 'omsflow.lu /storefront/ACME/account/login',
                description: 'Customer login on OMS domain',
                host: 'omsflow.lu',
                path: '/storefront/ACME/account/login',
                platform_code_body: null,
                expect_platform: 'oms',
                expanded: false, result: null, pass: null, running: false,
            },

            // ── Prod subdomain ──
            {
                id: 'prod-s-1', group: 'prod-subdomain', groupLabel: 'Prod Subdomain',
                label: 'acme.omsflow.lu /store/login',
                description: 'OMS subdomain, store login',
                host: 'acme.omsflow.lu',
                path: '/store/login',
                platform_code_body: null,
                expect_platform: 'oms',
                expanded: false, result: null, pass: null, running: false,
            },
            {
                id: 'prod-s-2', group: 'prod-subdomain', groupLabel: 'Prod Subdomain',
                label: 'acme.omsflow.lu /account/login',
                description: 'OMS subdomain, customer login',
                host: 'acme.omsflow.lu',
                path: '/account/login',
                platform_code_body: null,
                expect_platform: 'oms',
                expanded: false, result: null, pass: null, running: false,
            },
            {
                id: 'prod-s-3', group: 'prod-subdomain', groupLabel: 'Prod Subdomain',
                label: 'acme-rewards.rewardflow.lu /store/login',
                description: 'Loyalty subdomain (custom_subdomain), store login',
                host: 'acme-rewards.rewardflow.lu',
                path: '/store/login',
                platform_code_body: null,
                expect_platform: 'loyalty',
                expanded: false, result: null, pass: null, running: false,
            },
            {
                id: 'prod-s-4', group: 'prod-subdomain', groupLabel: 'Prod Subdomain',
                label: 'acme.omsflow.lu /api/v1/store/auth/login (API)',
                description: 'API call on OMS subdomain',
                host: 'acme.omsflow.lu',
                path: '/api/v1/store/auth/login',
                platform_code_body: null,
                expect_platform: 'oms',
                expanded: false, result: null, pass: null, running: false,
            },

            // ── Prod custom domain ──
            {
                id: 'prod-c-1', group: 'prod-custom', groupLabel: 'Prod Custom',
                label: 'wizatech.shop /store/login',
                description: 'Custom domain → WIZATECH, OMS platform (StoreDomain.platform_id=1)',
                host: 'wizatech.shop',
                path: '/store/login',
                platform_code_body: null,
                expect_platform: 'oms',
                expanded: false, result: null, pass: null, running: false,
            },
            {
                id: 'prod-c-2', group: 'prod-custom', groupLabel: 'Prod Custom',
                label: 'fashionhub.store /store/login',
                description: 'Custom domain → FASHIONHUB, Loyalty platform (StoreDomain.platform_id=3)',
                host: 'fashionhub.store',
                path: '/store/login',
                platform_code_body: null,
                expect_platform: 'loyalty',
                expanded: false, result: null, pass: null, running: false,
            },
            {
                id: 'prod-c-3', group: 'prod-custom', groupLabel: 'Prod Custom',
                label: 'wizatech.shop /api/v1/store/auth/login (API)',
                description: 'API call on custom domain — middleware should detect platform',
                host: 'wizatech.shop',
                path: '/api/v1/store/auth/login',
                platform_code_body: null,
                expect_platform: 'oms',
                expanded: false, result: null, pass: null, running: false,
            },
            {
                id: 'prod-c-4', group: 'prod-custom', groupLabel: 'Prod Custom',
                label: 'fashionhub.store /api/v1/store/auth/login (API)',
                description: 'API call on custom domain — middleware should detect platform',
                host: 'fashionhub.store',
                path: '/api/v1/store/auth/login',
                platform_code_body: null,
                expect_platform: 'loyalty',
                expanded: false, result: null, pass: null, running: false,
            },
        ],

        get filteredTests() {
            if (this.filterGroup === 'all') return this.tests;
            return this.tests.filter(t => t.group === this.filterGroup);
        },

        async runAllTests() {
            this.running = true;
            for (const test of this.tests) {
                test.running = true;
                try {
                    test.result = await this.traceRequest(test.host, test.path, test.platform_code_body, test.store_code_body);
                    test.pass = test.expect_platform === null
                        ? true  // No expectation
                        : test.result.login_platform_code === test.expect_platform;
                } catch (e) {
                    test.result = { error: e.message };
                    test.pass = false;
                }
                test.running = false;
            }
            this.running = false;
        },

        async runCustomTest() {
            try {
                this.customResult = await this.traceRequest(
                    this.customHost, this.customPath, this.customPlatformCode || null
                );
            } catch (e) {
                this.customResult = { error: e.message };
            }
        },

        async traceRequest(host, path, platformCodeBody, storeCodeBody) {
            let url = `/api/v1/admin/debug/platform-trace?host=${encodeURIComponent(host)}&path=${encodeURIComponent(path)}`;
            if (platformCodeBody) url += `&platform_code_body=${encodeURIComponent(platformCodeBody)}`;
            if (storeCodeBody) url += `&store_code_body=${encodeURIComponent(storeCodeBody)}`;
            const resp = await apiClient.get(url.replace('/api/v1', ''));
            return resp;
        },

        copyTrace(test) {
            const r = test.result;
            if (!r || r.error) return;
            let text = `${test.label}\n${test.description}\n`;
            text += `Host: ${r.input_host}  Path: ${r.input_path}`;
            if (r.input_platform_code_body) text += `  Body platform_code: ${r.input_platform_code_body}`;
            text += '\n\n';
            for (const step of r.steps) {
                text += `${step.step}\n`;
                if (step.note) text += `${step.note}\n`;
                if (step.result) text += JSON.stringify(step.result, null, 2) + '\n';
                text += '\n';
            }
            navigator.clipboard.writeText(text);
        },

        copyStepText(step) {
            let text = `${step.step}\n`;
            if (step.note) text += `${step.note}\n`;
            if (step.result) text += JSON.stringify(step.result, null, 2);
            navigator.clipboard.writeText(text);
        },

        renderTrace(result) {
            if (result.error) {
                return `<div class="text-red-600 dark:text-red-400 text-sm font-mono">${result.error}</div>`;
            }

            let html = `<div class="text-xs font-mono space-y-1">`;
            html += `<div class="mb-2 text-gray-500 dark:text-gray-400">`;
            html += `Host: <span class="text-gray-900 dark:text-white">${result.input_host}</span> `;
            html += `Path: <span class="text-gray-900 dark:text-white">${result.input_path}</span>`;
            if (result.input_platform_code_body) {
                html += ` Body platform_code: <span class="text-gray-900 dark:text-white">${result.input_platform_code_body}</span>`;
            }
            html += `</div>`;

            for (let i = 0; i < result.steps.length; i++) {
                const step = result.steps[i];
                const isLast = step.step.startsWith('8.');
                const bgClass = isLast
                    ? 'bg-indigo-50 dark:bg-indigo-900/30 border-indigo-200 dark:border-indigo-700'
                    : 'bg-gray-50 dark:bg-gray-900 border-gray-200 dark:border-gray-700';

                html += `<div class="p-2 rounded border ${bgClass}">`;
                html += `<div class="flex items-start justify-between">`;
                html += `<div class="font-semibold text-gray-700 dark:text-gray-300">${step.step}</div>`;
                const stepData = btoa(unescape(encodeURIComponent(
                    step.step + '\n' + (step.note || '') + '\n' + (step.result ? JSON.stringify(step.result, null, 2) : '')
                )));
                html += `<button onclick="navigator.clipboard.writeText(decodeURIComponent(escape(atob(this.dataset.text))))" data-text="${stepData}" class="ml-2 shrink-0 px-1.5 py-0.5 text-[10px] bg-gray-200 dark:bg-gray-700 text-gray-500 dark:text-gray-400 rounded hover:bg-gray-300 dark:hover:bg-gray-600">Copy</button>`;
                html += `</div>`;
                if (step.note) {
                    html += `<div class="text-gray-500 dark:text-gray-400 mt-0.5">${step.note}</div>`;
                }
                if (step.result) {
                    const jsonStr = JSON.stringify(step.result, null, 2);
                    html += `<pre class="mt-1 text-green-700 dark:text-green-400 whitespace-pre-wrap">${jsonStr}</pre>`;
                }
                html += `</div>`;
            }

            html += `</div>`;

            return html;
        },

        // ── Domain Health ──
        domainHealthResults: null,
        domainHealthLoading: false,
        domainHealthError: '',

        async runDomainHealth() {
            this.domainHealthLoading = true;
            this.domainHealthError = '';
            try {
                const resp = await apiClient.get('/admin/debug/domain-health');
                this.domainHealthResults = resp;
            } catch (e) {
                this.domainHealthError = e.message || 'Failed to run health check';
            }
            this.domainHealthLoading = false;
        },

        // ── Permissions Audit ──
        auditRoutes: [],
        auditSummary: null,
        auditLoading: false,
        auditError: '',
        auditFilterFrontend: 'all',
        auditFilterStatus: 'all',

        get filteredAuditRoutes() {
            return this.auditRoutes.filter(r => {
                if (this.auditFilterFrontend !== 'all' && r.frontend !== this.auditFilterFrontend) return false;
                if (this.auditFilterStatus !== 'all' && r.status !== this.auditFilterStatus) return false;
                return true;
            });
        },

        async runPermissionsAudit() {
            this.auditLoading = true;
            this.auditError = '';
            try {
                const resp = await apiClient.get('/admin/diagnostics/permissions-audit');
                this.auditRoutes = resp.routes;
                this.auditSummary = resp.summary;
            } catch (e) {
                this.auditError = e.message || 'Failed to run audit';
            }
            this.auditLoading = false;
        },

        // ── Tenant Isolation Audit ──
        isolationResults: null,
        isolationLoading: false,
        isolationError: '',
        isolationFilterStore: '',
        isolationFilterRisk: 'all',
        isolationShowClean: false,

        get filteredIsolationStores() {
            if (!this.isolationResults) return [];
            return this.isolationResults.results.filter(store => {
                // Text filter by store_code or store_name
                if (this.isolationFilterStore) {
                    const q = this.isolationFilterStore.toLowerCase();
                    if (!store.store_code.toLowerCase().includes(q) &&
                        !store.store_name.toLowerCase().includes(q)) return false;
                }
                // Risk filter — count findings at this risk level
                if (this.isolationFilterRisk !== 'all') {
                    const hasRisk = store.findings.some(f => f.risk === this.isolationFilterRisk);
                    if (!hasRisk) return false;
                }
                // Hide clean stores unless toggled
                if (!this.isolationShowClean && store.findings.length === 0) return false;
                return true;
            });
        },

        visibleFindings(store) {
            if (this.isolationFilterRisk === 'all') return store.findings;
            return store.findings.filter(f => f.risk === this.isolationFilterRisk);
        },

        async runIsolationAudit() {
            this.isolationLoading = true;
            this.isolationError = '';
            try {
                const resp = await apiClient.get('/admin/debug/isolation-audit');
                this.isolationResults = resp;
            } catch (e) {
                this.isolationError = e.message || 'Failed to run audit';
            }
            this.isolationLoading = false;
        },
    };
}
</script>
{% endblock %}
