import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { notFound } from 'next/navigation';
import { resolve } from '../../lib/server-container.js';
import { getFeatureFlags } from '../../lib/feature-flags.js';
import { SupervisorDashboard, } from '../../components/supervisor/supervisor-dashboard.js';
import { CreateSupervisorDialog } from '../../components/supervisor/create-supervisor-dialog.js';
import { WelcomeBanner } from '../../components/onboarding/welcome-banner.js';
/** Skip static pre-rendering — runtime DI container required. */
export const dynamic = 'force-dynamic';
export default async function SupervisorRoute() {
    const flags = getFeatureFlags();
    if (!flags.collaboration) {
        notFound();
    }
    const listPolicies = resolve('ListSupervisorPoliciesUseCase');
    const listRecent = resolve('ListRecentSupervisorDecisionsUseCase');
    const [{ policies }, recentDecisionsRaw] = await Promise.all([
        listPolicies.execute(),
        listRecent.execute({ limit: 20 }),
    ]);
    const recentDecisions = recentDecisionsRaw.map(toStreamShape);
    const names = await resolveScopeNames(policies);
    const scopeOptions = await loadScopeOptions();
    return (_jsxs("div", { className: "mx-auto flex w-full max-w-5xl flex-col gap-4 p-6", children: [_jsx(WelcomeBanner, { id: "supervisor:v1", title: "New here? Read the 2-minute supervisor walkthrough.", description: "Supervisors watch agents and decide what to approve, advise, escalate, or reject. Policies cascade from feature to repo to application to global.", ctaLabel: "Open the tutorial", ctaHref: "/onboarding#supervisors" }), _jsx("div", { className: "flex items-center justify-end", children: _jsx(CreateSupervisorDialog, { applications: scopeOptions.applications, repositories: scopeOptions.repositories, features: scopeOptions.features }) }), _jsx(SupervisorDashboard, { policies: policies, recentDecisions: recentDecisions, names: names })] }));
}
async function loadScopeOptions() {
    const apps = await safeListApplications();
    const repos = await safeListRepositories();
    const features = await safeListFeatures();
    return {
        applications: apps.map((a) => ({ id: a.id, name: a.name })),
        repositories: repos.map((r) => ({ id: r.id, name: r.name })),
        features: features.map((f) => ({
            id: f.id,
            name: f.name,
            ...(f.applicationId !== undefined && { applicationId: f.applicationId }),
            ...(f.repositoryId !== undefined && { repositoryId: f.repositoryId }),
        })),
    };
}
async function safeListApplications() {
    try {
        const repo = resolve('IApplicationRepository');
        return (await repo.list()).map((a) => ({ id: a.id, name: a.name }));
    }
    catch {
        return [];
    }
}
async function safeListRepositories() {
    try {
        const repo = resolve('IRepositoryRepository');
        return (await repo.list()).map((r) => ({ id: r.id, name: r.name }));
    }
    catch {
        return [];
    }
}
async function safeListFeatures() {
    try {
        const repo = resolve('IFeatureRepository');
        const all = await repo.list();
        return all.map((f) => ({
            id: f.id,
            name: f.name,
            ...(f.applicationId !== undefined && f.applicationId !== null
                ? { applicationId: f.applicationId }
                : {}),
            ...(f.repositoryId !== undefined && f.repositoryId !== null
                ? { repositoryId: f.repositoryId }
                : {}),
        }));
    }
    catch {
        return [];
    }
}
function toStreamShape(decision) {
    return {
        kind: 'supervisor_decision',
        decisionId: decision.id,
        scopeType: decision.scopeType,
        ...(decision.scopeId !== undefined && { scopeId: decision.scopeId }),
        ...(decision.featureId !== undefined && { featureId: decision.featureId }),
        supervisorRunId: decision.supervisorRunId,
        sourceEventKind: decision.sourceEventKind,
        sourceEventId: decision.sourceEventId,
        verdict: decision.verdict,
        rationale: decision.rationale,
        modelId: decision.modelId,
        promptVersion: decision.promptVersion,
        ...(decision.ruleRef !== undefined && { ruleRef: decision.ruleRef }),
        ...(decision.confidence !== undefined && { confidence: decision.confidence }),
        createdAt: decision.createdAt instanceof Date
            ? decision.createdAt.toISOString()
            : new Date(decision.createdAt).toISOString(),
    };
}
async function resolveScopeNames(policies) {
    const appIds = new Set();
    const repoIds = new Set();
    const featureIds = new Set();
    for (const p of policies) {
        if (p.featureId)
            featureIds.add(p.featureId);
        if (!p.scopeId)
            continue;
        if (p.scopeType === 'app')
            appIds.add(p.scopeId);
        else if (p.scopeType === 'repo')
            repoIds.add(p.scopeId);
    }
    const names = { app: {}, repo: {}, feature: {} };
    await Promise.all([
        hydrateNames(appIds, (id) => resolve('IApplicationRepository').findById(id), names.app),
        hydrateNames(repoIds, (id) => resolve('IRepositoryRepository').findById(id), names.repo),
        hydrateNames(featureIds, (id) => resolve('IFeatureRepository').findById(id), names.feature),
    ]);
    return names;
}
async function hydrateNames(ids, fetch, out) {
    await Promise.all([...ids].map(async (id) => {
        try {
            const row = await fetch(id);
            if (row?.name)
                out[id] = row.name;
        }
        catch {
            // Best-effort lookup — fall back to the raw id in the dashboard row.
        }
    }));
}
