"use client";
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { useCallback, useEffect, useRef, useState } from "react";
import Markdown from "react-markdown";
import { cn } from "@stigmer/theme";
import { MARKDOWN_COMPONENTS, REMARK_PLUGINS, stripFrontmatter } from "../internal/markdown-components.js";
import { useSkillUpload } from "./useSkillUpload.js";
import { usePushSkill } from "./usePushSkill.js";
import { useSkillDuplicateCheck } from "./useSkillDuplicateCheck.js";
// ---------------------------------------------------------------------------
// Main component
// ---------------------------------------------------------------------------
/**
 * Skill package upload component with validation and preview.
 *
 * Two-phase flow:
 * 1. **Drop zone** — User drags/drops or clicks to select a .zip file
 * 2. **Preview + confirm** — Validated package summary, file listing,
 *    rendered SKILL.md preview, and push button
 *
 * Validates the uploaded ZIP against the Anthropic Agent Skills spec:
 * must contain SKILL.md with valid YAML frontmatter (name, description).
 *
 * Zero Console dependencies — safe for platform builder embedding.
 * All visual properties flow through `--stgm-*` design tokens.
 *
 * @example
 * ```tsx
 * <SkillUploader
 *   org="acme"
 *   onComplete={(skill) => router.push(`/library/skills/${skill.metadata?.org}/${skill.metadata?.slug}`)}
 *   onCancel={() => router.back()}
 * />
 * ```
 */
