'use client';
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useCallback, useEffect, useRef, useState } from 'react';
import { Lock, Globe, Loader2, Search, AlertCircle } from 'lucide-react';
import { Input } from '../../ui/input.js';
import { Badge } from '../../ui/badge.js';
import { Skeleton } from '../../ui/skeleton.js';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '../../ui/select.js';
import { listGitHubRepositories } from '../../../app/actions/list-github-repositories.js';
import { listGitHubOrganizations } from '../../../app/actions/list-github-organizations.js';
/** Sentinel value representing the authenticated user's personal account */
const PERSONAL_OWNER = '__personal__';
export function GitHubRepoBrowser({ onSelect, loading: externalLoading = false, fetchRepos = listGitHubRepositories, fetchOrgs = listGitHubOrganizations, }) {
    const [repos, setRepos] = useState([]);
    const [orgs, setOrgs] = useState([]);
    const [fetching, setFetching] = useState(true);
    const [error, setError] = useState('');
    const [search, setSearch] = useState('');
    const [selectedOwner, setSelectedOwner] = useState(PERSONAL_OWNER);
    const debounceRef = useRef(null);
    // Fetch organizations on mount
    useEffect(() => {
        async function loadOrgs() {
            try {
                const result = await fetchOrgs();
                if (result.orgs) {
                    setOrgs(result.orgs);
                }
            }
            catch {
                // Org listing failure is non-critical — user can still browse personal repos
            }
        }
        loadOrgs();
    }, [fetchOrgs]);
    const fetchData = useCallback(async (searchTerm, owner) => {
        setFetching(true);
        setError('');
        try {
            const input = {};
            if (searchTerm)
                input.search = searchTerm;
            if (owner && owner !== PERSONAL_OWNER)
                input.owner = owner;
            const result = await fetchRepos(Object.keys(input).length > 0 ? input : undefined);
            if (result.error) {
                setError(result.error);
                setRepos([]);
            }
            else {
                setRepos(result.repos ?? []);
            }
        }
        catch {
            setError('Failed to fetch repositories');
            setRepos([]);
        }
        finally {
            setFetching(false);
        }
    }, [fetchRepos]);
    useEffect(() => {
        fetchData(search || undefined, selectedOwner);
    }, [fetchData, selectedOwner]); // eslint-disable-line react-hooks/exhaustive-deps
    function handleSearchChange(value) {
        setSearch(value);
        if (debounceRef.current)
            clearTimeout(debounceRef.current);
        debounceRef.current = setTimeout(() => {
            fetchData(value || undefined, selectedOwner);
        }, 300);
    }
    function handleOwnerChange(value) {
        setSelectedOwner(value);
        setSearch('');
    }
    const disabled = externalLoading;
    if (error && !fetching) {
        return (_jsxs("div", { className: "flex flex-col items-center gap-2 py-8 text-center", "data-testid": "repo-browser-error", children: [_jsx(AlertCircle, { className: "text-destructive h-8 w-8" }), _jsx("p", { className: "text-destructive text-sm", children: error })] }));
    }
    return (_jsxs("div", { className: "flex flex-col gap-3", children: [orgs.length > 0 ? (_jsxs(Select, { value: selectedOwner, onValueChange: handleOwnerChange, disabled: disabled, children: [_jsx(SelectTrigger, { "aria-label": "Select owner", children: _jsx(SelectValue, { placeholder: "Select owner" }) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: PERSONAL_OWNER, children: "My repositories" }), orgs.map((org) => (_jsx(SelectItem, { value: org.login, children: org.login }, org.login)))] })] })) : null, _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "text-muted-foreground absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2" }), _jsx(Input, { placeholder: "Search repositories...", value: search, onChange: (e) => handleSearchChange(e.target.value), className: "ps-9", disabled: disabled, "aria-label": "Search repositories" })] }), _jsx("div", { className: "max-h-64 overflow-x-hidden overflow-y-auto rounded-md border", role: "listbox", "aria-label": "GitHub repositories", children: fetching ? (_jsx("div", { className: "flex flex-col gap-2 p-3", "data-testid": "repo-browser-loading", children: Array.from({ length: 5 }).map((_, i) => (_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx(Skeleton, { className: "h-4 w-48" }), _jsx(Skeleton, { className: "h-3 w-72" })] }, `skeleton-${String(i)}`))) })) : repos.length === 0 ? (_jsx("div", { className: "text-muted-foreground py-8 text-center text-sm", "data-testid": "repo-browser-empty", children: "No repositories found" })) : (repos.map((repo) => (_jsxs("button", { type: "button", role: "option", "aria-selected": false, className: "hover:bg-accent flex w-full items-start gap-2 border-b px-3 py-2.5 text-start last:border-b-0 disabled:opacity-50", onClick: () => onSelect(repo.nameWithOwner), disabled: disabled, children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "truncate text-sm font-medium", children: repo.nameWithOwner }), _jsx(Badge, { variant: repo.isPrivate ? 'secondary' : 'outline', className: "shrink-0 text-xs", children: repo.isPrivate ? (_jsxs(_Fragment, { children: [_jsx(Lock, { className: "me-1 h-3 w-3" }), "Private"] })) : (_jsxs(_Fragment, { children: [_jsx(Globe, { className: "me-1 h-3 w-3" }), "Public"] })) })] }), repo.description ? (_jsx("p", { className: "text-muted-foreground mt-0.5 truncate text-xs", children: repo.description })) : null] }), disabled ? _jsx(Loader2, { className: "mt-0.5 h-4 w-4 shrink-0 animate-spin" }) : null] }, repo.nameWithOwner)))) })] }));
}
