"use client";

import {
    createContext,
    useCallback,
    useContext,
    useEffect,
    useState,
} from "react";
import type { AuditData, TabKey } from "@/lib/types";
import { initSubgraphColors } from "@/lib/utils";

interface AppContextValue {
    data: AuditData | null;
    loading: boolean;
    error: string | null;
    activeTab: TabKey;
    setActiveTab: (tab: TabKey) => void;
    search: string;
    setSearch: (search: string) => void;
    selectedSubgraph: string | null;
    setSelectedSubgraph: (subgraph: string | null) => void;
    page: number;
    setPage: (page: number) => void;
    sortColumn: string | null;
    setSortColumn: (column: string | null) => void;
    sortDirection: "asc" | "desc";
    setSortDirection: (direction: "asc" | "desc") => void;
    theme: "dark" | "light";
    setTheme: (theme: "dark" | "light") => void;
    toggleTheme: () => void;
}

const AppContext = createContext<AppContextValue | null>(null);

function getInitialTheme(): "dark" | "light" {
    if (typeof window === "undefined") return "dark";
    const stored = localStorage.getItem("schema-audit-theme");
    if (stored === "light" || stored === "dark") return stored;
    return "dark";
}

function applyTheme(theme: "dark" | "light") {
    if (typeof document === "undefined") return;
    const html = document.documentElement;
    if (theme === "light") {
        html.classList.add("light");
    } else {
        html.classList.remove("light");
    }
}

export function AppProvider({ children }: { children: React.ReactNode }) {
    const [data, setData] = useState<AuditData | null>(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState<string | null>(null);
    const [activeTab, setActiveTabState] = useState<TabKey>("queries");
    const [search, setSearchState] = useState("");
    const [selectedSubgraph, setSelectedSubgraphState] = useState<
        string | null
    >(null);
    const [page, setPage] = useState(1);
    const [sortColumn, setSortColumn] = useState<string | null>(null);
    const [sortDirection, setSortDirection] = useState<"asc" | "desc">("asc");
    const [theme, setThemeState] = useState<"dark" | "light">("dark");

    // Initialize theme from localStorage on mount
    useEffect(() => {
        const initial = getInitialTheme();
        setThemeState(initial);
        applyTheme(initial);
    }, []);

    // Fetch audit data on mount
    useEffect(() => {
        let cancelled = false;

        async function fetchData() {
            try {
                const response = await fetch("/data/audit-data.json");
                if (!response.ok) {
                    throw new Error(
                        `Failed to load audit data: ${response.status} ${response.statusText}`
                    );
                }
                const json: AuditData = await response.json();
                if (!cancelled) {
                    initSubgraphColors(json.repos);
                    setData(json);
                    setLoading(false);
                }
            } catch (err) {
                if (!cancelled) {
                    setError(
                        err instanceof Error
                            ? err.message
                            : "Failed to load audit data"
                    );
                    setLoading(false);
                }
            }
        }

        fetchData();
        return () => {
            cancelled = true;
        };
    }, []);

    const setActiveTab = useCallback((tab: TabKey) => {
        setActiveTabState(tab);
        setPage(1);
    }, []);

    const setSearch = useCallback((value: string) => {
        setSearchState(value);
        setPage(1);
    }, []);

    const setSelectedSubgraph = useCallback((subgraph: string | null) => {
        setSelectedSubgraphState(subgraph);
        setPage(1);
    }, []);

    const setTheme = useCallback((value: "dark" | "light") => {
        setThemeState(value);
        applyTheme(value);
        localStorage.setItem("schema-audit-theme", value);
    }, []);

    const toggleTheme = useCallback(() => {
        setTheme(theme === "dark" ? "light" : "dark");
    }, [theme, setTheme]);

    return (
        <AppContext.Provider
            value={{
                data,
                loading,
                error,
                activeTab,
                setActiveTab,
                search,
                setSearch,
                selectedSubgraph,
                setSelectedSubgraph,
                page,
                setPage,
                sortColumn,
                setSortColumn,
                sortDirection,
                setSortDirection,
                theme,
                setTheme,
                toggleTheme,
            }}
        >
            {children}
        </AppContext.Provider>
    );
}

export function useApp(): AppContextValue {
    const context = useContext(AppContext);
    if (!context) {
        throw new Error("useApp must be used within an AppProvider");
    }
    return context;
}
