import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { memo, useCallback, useEffect, useState } from 'react';
import { FolderGit2, ChevronRight, ChevronDown, Download, GitBranch, Globe, Plus, RefreshCw, Sparkles, Trash2, Upload, X, } from 'lucide-react';
import { useQueryClient } from '@tanstack/react-query';
import { useGitStore } from '../../stores/gitStore';
import { usePanelWidthStore } from '../../stores/panelWidthStore';
import { useGitStatus, usePullChanges, usePushCommits, useGitInit, useGitRemotes, useAddRemote, useRemoveRemote, } from '../../hooks/useGit';
import { Button } from '../ui/Button';
import { GitFileList } from './GitFileList';
import { ResizeHandle } from '../ui/ResizeHandle';
const PANEL_KEY = 'git';
const DEFAULT_WIDTH = 320;
const MIN_WIDTH = 320;
const MAX_WIDTH = 600;
export const GitSidebar = memo(function GitSidebar({ onFixWithAI, }) {
    const isExpanded = useGitStore((state) => state.isExpanded);
    const collapseSidebar = useGitStore((state) => state.collapseSidebar);
    const panelWidth = usePanelWidthStore((s) => s.widths[PANEL_KEY] ?? DEFAULT_WIDTH);
    const { data: status, isLoading, error, refetch } = useGitStatus();
    const { data: remotes } = useGitRemotes();
    const queryClient = useQueryClient();
    const pushMutation = usePushCommits();
    const pullMutation = usePullChanges();
    const initMutation = useGitInit();
    const addRemoteMutation = useAddRemote();
    const removeRemoteMutation = useRemoveRemote();
    const [errors, setErrors] = useState([]);
    const [showRemotes, setShowRemotes] = useState(false);
    const [showAddRemote, setShowAddRemote] = useState(false);
    const [remoteName, setRemoteName] = useState('origin');
    const [remoteUrl, setRemoteUrl] = useState('');
    const [confirmRemoveRemote, setConfirmRemoveRemote] = useState(null);
    useEffect(() => {
        if (isExpanded) {
            queryClient.invalidateQueries({ queryKey: ['git', 'status'] });
        }
    }, [isExpanded, queryClient]);
    const handleRefresh = () => {
        refetch();
    };
    const addError = useCallback((message, context) => {
        const id = `${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
        setErrors((prev) => [...prev, { id, message, context }]);
    }, []);
    const dismissError = useCallback((id) => {
        setErrors((prev) => prev.filter((e) => e.id !== id));
    }, []);
    const handlePush = async () => {
        try {
            await pushMutation.mutateAsync();
        }
        catch (err) {
            addError(err instanceof Error ? err.message : 'Failed to push', 'git push');
        }
    };
    const handlePull = async () => {
        try {
            await pullMutation.mutateAsync();
        }
        catch (err) {
            addError(err instanceof Error ? err.message : 'Failed to pull', 'git pull');
        }
    };
    const handleAddRemote = async () => {
        if (!remoteName.trim() || !remoteUrl.trim())
            return;
        try {
            await addRemoteMutation.mutateAsync({
                name: remoteName.trim(),
                url: remoteUrl.trim(),
            });
            setRemoteName('origin');
            setRemoteUrl('');
            setShowAddRemote(false);
        }
        catch (err) {
            addError(err instanceof Error ? err.message : 'Failed to add remote', 'git remote add');
        }
    };
    const handleRemoveRemote = async (name) => {
        if (confirmRemoveRemote !== name) {
            setConfirmRemoveRemote(name);
            return;
        }
        setConfirmRemoveRemote(null);
        try {
            await removeRemoteMutation.mutateAsync(name);
        }
        catch (err) {
            addError(err instanceof Error ? err.message : 'Failed to remove remote', 'git remote remove');
        }
    };
    const handleFixWithAI = useCallback((gitError) => {
        const prompt = gitError.context
            ? `I got a git error during ${gitError.context}:\n\n${gitError.message}\n\nPlease help me fix this.`
            : `I got a git error:\n\n${gitError.message}\n\nPlease help me fix this.`;
        dismissError(gitError.id);
        onFixWithAI?.(prompt);
    }, [onFixWithAI, dismissError]);
    if (!isExpanded)
        return null;
    const allFiles = [
        ...(status?.conflicted || []),
        ...(status?.staged || []),
        ...(status?.unstaged || []),
        ...(status?.untracked || []),
    ];
    const totalChanges = allFiles.length;
    const hasRemotes = status?.remotes && status.remotes.length > 0;
    const hasUpstream = status?.hasUpstream ?? false;
    const canPush = status && hasRemotes && (status.ahead > 0 || !hasUpstream);
    const _canPull = !!status;
    const hasPendingPulls = status && status.behind > 0;
    const isActing = pushMutation.isPending || pullMutation.isPending;
    const isNotGitRepo = error instanceof Error &&
        error.message.toLowerCase().includes('not a git repository');
    const pushTitle = !hasRemotes
        ? 'No remote configured'
        : !hasUpstream
            ? 'Publish branch to remote'
            : canPush
                ? `Push ${status?.ahead} commit(s) to remote`
                : 'Nothing to push';
    return (_jsxs("div", { className: "border-l border-border bg-background flex h-full relative", style: { width: panelWidth }, children: [_jsx(ResizeHandle, { panelKey: PANEL_KEY, side: "right", minWidth: MIN_WIDTH, maxWidth: MAX_WIDTH, defaultWidth: DEFAULT_WIDTH }), _jsxs("div", { className: "flex-1 flex flex-col h-full min-w-0 w-full", children: [_jsxs("div", { className: "h-14 border-b border-border px-3 flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2 flex-1", children: [_jsx(GitBranch, { className: "w-4 h-4 text-muted-foreground" }), _jsxs("span", { className: "font-medium text-foreground", children: ["Git Changes", totalChanges > 0 && (_jsxs("span", { className: "ml-2 text-xs text-muted-foreground", children: ["(", totalChanges, ")"] }))] })] }), _jsx(Button, { variant: "ghost", size: "icon", onClick: collapseSidebar, title: "Close sidebar", children: _jsx(ChevronRight, { className: "w-4 h-4" }) })] }), _jsx("div", { className: "flex-1 overflow-y-auto", children: isLoading ? (_jsx("div", { className: "p-4 text-sm text-muted-foreground", children: "Loading git status..." })) : isNotGitRepo ? (_jsxs("div", { className: "p-4 flex flex-col items-center justify-center gap-3 text-center", children: [_jsx(FolderGit2, { className: "w-10 h-10 text-muted-foreground" }), _jsx("div", { className: "text-sm text-muted-foreground", children: "No git repository found in this directory." }), _jsxs(Button, { variant: "secondary", size: "sm", onClick: () => initMutation.mutate(), disabled: initMutation.isPending, className: "gap-1.5", children: [_jsx(GitBranch, { className: `w-3.5 h-3.5 ${initMutation.isPending ? 'animate-spin' : ''}` }), initMutation.isPending
                                            ? 'Initializing...'
                                            : 'Initialize Repository'] }), initMutation.isError && (_jsx("span", { className: "text-xs text-orange-500", children: initMutation.error instanceof Error
                                        ? initMutation.error.message
                                        : 'Failed to initialize' }))] })) : error ? (_jsx("div", { className: "p-3 text-sm text-muted-foreground", children: _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx("span", { className: "text-orange-500", children: error instanceof Error
                                            ? error.message
                                            : 'Failed to load git status' }), _jsx(Button, { variant: "secondary", size: "sm", onClick: handleRefresh, children: "Retry" })] }) })) : !status || totalChanges === 0 ? (_jsx("div", { className: "p-3 text-sm text-muted-foreground", children: "No changes detected" })) : (_jsx(GitFileList, { status: status })) }), status && !isNotGitRepo && !error && (_jsxs("div", { className: "border-t border-border", children: [_jsxs("button", { type: "button", onClick: () => setShowRemotes(!showRemotes), className: "w-full px-3 py-2 flex items-center gap-2 text-xs text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors", children: [showRemotes ? (_jsx(ChevronDown, { className: "w-3 h-3" })) : (_jsx(ChevronRight, { className: "w-3 h-3" })), _jsx(Globe, { className: "w-3 h-3" }), _jsx("span", { children: "Remotes" }), status.remotes && (_jsx("span", { className: "ml-auto text-[10px] opacity-60", children: status.remotes.length }))] }), showRemotes && (_jsxs("div", { className: "px-3 pb-2 space-y-1", children: [remotes && remotes.length > 0 ? (remotes
                                        .filter((r) => r.type === 'fetch')
                                        .map((remote) => (_jsxs("div", { className: "flex items-center gap-2 text-xs group", children: [_jsx("span", { className: "font-medium text-foreground", children: remote.name }), _jsx("span", { className: "truncate text-muted-foreground flex-1 min-w-0", children: remote.url }), _jsx("button", { type: "button", onClick: () => {
                                                    if (confirmRemoveRemote === remote.name) {
                                                        handleRemoveRemote(remote.name);
                                                    }
                                                    else {
                                                        setConfirmRemoveRemote(remote.name);
                                                    }
                                                }, onBlur: () => setConfirmRemoveRemote(null), disabled: removeRemoteMutation.isPending, className: `${confirmRemoveRemote === remote.name ? 'opacity-100 text-red-500' : 'opacity-0 group-hover:opacity-100 text-muted-foreground hover:text-red-500'} transition-all p-0.5`, title: confirmRemoveRemote === remote.name
                                                    ? `Click again to confirm removing ${remote.name}`
                                                    : `Remove ${remote.name}`, children: confirmRemoveRemote === remote.name ? (_jsx("span", { className: "text-[10px] font-medium", children: "Remove?" })) : (_jsx(Trash2, { className: "w-3 h-3" })) })] }, remote.name)))) : (_jsx("div", { className: "text-xs text-muted-foreground py-1", children: "No remotes configured" })), showAddRemote ? (_jsxs("div", { className: "space-y-1.5 pt-1", children: [_jsx("input", { type: "text", value: remoteName, onChange: (e) => setRemoteName(e.target.value), placeholder: "Name (e.g. origin)", className: "w-full text-xs px-2 py-1 rounded border border-border bg-background text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-primary" }), _jsx("input", { type: "text", value: remoteUrl, onChange: (e) => setRemoteUrl(e.target.value), placeholder: "URL (e.g. https://github.com/...)", className: "w-full text-xs px-2 py-1 rounded border border-border bg-background text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-primary", onKeyDown: (e) => {
                                                    if (e.key === 'Enter')
                                                        handleAddRemote();
                                                    if (e.key === 'Escape')
                                                        setShowAddRemote(false);
                                                } }), _jsxs("div", { className: "flex gap-1", children: [_jsx(Button, { variant: "secondary", size: "sm", onClick: handleAddRemote, disabled: addRemoteMutation.isPending ||
                                                            !remoteName.trim() ||
                                                            !remoteUrl.trim(), className: "flex-1 h-6 text-[10px]", children: addRemoteMutation.isPending ? 'Adding...' : 'Add' }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => setShowAddRemote(false), className: "h-6 text-[10px]", children: "Cancel" })] })] })) : (_jsxs("button", { type: "button", onClick: () => setShowAddRemote(true), className: "flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors pt-1", children: [_jsx(Plus, { className: "w-3 h-3" }), _jsx("span", { children: "Add remote" })] }))] }))] })), errors.length > 0 && (_jsx("div", { className: "border-t border-border", children: errors.map((gitError) => (_jsxs("div", { className: "px-3 py-2 text-xs border-b border-border last:border-b-0 bg-orange-50 dark:bg-orange-950/20 flex items-start gap-2", children: [_jsx("span", { className: "text-orange-500 flex-1 min-w-0 break-words", children: gitError.message }), _jsxs("div", { className: "flex items-center gap-1 flex-shrink-0", children: [onFixWithAI && (_jsxs("button", { type: "button", onClick: () => handleFixWithAI(gitError), className: "flex items-center gap-1 text-[10px] px-1.5 py-0.5 rounded bg-primary/10 text-primary hover:bg-primary/20 transition-colors", title: "Fix with AI", children: [_jsx(Sparkles, { className: "w-3 h-3" }), "Fix"] })), _jsx("button", { type: "button", onClick: () => dismissError(gitError.id), className: "text-muted-foreground hover:text-foreground transition-colors p-0.5", title: "Dismiss", children: _jsx(X, { className: "w-3 h-3" }) })] })] }, gitError.id))) })), _jsxs("div", { className: "h-12 border-t border-border flex items-center gap-1 px-2", children: [_jsxs(Button, { variant: "secondary", size: "sm", onClick: handlePull, disabled: isActing || !hasRemotes || !hasUpstream, title: !hasRemotes
                                    ? 'No remote configured'
                                    : !hasUpstream
                                        ? 'Branch not published yet'
                                        : hasPendingPulls
                                            ? `Pull ${status?.behind} commit(s) from remote`
                                            : 'Pull from remote', className: "flex-1 h-8 text-xs gap-1.5", children: [_jsx(Download, { className: `w-3.5 h-3.5 ${pullMutation.isPending ? 'animate-pulse' : ''}` }), "Pull", hasPendingPulls && (_jsxs("span", { className: "text-orange-500", children: ["\u2193", status?.behind] }))] }), _jsxs(Button, { variant: "secondary", size: "sm", onClick: handlePush, disabled: !canPush || isActing, title: pushTitle, className: "flex-1 h-8 text-xs gap-1.5", children: [_jsx(Upload, { className: `w-3.5 h-3.5 ${pushMutation.isPending ? 'animate-pulse' : ''}` }), !hasUpstream && hasRemotes ? 'Publish' : 'Push', hasUpstream && status && status.ahead > 0 && (_jsxs("span", { className: "text-green-500", children: ["\u2191", status.ahead] }))] })] }), _jsxs("div", { className: "h-12 px-4 border-t border-border text-xs text-muted-foreground flex items-center justify-between gap-2", children: [_jsxs("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: [_jsx(GitBranch, { className: "w-3 h-3 flex-shrink-0" }), status?.branch && (_jsx("span", { className: "truncate", children: status.branch })), status && !hasUpstream && hasRemotes && (_jsx("span", { className: "text-[10px] text-orange-500 flex-shrink-0", children: "unpublished" }))] }), _jsx(Button, { variant: "ghost", size: "icon", onClick: handleRefresh, title: "Refresh git status", className: "h-6 w-6 flex-shrink-0", disabled: isLoading, children: _jsx(RefreshCw, { className: `w-3 h-3 ${isLoading ? 'animate-spin' : ''}` }) })] })] })] }));
});
//# sourceMappingURL=GitSidebar.js.map