"use client";
import { useCallback, useEffect, useState } from "react";
const GITHUB_REPOS_API = "https://api.github.com/user/repos";
const GITHUB_BRANCHES_API = "https://api.github.com/repos";
const PER_PAGE = 100;
function parseRepoResponse(r) {
    const ownerObj = r.owner;
    return {
        id: r.id,
        fullName: r.full_name,
        name: r.name,
        owner: ownerObj.login,
        ownerType: ownerObj.type === "Organization" ? "Organization" : "User",
        htmlUrl: r.html_url,
        cloneUrl: r.clone_url,
        defaultBranch: r.default_branch,
        isPrivate: r.private,
        updatedAt: r.updated_at,
    };
}
async function fetchRepoPage(token, page) {
    const url = `${GITHUB_REPOS_API}?sort=pushed&direction=desc&per_page=${PER_PAGE}&page=${page}`;
    const resp = await fetch(url, {
        headers: { Authorization: `Bearer ${token}` },
    });
    if (!resp.ok) {
        throw new Error(`GitHub API error: ${resp.status}`);
    }
    const data = await resp.json();
    const repos = data.map(parseRepoResponse);
    return { repos, hasMore: repos.length === PER_PAGE };
}
/**
 * Data hook that fetches the authenticated user's GitHub repositories.
 *
 * Loads the first page immediately, then eagerly background-fetches
 * remaining pages so client-side search covers the full repo set.
 * Provides client-side search filtering and branch fetching.
 *
 * @example
 * ```tsx
 * function RepoList({ token }: { token: string }) {
 *   const { repos, isLoading, search, setSearch, fetchBranches } =
 *     useGitHubRepos(token);
 *
 *   if (isLoading) return <Skeleton />;
 *
 *   return (
 *     <div>
 *       <input
 *         value={search}
 *         onChange={(e) => setSearch(e.target.value)}
 *         placeholder="Filter repositories…"
 *       />
 *       <ul>
 *         {repos.map((repo) => (
 *           <li key={repo.id}>{repo.fullName}</li>
 *         ))}
 *       </ul>
 *     </div>
 *   );
 * }
 * ```
 *
 * @example
 * ```tsx
 * // Skip fetching until a token is available
 * const { repos } = useGitHubRepos(token ?? null);
 * ```
 */
export function useGitHubRepos(token) {
    const [allRepos, setAllRepos] = useState([]);
    const [isLoading, setIsLoading] = useState(false);
    const [isBackgroundLoading, setIsBackgroundLoading] = useState(false);
    const [error, setError] = useState(null);
    const [search, setSearch] = useState("");
    const [hasMore, setHasMore] = useState(true);
    useEffect(() => {
        if (!token) {
            setAllRepos([]);
            setIsLoading(false);
            setIsBackgroundLoading(false);
            setHasMore(false);
            return;
        }
        const cancelled = { current: false };
        async function fetchAll() {
            setIsLoading(true);
            setError(null);
            setAllRepos([]);
            setHasMore(true);
            try {
                const first = await fetchRepoPage(token, 1);
                if (cancelled.current)
                    return;
                setAllRepos(first.repos);
                setIsLoading(false);
                if (!first.hasMore) {
                    setHasMore(false);
                    return;
                }
                setIsBackgroundLoading(true);
                let page = 2;
                let more = true;
                while (more && !cancelled.current) {
                    const result = await fetchRepoPage(token, page);
                    if (cancelled.current)
                        return;
                    setAllRepos((prev) => [...prev, ...result.repos]);
                    more = result.hasMore;
                    page++;
                }
                if (!cancelled.current) {
                    setHasMore(false);
                    setIsBackgroundLoading(false);
                }
            }
            catch (e) {
                if (cancelled.current)
                    return;
                setError(e instanceof Error ? e.message : "Failed to fetch repos");
                setIsLoading(false);
                setIsBackgroundLoading(false);
            }
        }
        fetchAll();
        return () => {
            cancelled.current = true;
        };
    }, [token]);
    const loadMore = useCallback(() => {
        // Retained for backwards compatibility. Background pagination
        // fetches all pages automatically after the first page loads.
    }, []);
    const filtered = search
        ? allRepos.filter((r) => r.fullName.toLowerCase().includes(search.toLowerCase()))
        : allRepos;
    const fetchBranches = useCallback(async (owner, repo) => {
        if (!token)
            return [];
        try {
            const resp = await fetch(`${GITHUB_BRANCHES_API}/${owner}/${repo}/branches?per_page=100`, { headers: { Authorization: `Bearer ${token}` } });
            if (!resp.ok)
                return [];
            const data = await resp.json();
            return data.map((b) => ({
                name: b.name,
            }));
        }
        catch {
            return [];
        }
    }, [token]);
    return {
        repos: filtered,
        isLoading,
        isBackgroundLoading,
        error,
        search,
        setSearch,
        hasMore,
        loadMore,
        fetchBranches,
    };
}
//# sourceMappingURL=useGitHubRepos.js.map