export function SkillUploader({ org, tag, onComplete, onCancel, className, }) {
    const upload = useSkillUpload();
    const { push, isPushing, error: pushError, clearError } = usePushSkill();
    const dupCheck = useSkillDuplicateCheck();
    const handleFileProcessed = useCallback(async (file) => {
        dupCheck.reset();
        await upload.processFile(file);
    }, [upload, dupCheck]);
    useEffect(() => {
        if (upload.preview && upload.artifact) {
            const slug = normalizeToSlug(upload.preview.name);
            dupCheck.check({ org, slug, artifactBytes: upload.artifact });
        }
    }, [upload.preview, upload.artifact, org]);
    const handlePush = useCallback(async () => {
        if (!upload.artifact)
            return;
        clearError();
        try {
            const skill = await push({ org, artifact: upload.artifact, tag });
            onComplete?.(skill);
        }
        catch {
            // Error captured in usePushSkill state
        }
    }, [upload.artifact, clearError, push, org, tag, onComplete]);
    const handleReset = useCallback(() => {
        upload.reset();
        dupCheck.reset();
    }, [upload, dupCheck]);
    return (_jsx("div", { className: cn("flex flex-col gap-0 rounded-lg border border-border bg-card", className), children: upload.preview ? (_jsx(PreviewPhase, { preview: upload.preview, isPushing: isPushing, pushError: pushError, onPush: handlePush, onReset: handleReset, onCancel: onCancel, isDuplicate: dupCheck.isDuplicate, isCheckingDuplicate: dupCheck.isChecking })) : (_jsx(DropZonePhase, { onFile: handleFileProcessed, isProcessing: upload.isProcessing, validationError: upload.validationError, onCancel: onCancel })) }));
}
// ---------------------------------------------------------------------------
// Phase 1: Drop Zone
// ---------------------------------------------------------------------------
function DropZonePhase({ onFile, isProcessing, validationError, onCancel, }) {
    const [isDragOver, setIsDragOver] = useState(false);
    const inputRef = useRef(null);
    const handleDragOver = useCallback((e) => {
        e.preventDefault();
        e.stopPropagation();
        setIsDragOver(true);
    }, []);
    const handleDragLeave = useCallback((e) => {
        e.preventDefault();
        e.stopPropagation();
        setIsDragOver(false);
    }, []);
    const handleDrop = useCallback((e) => {
        e.preventDefault();
        e.stopPropagation();
        setIsDragOver(false);
        const file = e.dataTransfer.files[0];
        if (file)
            onFile(file);
    }, [onFile]);
    const handleClick = useCallback(() => {
        inputRef.current?.click();
    }, []);
    const handleFileChange = useCallback((e) => {
        const file = e.target.files?.[0];
        if (file)
            onFile(file);
        if (inputRef.current)
            inputRef.current.value = "";
    }, [onFile]);
    return (_jsxs("div", { className: "flex flex-col", children: [_jsxs("div", { role: "button", tabIndex: 0, "aria-label": "Upload skill package", onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, onClick: handleClick, onKeyDown: (e) => { if (e.key === "Enter" || e.key === " ")
                    handleClick(); }, className: cn("flex flex-col items-center justify-center gap-3 rounded-lg border-2 border-dashed p-12 transition-colors cursor-pointer", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", isDragOver
                    ? "border-primary bg-muted-subtle"
                    : "border-border hover:border-muted-foreground hover:bg-muted-subtle", isProcessing && "pointer-events-none opacity-60"), children: [_jsx(UploadIcon, { className: cn("size-10 text-muted-foreground", isDragOver && "text-primary") }), isProcessing ? (_jsx("p", { className: "text-sm font-medium text-foreground", children: "Processing..." })) : (_jsxs(_Fragment, { children: [_jsx("p", { className: "text-sm font-medium text-foreground", children: "Drop your skill package here" }), _jsx("p", { className: "text-xs text-muted-foreground", children: "or click to browse" })] })), _jsx("p", { className: "mt-2 text-[10px] text-muted-foreground-subtle", children: "Accepts .zip files following the Anthropic Agent Skills format" }), _jsx("input", { ref: inputRef, type: "file", accept: ".zip", onChange: handleFileChange, className: "hidden", "aria-hidden": "true" })] }), validationError && (_jsx("div", { className: "px-4 py-3", children: _jsx("p", { className: "text-sm text-destructive", role: "alert", children: validationError }) })), onCancel && (_jsx("div", { className: "flex justify-end border-t border-border px-4 py-3", children: _jsx("button", { type: "button", onClick: onCancel, className: cn("rounded-md px-3 py-1.5 text-sm font-medium text-muted-foreground", "hover:text-foreground hover:bg-muted", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", "transition-colors"), children: "Cancel" }) }))] }));
}
// ---------------------------------------------------------------------------
// Phase 2: Preview + Confirm
// ---------------------------------------------------------------------------
function PreviewPhase({ preview, isPushing, pushError, onPush, onReset, onCancel, isDuplicate, isCheckingDuplicate, }) {
    const strippedContent = stripFrontmatter(preview.skillMdContent);
    return (_jsxs("div", { className: "flex flex-col", children: [_jsx("div", { className: "border-b border-border px-4 py-3", children: _jsx("h3", { className: "text-sm font-medium text-foreground", children: "Skill Package Preview" }) }), _jsxs("div", { className: "flex flex-col gap-2 border-b border-border px-4 py-3", children: [_jsxs("div", { className: "flex items-baseline gap-2", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground w-20 shrink-0", children: "Name" }), _jsx("span", { className: "text-sm font-medium text-foreground font-mono", children: preview.name })] }), preview.description && (_jsxs("div", { className: "flex items-baseline gap-2", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground w-20 shrink-0", children: "Description" }), _jsx("span", { className: "text-sm text-foreground", children: preview.description })] }))] }), _jsxs("div", { className: "border-b border-border px-4 py-3", children: [_jsxs("div", { className: "mb-2 flex items-baseline justify-between", children: [_jsxs("span", { className: "text-xs font-medium text-muted-foreground", children: ["Files (", preview.files.filter((f) => !f.isDirectory).length, ")"] }), _jsxs("span", { className: "text-[10px] text-muted-foreground-subtle", children: [formatBytes(preview.totalSize), " total"] })] }), _jsx("div", { className: "rounded-md border border-border overflow-hidden", children: _jsx("table", { className: "w-full text-xs", children: _jsx("tbody", { children: preview.files
                                    .filter((f) => !f.isDirectory)
                                    .map((file) => (_jsxs("tr", { className: "border-b border-border last:border-b-0", children: [_jsx("td", { className: "px-3 py-1.5 font-mono text-foreground", children: file.path }), _jsx("td", { className: "px-3 py-1.5 text-right text-muted-foreground tabular-nums", children: formatBytes(file.size) })] }, file.path))) }) }) })] }), strippedContent && (_jsxs("div", { className: "border-b border-border px-4 py-3", children: [_jsx("span", { className: "mb-2 block text-xs font-medium text-muted-foreground", children: "SKILL.md Preview" }), _jsx("div", { className: "max-h-[240px] overflow-y-auto rounded-md border border-border p-3", children: _jsx(Markdown, { remarkPlugins: REMARK_PLUGINS, components: MARKDOWN_COMPONENTS, children: strippedContent }) })] })), isDuplicate && (_jsxs("div", { className: "flex items-start gap-2.5 border-b border-amber-500/20 bg-amber-500/5 px-4 py-3", role: "alert", children: [_jsx(WarningIcon, { className: "mt-0.5 size-4 shrink-0 text-amber-600 dark:text-amber-400" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("p", { className: "text-sm font-medium text-amber-700 dark:text-amber-300", children: "No changes detected" }), _jsx("p", { className: "mt-0.5 text-xs text-amber-600 dark:text-amber-400", children: "This skill's content is identical to the current version. Pushing will create a new version record with the same content." })] })] })), isCheckingDuplicate && (_jsxs("div", { className: "flex items-center gap-2 border-b border-border px-4 py-2", children: [_jsx(Spinner, {}), _jsx("span", { className: "text-xs text-muted-foreground", children: "Checking for changes..." })] })), pushError && (_jsx("div", { className: "px-4 py-2", children: _jsx("p", { className: "text-sm text-destructive", role: "alert", children: pushError.message }) })), _jsxs("div", { className: "flex items-center justify-between px-4 py-3", children: [_jsx("button", { type: "button", onClick: onReset, className: cn("rounded-md px-3 py-1.5 text-sm font-medium text-muted-foreground", "hover:text-foreground hover:bg-muted", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", "transition-colors"), children: "Choose Different File" }), _jsxs("div", { className: "flex items-center gap-2", children: [onCancel && (_jsx("button", { type: "button", onClick: onCancel, className: cn("rounded-md px-3 py-1.5 text-sm font-medium text-muted-foreground", "hover:text-foreground hover:bg-muted", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", "transition-colors"), children: "Cancel" })), _jsx("button", { type: "button", onClick: onPush, disabled: isPushing, className: cn("rounded-md bg-primary px-4 py-1.5 text-sm font-medium text-primary-foreground", "hover:bg-primary-hover", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", "disabled:opacity-50 disabled:cursor-not-allowed", "transition-colors"), children: isPushing ? "Pushing..." : isDuplicate ? "Push Anyway" : "Push Skill" })] })] })] }));
}
// ---------------------------------------------------------------------------
// Utilities
// ---------------------------------------------------------------------------
function normalizeToSlug(name) {
    return name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
}
function formatBytes(bytes) {
    if (bytes < 1024)
        return `${bytes} B`;
    if (bytes < 1024 * 1024)
        return `${(bytes / 1024).toFixed(1)} KB`;
    return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
}
// ---------------------------------------------------------------------------
// Icons
// ---------------------------------------------------------------------------
function WarningIcon({ className }) {
    return (_jsxs("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: "M8 1.5 1 14h14L8 1.5Z" }), _jsx("path", { d: "M8 6v3.5" }), _jsx("circle", { cx: "8", cy: "11.5", r: "0.5", fill: "currentColor", stroke: "none" })] }));
}
function Spinner() {
    return (_jsx("svg", { width: "14", height: "14", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", className: "animate-spin", "aria-hidden": "true", children: _jsx("path", { d: "M8 2a6 6 0 1 0 6 6" }) }));
}
function UploadIcon({ className }) {
    return (_jsxs("svg", { className: className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }), _jsx("polyline", { points: "17 8 12 3 7 8" }), _jsx("line", { x1: "12", y1: "3", x2: "12", y2: "15" })] }));
}
//# sourceMappingURL=SkillUploader.js.map