import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
/**
 * Add Wizard Screen
 *
 * Multi-step wizard for adding a new flow (repository).
 * Steps:
 * 1. Enter repository path
 * 2. Enter git remote (defaults to 'origin')
 * 3. Enter optional display name
 * 4. Review and confirm
 */
import { decodeAbsolutePath } from "@ghostflow/client";
import { useAddFlow } from "@ghostflow/ui-core";
import { Effect, Match, pipe } from "effect";
import { Box, Text, useInput } from "ink";
import TextInput from "ink-text-input";
import { useCallback, useState } from "react";
import { KeyHints, WIZARD_HINTS } from "../components/KeyHints.js";
import { useSDK } from "../contexts/SDKContext.js";
// ============================================================================
// Constants
// ============================================================================
/** Wizard title */
const WIZARD_TITLE = "Add Repository";
/** Step labels */
const STEP_PATH_LABEL = "Step 1: Repository Path";
const STEP_REMOTE_LABEL = "Step 2: Git Remote";
const STEP_NAME_LABEL = "Step 3: Display Name (optional)";
const STEP_CONFIRM_LABEL = "Step 4: Confirm";
/** Placeholders */
const PATH_PLACEHOLDER = "/path/to/repository";
const REMOTE_PLACEHOLDER = "origin";
const NAME_PLACEHOLDER = "my-project";
/** Default values */
const DEFAULT_REMOTE = "origin";
/** Help text */
const PATH_HELP = "Enter the absolute path to the git repository";
const REMOTE_HELP = "Press Enter to use 'origin' or enter a different remote name";
const NAME_HELP = "Press Enter to skip (will use directory name)";
const CONFIRM_HELP = "Press Enter to add, Escape to cancel";
/** Status messages */
const ADDING_TEXT = "Adding flow...";
const SUCCESS_TEXT = "Flow added successfully!";
const ERROR_PREFIX = "Error: ";
// ============================================================================
// Helpers
// ============================================================================
/** Trims and returns undefined if empty */
const trimToOption = (value) => {
    if (value === undefined)
        return undefined;
    const trimmed = value.trim();
    return trimmed.length > 0 ? trimmed : undefined;
};
/** Trims and returns default if empty */
const trimWithDefault = (value, defaultValue) => trimToOption(value) ?? defaultValue;
// ============================================================================
// Component
// ============================================================================
/**
 * Multi-step wizard for adding a new flow.
 */
