"use client";
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import Markdown from "react-markdown";
import { cn } from "@stigmer/theme";
import { timestampDate } from "@bufbuild/protobuf/wkt";
import { SkillState } from "@stigmer/protos/ai/stigmer/agentic/skill/v1/status_pb";
import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
import { useSkill } from "./useSkill";
import { SkillFileBrowser } from "./SkillFileBrowser";
import { ErrorMessage } from "../error/ErrorMessage";
import { VisibilityToggle } from "../library/VisibilityToggle";
import { PermissionGate } from "../iam-policy/PermissionGate";
import { MARKDOWN_COMPONENTS, REMARK_PLUGINS, stripFrontmatter } from "../internal/markdown-components";
import { ResourceDetailShell } from "../resource-detail/ResourceDetailShell";
import { Section } from "../resource-detail/Section";
import { useDetailTabs } from "../resource-detail/useDetailTabs";
import { InlineEditText } from "../inline-edit/InlineEditText";
import { InlineEditTextarea } from "../inline-edit/InlineEditTextarea";
import { useSkillVersions } from "./useSkillVersions";
import { VersionTimeline } from "../version-history/VersionTimeline";
import { SkillDiffDialog } from "./SkillDiffDialog";
const CONTENT_TAB = { id: "content", label: "Content" };
const VERSIONS_TAB = { id: "versions", label: "Versions" };
/**
 * Operational detail hub for a Skill knowledge package.
 *
 * Fetches the skill via {@link useSkill} internally and renders its
 * content inside a {@link ResourceDetailShell}: a standardized header
 * with action bar, the SKILL.md content with a source/rendered toggle,
 * and version/provenance information.
 *
 * The SKILL.md content is the primary value of this view — it IS the
 * skill. Users can toggle between rendered markdown and raw source
 * (like GitHub's Preview/Code toggle).
 *
 * Handles loading, error, and not-found states automatically.
 * Zero Console dependencies — safe for platform builder embedding.
 * All visual properties flow through `--stgm-*` design tokens.
 *
 * @example
 * ```tsx
 * // Minimal — self-contained, fetches its own data
 * <SkillDetailView org="acme" slug="code-style-guide" />
 * ```
 *
 * @example
 * ```tsx
 * // Pinned to a specific version tag
 * <SkillDetailView org="acme" slug="code-style-guide" version="stable" />
 * ```
 */
