"use client";
import { useCallback, useMemo, useRef, useState } from "react";
import { stringify as stringifyYaml } from "yaml";
import { useStigmer } from "../hooks";
import { toError } from "../internal/toError";
import { parseResourceYaml } from "./parse-resource-yaml";
// ---------------------------------------------------------------------------
// Hook
// ---------------------------------------------------------------------------
/**
 * Headless import hook for Stigmer resources.
 *
 * Orchestrates the file import workflow:
 * 1. User selects a `.yaml`, `.yml`, or `.json` file
 * 2. `readFile` reads the content, detects the format, and validates
 *    the structure via `parseResourceYaml`
 * 3. On success, `preview` is populated with kind, name, slug, format
 * 4. On validation error, `error` is populated with a user-facing message
 * 5. User confirms → `apply(org)` calls the appropriate SDK `apply()` method
 *
 * Follows the established mutation-hook pattern: `isApplying` + `error` +
 * `reset`. The `preview` state enables a confirmation step before committing
 * (Nielsen heuristic #3: user control, #5: error prevention).
 *
 * @example
 * ```tsx
 * const { readFile, preview, error, reset, apply, isApplying } = useImportResource();
 *
 * const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
 *   const file = e.target.files?.[0];
 *   if (file) readFile(file);
 * };
 *
 * if (preview) {
 *   return (
 *     <div>
 *       <p>Import {preview.kind}: {preview.name}</p>
 *       <button onClick={() => apply(org)} disabled={isApplying}>
 *         Confirm
 *       </button>
 *     </div>
 *   );
 * }
 * ```
 *
 * @see {@link parseResourceYaml} for the validation logic
 * @see {@link ImportResourceDialog} for the styled component that composes this hook
 */
export function useImportResource() {
    const stigmer = useStigmer();
    const [preview, setPreview] = useState(null);
    const [error, setError] = useState(null);
    const [isApplying, setIsApplying] = useState(false);
    const contentRef = useRef(null);
    const parsedRef = useRef(null);
    const reset = useCallback(() => {
        setPreview(null);
        setError(null);
        setIsApplying(false);
        contentRef.current = null;
        parsedRef.current = null;
    }, []);
    const readFile = useCallback(async (file) => {
        setPreview(null);
        setError(null);
        contentRef.current = null;
        parsedRef.current = null;
        let text;
        try {
            text = await file.text();
        }
        catch {
            setError("Failed to read the selected file.");
            return;
        }
        if (!text.trim()) {
            setError("The selected file is empty.");
            return;
        }
        const format = detectFormat(file.name, text);
        // For JSON files, convert to YAML-parseable content first.
        // parseResourceYaml expects YAML, but since YAML is a superset of JSON,
        // we can pass JSON directly. However for cleaner error messages, we
        // normalize JSON → plain object → YAML string if needed.
        let yamlContent;
        if (format === "json") {
            try {
                const parsed = JSON.parse(text);
                if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
                    setError("JSON file must contain a single object (not an array or primitive).");
                    return;
                }
                yamlContent = stringifyYaml(parsed);
            }
            catch {
                setError("The file does not contain valid JSON.");
                return;
            }
        }
        else {
            yamlContent = text;
        }
        // Validate structure using the existing parser. We use a dummy org
        // here — the real org is provided at apply time.
        let parsed;
        try {
            parsed = parseResourceYaml(yamlContent, "__preview__");
        }
        catch (err) {
            setError(err instanceof Error ? err.message : "Failed to validate resource file.");
            return;
        }
        contentRef.current = yamlContent;
        parsedRef.current = parsed;
        setPreview({
            kind: parsed.kind,
            name: parsed.input.name,
            slug: "slug" in parsed.input ? parsed.input.slug : undefined,
            format,
            rawContent: text,
        });
    }, []);
    const apply = useCallback(async (org) => {
        const content = contentRef.current;
        if (!content) {
            throw new Error("No file has been validated. Call readFile first.");
        }
        setIsApplying(true);
        setError(null);
        try {
            const parsed = parseResourceYaml(content, org);
            switch (parsed.kind) {
                case "Agent": {
                    const agent = await stigmer.agent.apply(parsed.input);
                    return {
                        kind: "Agent",
                        name: agent.metadata?.name ?? parsed.input.name,
                        org: agent.metadata?.org ?? org,
                        slug: agent.metadata?.slug ?? parsed.input.name,
                    };
                }
                case "McpServer": {
                    const mcpServer = await stigmer.mcpServer.apply(parsed.input);
                    return {
                        kind: "McpServer",
                        name: mcpServer.metadata?.name ?? parsed.input.name,
                        org: mcpServer.metadata?.org ?? org,
                        slug: mcpServer.metadata?.slug ?? parsed.input.name,
                    };
                }
            }
        }
        catch (err) {
            const message = toError(err).message;
            setError(message);
            throw err;
        }
        finally {
            setIsApplying(false);
        }
    }, [stigmer]);
    return useMemo(() => ({ readFile, preview, error, reset, apply, isApplying }), [readFile, preview, error, reset, apply, isApplying]);
}
// ---------------------------------------------------------------------------
// Format detection
// ---------------------------------------------------------------------------
const JSON_EXTENSIONS = new Set([".json"]);
const YAML_EXTENSIONS = new Set([".yaml", ".yml"]);
function detectFormat(filename, content) {
    const lowerName = filename.toLowerCase();
    const dotIndex = lowerName.lastIndexOf(".");
    if (dotIndex >= 0) {
        const ext = lowerName.slice(dotIndex);
        if (JSON_EXTENSIONS.has(ext))
            return "json";
        if (YAML_EXTENSIONS.has(ext))
            return "yaml";
    }
    // Fallback: try parsing as JSON. If it parses, treat as JSON.
    try {
        JSON.parse(content);
        return "json";
    }
    catch {
        return "yaml";
    }
}
//# sourceMappingURL=useImportResource.js.map