'use client';
import { useState, useCallback, useRef, useEffect } from 'react';
import { openIde } from '../../../app/actions/open-ide.js';
import { openShell } from '../../../app/actions/open-shell.js';
import { openFolder } from '../../../app/actions/open-folder.js';
import { rebaseFeature } from '../../../app/actions/rebase-feature.js';
const ERROR_CLEAR_DELAY = 5000;
export function useFeatureActions(input) {
    const [ideLoading, setIdeLoading] = useState(false);
    const [shellLoading, setShellLoading] = useState(false);
    const [folderLoading, setFolderLoading] = useState(false);
    const [specsLoading, setSpecsLoading] = useState(false);
    const [rebaseLoading, setRebaseLoading] = useState(false);
    const [ideError, setIdeError] = useState(null);
    const [shellError, setShellError] = useState(null);
    const [folderError, setFolderError] = useState(null);
    const [specsError, setSpecsError] = useState(null);
    const [rebaseError, setRebaseError] = useState(null);
    const ideTimerRef = useRef(null);
    const shellTimerRef = useRef(null);
    const folderTimerRef = useRef(null);
    const specsTimerRef = useRef(null);
    const rebaseTimerRef = useRef(null);
    // Clear timers on unmount — read .current inside cleanup so we get the
    // actual timer value at teardown time, not the always-null value at mount.
    useEffect(() => {
        const refs = [ideTimerRef, shellTimerRef, folderTimerRef, specsTimerRef, rebaseTimerRef];
        return () => {
            for (const ref of refs) {
                if (ref.current)
                    clearTimeout(ref.current);
            }
        };
    }, []);
    const performAction = useCallback(async (action, setLoading, setError, timerRef, isLoading) => {
        if (!input || isLoading)
            return;
        // Clear any existing timer
        if (timerRef.current)
            clearTimeout(timerRef.current);
        setLoading(true);
        setError(null);
        try {
            const result = await action({
                repositoryPath: input.repositoryPath,
                branch: input.branch,
            });
            if (!result.success) {
                const errorMessage = result.error ?? 'An unexpected error occurred';
                setError(errorMessage);
                timerRef.current = setTimeout(() => setError(null), ERROR_CLEAR_DELAY);
            }
        }
        catch (err) {
            const errorMessage = err instanceof Error ? err.message : 'An unexpected error occurred';
            setError(errorMessage);
            timerRef.current = setTimeout(() => setError(null), ERROR_CLEAR_DELAY);
        }
        finally {
            setLoading(false);
        }
    }, [input]);
    const handleOpenIde = useCallback(() => performAction(openIde, setIdeLoading, setIdeError, ideTimerRef, ideLoading), [performAction, ideLoading]);
    const handleOpenShell = useCallback(() => performAction(openShell, setShellLoading, setShellError, shellTimerRef, shellLoading), [performAction, shellLoading]);
    const handleOpenFolder = useCallback(async () => {
        if (!input || folderLoading)
            return;
        if (folderTimerRef.current)
            clearTimeout(folderTimerRef.current);
        setFolderLoading(true);
        setFolderError(null);
        try {
            const folderPath = input.worktreePath ?? input.repositoryPath;
            const result = await openFolder(folderPath);
            if (!result.success) {
                const errorMessage = result.error ?? 'An unexpected error occurred';
                setFolderError(errorMessage);
                folderTimerRef.current = setTimeout(() => setFolderError(null), ERROR_CLEAR_DELAY);
            }
        }
        catch (err) {
            const errorMessage = err instanceof Error ? err.message : 'An unexpected error occurred';
            setFolderError(errorMessage);
            folderTimerRef.current = setTimeout(() => setFolderError(null), ERROR_CLEAR_DELAY);
        }
        finally {
            setFolderLoading(false);
        }
    }, [input, folderLoading]);
    const handleOpenSpecsFolder = useCallback(async () => {
        if (!input?.specPath || specsLoading)
            return;
        if (specsTimerRef.current)
            clearTimeout(specsTimerRef.current);
        setSpecsLoading(true);
        setSpecsError(null);
        try {
            const result = await openFolder(input.specPath);
            if (!result.success) {
                const errorMessage = result.error ?? 'An unexpected error occurred';
                setSpecsError(errorMessage);
                specsTimerRef.current = setTimeout(() => setSpecsError(null), ERROR_CLEAR_DELAY);
            }
        }
        catch (err) {
            const errorMessage = err instanceof Error ? err.message : 'An unexpected error occurred';
            setSpecsError(errorMessage);
            specsTimerRef.current = setTimeout(() => setSpecsError(null), ERROR_CLEAR_DELAY);
        }
        finally {
            setSpecsLoading(false);
        }
    }, [input, specsLoading]);
    const handleRebaseOnMain = useCallback(async () => {
        if (!input?.featureId || rebaseLoading)
            return;
        if (rebaseTimerRef.current)
            clearTimeout(rebaseTimerRef.current);
        setRebaseLoading(true);
        setRebaseError(null);
        try {
            const result = await rebaseFeature(input.featureId);
            if (!result.success) {
                const errorMessage = result.error ?? 'An unexpected error occurred';
                setRebaseError(errorMessage);
                rebaseTimerRef.current = setTimeout(() => setRebaseError(null), ERROR_CLEAR_DELAY);
            }
        }
        catch (err) {
            const errorMessage = err instanceof Error ? err.message : 'An unexpected error occurred';
            setRebaseError(errorMessage);
            rebaseTimerRef.current = setTimeout(() => setRebaseError(null), ERROR_CLEAR_DELAY);
        }
        finally {
            setRebaseLoading(false);
        }
    }, [input, rebaseLoading]);
    return {
        openInIde: handleOpenIde,
        openInShell: handleOpenShell,
        openFolder: handleOpenFolder,
        openSpecsFolder: handleOpenSpecsFolder,
        rebaseOnMain: handleRebaseOnMain,
        ideLoading,
        shellLoading,
        folderLoading,
        specsLoading,
        rebaseLoading,
        ideError,
        shellError,
        folderError,
        specsError,
        rebaseError,
    };
}