export const AddWizardScreen = ({ send, wizardData }) => {
    const sdk = useSDK();
    const [currentStep, setCurrentStep] = useState("path");
    const [pathValue, setPathValue] = useState(wizardData.path);
    const [remoteValue, setRemoteValue] = useState(DEFAULT_REMOTE);
    const [nameValue, setNameValue] = useState(wizardData.name);
    const [error, setError] = useState(undefined);
    // Create add mutation with SDK callback
    const addFlow = useAddFlow({
        onAdd: useCallback(async (input) => {
            // Validate and decode path to AbsolutePath
            const absolutePathExit = Effect.runSyncExit(decodeAbsolutePath(input.path));
            if (absolutePathExit._tag === "Failure") {
                throw new Error("Invalid path: must be an absolute path starting with /");
            }
            const absolutePath = absolutePathExit.value;
            // Build config input, only including optional properties when present
            const configInput = {
                path: absolutePath,
                remote: input.remote,
                ...(input.branch !== undefined ? { branch: input.branch } : {}),
                ...(input.name !== undefined ? { name: input.name } : {})
            };
            const result = await sdk.config.addFlow(configInput);
            // Handle partial failure case
            if (result._tag === "ConfigWrittenReloadFailed") {
                // Config was added but daemon reload failed
                console.warn("[ghostflow] Reload failed after add:", result.reloadError);
            }
        }, [sdk])
    });
    const handleNext = useCallback(() => {
        pipe(Match.value(currentStep), Match.when("path", () => {
            const trimmedPath = trimToOption(pathValue);
            if (trimmedPath === undefined)
                return;
            if (!trimmedPath.startsWith("/")) {
                setError("Path must be absolute (start with /)");
                return;
            }
            setError(undefined);
            send({ type: "SET_PATH", path: trimmedPath });
            setCurrentStep("remote");
        }), Match.when("remote", () => {
            const remote = trimWithDefault(remoteValue, DEFAULT_REMOTE);
            setRemoteValue(remote);
            setCurrentStep("name");
        }), Match.when("name", () => {
            const trimmedName = trimToOption(nameValue);
            if (trimmedName !== undefined) {
                send({ type: "SET_NAME", name: trimmedName });
            }
            setCurrentStep("confirm");
        }), Match.when("confirm", () => {
            setError(undefined);
            const path = trimToOption(pathValue);
            const remote = trimWithDefault(remoteValue, DEFAULT_REMOTE);
            const name = trimToOption(nameValue);
            if (path === undefined)
                return;
            // Build input, only including name when present
            const mutationInput = {
                path,
                remote,
                ...(name !== undefined ? { name } : {})
            };
            addFlow.mutate(mutationInput, {
                onSuccess: () => send({ type: "COMPLETE" }),
                onError: (err) => setError(err.message)
            });
        }), Match.exhaustive);
    }, [addFlow, currentStep, nameValue, pathValue, remoteValue, send]);
    const handleBack = useCallback(() => {
        pipe(Match.value(currentStep), Match.when("path", () => send({ type: "CANCEL" })), Match.when("remote", () => setCurrentStep("path")), Match.when("name", () => setCurrentStep("remote")), Match.when("confirm", () => setCurrentStep("name")), Match.exhaustive);
    }, [currentStep, send]);
    useInput((input, key) => {
        if (key.escape) {
            send({ type: "CANCEL" });
        }
        // Handle back navigation with backspace when input is empty
        if (key.backspace && currentStep !== "path") {
            // Only go back if the current field is empty
            const isEmpty = pipe(Match.value(currentStep), Match.when("remote", () => remoteValue === undefined), Match.when("name", () => nameValue === undefined), Match.when("confirm", () => false), // Always allow going back from confirm
            Match.orElse(() => false));
            // If on confirm step, always allow back via backspace
            if (currentStep === "confirm" || isEmpty) {
                handleBack();
            }
        }
        // Only handle enter in confirm step (TextInput handles enter in other steps)
        if (key.return && currentStep === "confirm" && !addFlow.isPending) {
            handleNext();
        }
    });
    return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: WIZARD_TITLE }) }), currentStep === "path" && (_jsx(PathStep, { error: error, onSubmit: handleNext, placeholder: PATH_PLACEHOLDER, setValue: setPathValue, value: pathValue })), currentStep === "remote" && (_jsx(RemoteStep, { onSubmit: handleNext, placeholder: REMOTE_PLACEHOLDER, setValue: setRemoteValue, value: remoteValue })), currentStep === "name" && (_jsx(NameStep, { onSubmit: handleNext, placeholder: NAME_PLACEHOLDER, setValue: setNameValue, value: nameValue })), currentStep === "confirm" && (_jsx(ConfirmStep, { error: error, isPending: addFlow.isPending, isSuccess: addFlow.isSuccess, name: trimToOption(nameValue), path: trimToOption(pathValue) ?? "", remote: trimWithDefault(remoteValue, DEFAULT_REMOTE) })), _jsx(KeyHints, { hints: WIZARD_HINTS })] }));
};
const PathStep = ({ error, onSubmit, placeholder, setValue, value }) => (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: STEP_PATH_LABEL }), _jsx(Text, { dimColor: true, children: PATH_HELP }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "cyan", children: ">" }), _jsx(TextInput, { onChange: (val) => setValue(val.length > 0 ? val : undefined), onSubmit: onSubmit, placeholder: placeholder, value: value ?? "" })] }), error !== undefined && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "red", children: error }) }))] }));
const RemoteStep = ({ onSubmit, placeholder, setValue, value }) => (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: STEP_REMOTE_LABEL }), _jsx(Text, { dimColor: true, children: REMOTE_HELP }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "cyan", children: ">" }), _jsx(TextInput, { onChange: (val) => setValue(val.length > 0 ? val : undefined), onSubmit: onSubmit, placeholder: placeholder, value: value ?? "" })] })] }));
const NameStep = ({ onSubmit, placeholder, setValue, value }) => (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: STEP_NAME_LABEL }), _jsx(Text, { dimColor: true, children: NAME_HELP }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "cyan", children: ">" }), _jsx(TextInput, { onChange: (val) => setValue(val.length > 0 ? val : undefined), onSubmit: onSubmit, placeholder: placeholder, value: value ?? "" })] })] }));
const ConfirmStep = ({ error, isPending, isSuccess, name, path, remote }) => (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: STEP_CONFIRM_LABEL }), _jsx(Text, { dimColor: true, children: CONFIRM_HELP }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: "Path:" }), _jsx(Text, { children: path })] }), _jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: "Remote:" }), _jsx(Text, { children: remote })] }), _jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: "Name:" }), _jsx(Text, { children: name ?? "(auto)" })] })] }), isPending && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "cyan", children: ADDING_TEXT }) })), isSuccess && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "green", children: SUCCESS_TEXT }) })), error !== undefined && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "red", children: [ERROR_PREFIX, error] }) }))] }));
//# sourceMappingURL=AddWizardScreen.js.map