export function SkillDetailView({ org, slug, version, onResourceLoad, onVisibilityChange, isVisibilityPending, primaryAction, actions, additionalTabs, activeTab, onTabChange, defaultTab, onVersionSelect, editable = false, onResourceUpdated, className, }) {
    const { skill, isLoading, error, refetch } = useSkill(org, slug, version);
    const { versions, isEmpty: noVersions, getArtifactKey } = useSkillVersions(org, slug);
    const [diffState, setDiffState] = useState(null);
    const builtInTabs = useMemo(() => (noVersions ? [CONTENT_TAB] : [CONTENT_TAB, VERSIONS_TAB]), [noVersions]);
    const { effectiveTabs, effectiveActiveTab, effectiveOnTabChange, activeAdditionalTab, } = useDetailTabs({
        builtInTabs,
        additionalTabs,
        activeTab,
        onTabChange,
        defaultTab,
    });
    const handleVersionSelect = useCallback((id) => onVersionSelect?.(id), [onVersionSelect]);
    const handleCompare = useCallback((fromId, toId) => {
        const fromKey = getArtifactKey(fromId);
        const toKey = getArtifactKey(toId);
        if (!fromKey || !toKey)
            return;
        setDiffState({
            fromArtifactKey: fromKey,
            toArtifactKey: toKey,
            fromLabel: fromId.slice(0, 12),
            toLabel: toId.slice(0, 12),
        });
    }, [getArtifactKey]);
    const closeDiff = useCallback(() => setDiffState(null), []);
    const onResourceLoadRef = useRef(onResourceLoad);
    onResourceLoadRef.current = onResourceLoad;
    useEffect(() => {
        if (skill?.metadata?.name) {
            onResourceLoadRef.current?.({ name: skill.metadata.name, id: skill.metadata.id });
        }
    }, [skill]);
    if (isLoading)
        return _jsx(LoadingSkeleton, { className: className });
    if (error)
        return _jsx(ErrorMessage, { error: error, retry: refetch, className: className });
    if (!skill)
        return _jsx(NotFoundState, { className: className });
    const meta = skill.metadata;
    const spec = skill.spec;
    const status = skill.status;
    const specAudit = status?.audit?.specAudit;
    const headerMeta = {
        name: meta?.name || meta?.slug || "Untitled",
        id: meta?.id || "",
        org: meta?.org,
        slug: meta?.slug,
        description: undefined,
        icon: _jsx(SkillIcon, { className: "size-6 text-muted-foreground" }),
        createdAt: specAudit?.createdAt ? timestampDate(specAudit.createdAt) : null,
        updatedAt: specAudit?.updatedAt ? timestampDate(specAudit.updatedAt) : null,
        status: status ? skillStateToPhase(status.state) : undefined,
        statusLabel: status ? skillStateLabel(status.state) : undefined,
    };
    const visibilityBadge = meta?.visibility === ApiResourceVisibility.visibility_public ? (_jsx("span", { className: "shrink-0 rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground", children: "Public" })) : undefined;
    const visibilityControl = onVisibilityChange && meta ? (_jsx(PermissionGate, { resource: { kind: "skill", id: meta.id }, relation: "can_edit", fallback: visibilityBadge, children: _jsx(VisibilityToggle, { visibility: meta.visibility, onVisibilityChange: onVisibilityChange, isPending: isVisibilityPending }) })) : visibilityBadge;
    let tabContent;
    if (activeAdditionalTab) {
        tabContent = activeAdditionalTab.content;
    }
    else if (effectiveActiveTab === "versions" && versions.length > 0) {
        tabContent = (_jsx(VersionTimeline, { entries: versions, onEntrySelect: handleVersionSelect, onCompare: handleCompare }));
    }
    else {
        tabContent = (_jsx(SkillOverview, { spec: spec, status: status, editable: editable }));
    }
    return (_jsxs(_Fragment, { children: [_jsx(ResourceDetailShell, { header: headerMeta, visibilityControl: visibilityControl, primaryAction: primaryAction, actions: actions, tabs: effectiveTabs, activeTab: effectiveTabs ? effectiveActiveTab : undefined, onTabChange: effectiveTabs ? effectiveOnTabChange : undefined, tabsAriaLabel: "Skill detail sections", className: className, children: tabContent }), _jsx(SkillDiffDialog, { state: diffState, onClose: closeDiff })] }));
}
// ---------------------------------------------------------------------------
// Overview content — the skill's built-in "Content" tab
// ---------------------------------------------------------------------------
function SkillOverview({ spec, status, editable, }) {
    return (_jsxs("div", { className: "flex flex-col gap-6", children: [(editable || spec?.description) && (_jsx(Section, { title: "Description", children: editable ? (_jsx("div", { className: "max-h-20 overflow-y-auto p-3", children: _jsx(InlineEditTextarea, { value: spec?.description || "", onSave: async () => false, isSaving: false, placeholder: "Add a description", minRows: 2, disabled: true }) })) : (_jsx("div", { className: "p-3", children: _jsx("pre", { className: "whitespace-pre-wrap break-words text-sm text-foreground font-sans", children: spec?.description }) })) })), (editable || spec?.tag) && (_jsx(Section, { title: "Tag", children: editable ? (_jsx("div", { className: "p-3", children: _jsx(InlineEditText, { value: spec?.tag || "", onSave: async () => false, isSaving: false, placeholder: "Add a tag (e.g. stable, latest)", disabled: true }) })) : (_jsx("div", { className: "flex items-center gap-2 px-3 py-2.5", children: _jsx("span", { className: "rounded bg-muted px-1.5 py-0.5 font-mono text-xs font-medium text-foreground", children: spec?.tag }) })) })), status?.artifactStorageKey ? (_jsx(SkillFileBrowser, { artifactStorageKey: status.artifactStorageKey })) : spec?.skillMd ? (_jsx(SkillContentSection, { content: spec.skillMd })) : null, status && (status.versionHash || status.gitProvenance) && (_jsx(VersionSection, { versionHash: status.versionHash, gitProvenance: status.gitProvenance }))] }));
}
// ---------------------------------------------------------------------------
// Skill state → StatusPhase mapping
// ---------------------------------------------------------------------------
function skillStateToPhase(state) {
    switch (state) {
        case SkillState.READY:
            return "ready";
        case SkillState.FAILED:
            return "failed";
        case SkillState.UPLOADING:
            return "pending";
        default:
            return undefined;
    }
}
function skillStateLabel(state) {
    switch (state) {
        case SkillState.READY:
            return "Ready";
        case SkillState.FAILED:
            return "Failed";
        case SkillState.UPLOADING:
            return "Uploading";
        default:
            return undefined;
    }
}
function SkillContentSection({ content }) {
    const [viewMode, setViewMode] = useState("rendered");
    return (_jsx(SkillSection, { title: "Skill Content", trailing: _jsx(ContentViewToggle, { value: viewMode, onChange: setViewMode }), children: viewMode === "rendered" ? (_jsx("div", { className: "p-4", children: _jsx(Markdown, { remarkPlugins: REMARK_PLUGINS, components: MARKDOWN_COMPONENTS, children: stripFrontmatter(content) }) })) : (_jsx("pre", { className: "overflow-x-auto p-4 font-mono text-sm leading-relaxed text-foreground", children: content })) }));
}
function ContentViewToggle({ value, onChange, }) {
    return (_jsxs("div", { role: "radiogroup", "aria-label": "Content view mode", className: "inline-flex rounded-md border border-input text-[11px]", children: [_jsx("button", { type: "button", role: "radio", "aria-checked": value === "rendered", onClick: () => onChange("rendered"), className: cn("rounded-l-md px-2 py-0.5 font-medium transition-colors", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", value === "rendered"
                    ? "bg-muted text-foreground"
                    : "text-muted-foreground hover:text-foreground"), children: "Preview" }), _jsx("button", { type: "button", role: "radio", "aria-checked": value === "source", onClick: () => onChange("source"), className: cn("rounded-r-md border-l border-input px-2 py-0.5 font-medium transition-colors", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", value === "source"
                    ? "bg-muted text-foreground"
                    : "text-muted-foreground hover:text-foreground"), children: "Source" })] }));
}
// ---------------------------------------------------------------------------
// Version section
// ---------------------------------------------------------------------------
function VersionSection({ versionHash, gitProvenance, }) {
    const truncatedHash = versionHash ? versionHash.slice(0, 12) : null;
    return (_jsx(Section, { title: "Version", children: _jsxs("div", { className: "flex flex-col gap-3 p-3", children: [truncatedHash && (_jsxs("div", { className: "flex items-baseline gap-2", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Hash" }), _jsx("code", { className: "font-mono text-xs text-foreground", title: versionHash, children: truncatedHash })] })), gitProvenance && _jsx(GitProvenanceDisplay, { provenance: gitProvenance })] }) }));
}
function GitProvenanceDisplay({ provenance, }) {
    const repoUrl = normalizeGitUrl(provenance.remoteUrl);
    const truncatedCommit = provenance.commit
        ? provenance.commit.slice(0, 7)
        : null;
    return (_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsxs("div", { className: "flex items-baseline gap-2", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Git" }), _jsxs("div", { className: "flex flex-wrap items-baseline gap-x-1.5 text-xs text-foreground", children: [repoUrl ? (_jsx("a", { href: repoUrl, className: "text-primary underline underline-offset-2 hover:text-primary-muted", target: "_blank", rel: "noopener noreferrer", children: formatRepoName(repoUrl) })) : (_jsx("span", { className: "font-mono", children: provenance.remoteUrl })), provenance.ref && (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-muted-foreground", children: "@" }), _jsx("span", { children: provenance.ref })] })), truncatedCommit && (_jsx("code", { className: "rounded bg-muted px-1 py-0.5 font-mono text-[10px]", title: provenance.commit, children: truncatedCommit }))] })] }), provenance.subdir && (_jsxs("div", { className: "flex items-baseline gap-2", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Path" }), _jsx("code", { className: "font-mono text-xs text-foreground", children: provenance.subdir })] }))] }));
}
// ---------------------------------------------------------------------------
// Shared layout primitives
// ---------------------------------------------------------------------------
function SkillSection({ title, trailing, children, }) {
    return (_jsxs("section", { children: [_jsxs("div", { className: "mb-2 flex items-center justify-between", children: [_jsx("h3", { className: "text-xs font-medium uppercase tracking-wider text-muted-foreground", children: title }), trailing] }), _jsx("div", { className: "overflow-hidden rounded-lg border border-border", children: children })] }));
}
// ---------------------------------------------------------------------------
// Non-happy states
// ---------------------------------------------------------------------------
function LoadingSkeleton({ className }) {
    return (_jsxs("div", { className: cn("flex flex-col gap-6", className), "aria-busy": "true", "aria-label": "Loading skill details", children: [_jsxs("div", { className: "flex items-start gap-3", children: [_jsx("div", { className: "mt-1 size-6 shrink-0 animate-pulse rounded bg-muted" }), _jsxs("div", { className: "flex-1 space-y-2", children: [_jsx("div", { className: "h-5 w-48 animate-pulse rounded bg-muted" }), _jsx("div", { className: "h-3 w-64 animate-pulse rounded bg-muted" }), _jsx("div", { className: "h-4 w-full max-w-md animate-pulse rounded bg-muted" })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx("div", { className: "h-3 w-28 animate-pulse rounded bg-muted" }), _jsx("div", { className: "animate-pulse rounded-lg border border-border bg-muted-faint", style: { height: "240px" } })] }), _jsxs("div", { className: "space-y-2", children: [_jsx("div", { className: "h-3 w-20 animate-pulse rounded bg-muted" }), _jsx("div", { className: "animate-pulse rounded-lg border border-border bg-muted-faint", style: { height: "64px" } })] })] }));
}
function NotFoundState({ className }) {
    return (_jsxs("div", { role: "status", className: cn("flex flex-col items-center gap-2 py-12 text-center", className), children: [_jsx(SkillIcon, { className: "size-10 text-muted-foreground-faint" }), _jsx("p", { className: "text-sm font-medium text-muted-foreground", children: "Skill not found" }), _jsx("p", { className: "text-xs text-muted-foreground-subtle", children: "This skill doesn't exist or you don't have access to it." })] }));
}
// ---------------------------------------------------------------------------
// Utilities
// ---------------------------------------------------------------------------
function normalizeGitUrl(url) {
    if (!url)
        return null;
    const cleaned = url.replace(/\.git$/, "");
    if (cleaned.startsWith("https://") || cleaned.startsWith("http://")) {
        return cleaned;
    }
    const sshMatch = cleaned.match(/^(?:git@|ssh:\/\/)([^:/]+)[:/](.+)$/);
    if (sshMatch) {
        return `https://${sshMatch[1]}/${sshMatch[2]}`;
    }
    return null;
}
function formatRepoName(url) {
    try {
        const parsed = new URL(url);
        return parsed.pathname.replace(/^\//, "").replace(/\.git$/, "");
    }
    catch {
        return url;
    }
}
// ---------------------------------------------------------------------------
// Icons — inline SVGs following the SDK pattern (no icon library dependency)
// ---------------------------------------------------------------------------
function SkillIcon({ className }) {
    return (_jsx("svg", { className: className, viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: _jsx("path", { d: "M9 1.5 4 9h4l-1 5.5L12 7H8l1-5.5Z" }) }));
}
//# sourceMappingURL=SkillDetailView.js.map