/**
 * AuthContext - Firebase Authentication State Management
 *
 * Provides authentication state, tier info, and methods throughout the app
 */

import { createContext, useContext, useEffect, useState, useCallback } from "react";
import {
    createUserWithEmailAndPassword,
    signInWithEmailAndPassword,
    signOut,
    onAuthStateChanged,
} from "firebase/auth";
import { auth } from "../firebase/config";
import { getAccount } from "../api/account";

const AuthContext = createContext();

const DEFAULT_TIER_LIMITS = {
    max_addresses: 1,
    max_alert_types: 1,
    allowed_channels: ["email"],
};

/**
 * Hook to access auth context
 * @returns {Object} Auth context value
 */
export function useAuth() {
    const context = useContext(AuthContext);
    if (!context) {
        throw new Error("useAuth must be used within AuthProvider");
    }
    return context;
}

/**
 * AuthProvider - Wraps app and provides auth state + tier info
 */
export function AuthProvider({ children }) {
    const [currentUser, setCurrentUser] = useState(null);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);

    const [userTier, setUserTier] = useState("free");
    const [tierLimits, setTierLimits] = useState(DEFAULT_TIER_LIMITS);
    const [addressCount, setAddressCount] = useState(0);
    const [subscriptionStatus, setSubscriptionStatus] = useState("none");

    const refreshAccount = useCallback(async () => {
        try {
            const data = await getAccount();
            setUserTier(data.subscription_tier || "free");
            setTierLimits(data.tier_limits || DEFAULT_TIER_LIMITS);
            setAddressCount(data.address_count || 0);
            setSubscriptionStatus(data.subscription_status || "none");
        } catch {
            // account fetch can fail during onboarding before subscription is active
        }
    }, []);

    async function signup(email, password) {
        try {
            setError(null);
            const result = await createUserWithEmailAndPassword(
                auth,
                email,
                password,
            );
            return result.user;
        } catch (err) {
            setError(err.message);
            throw err;
        }
    }

    async function login(email, password) {
        try {
            setError(null);
            const result = await signInWithEmailAndPassword(
                auth,
                email,
                password,
            );
            return result.user;
        } catch (err) {
            setError(err.message);
            throw err;
        }
    }

    async function logout() {
        try {
            setError(null);
            setUserTier("free");
            setTierLimits(DEFAULT_TIER_LIMITS);
            setAddressCount(0);
            setSubscriptionStatus("none");
            await signOut(auth);
        } catch (err) {
            setError(err.message);
            throw err;
        }
    }

    useEffect(() => {
        const unsubscribe = onAuthStateChanged(auth, (user) => {
            setCurrentUser(user);
            setLoading(false);
            if (user) {
                refreshAccount();
            }
        });
        return unsubscribe;
    }, [refreshAccount]);

    const isSubscribed =
        subscriptionStatus === "active" || subscriptionStatus === "trialing";

    const value = {
        currentUser,
        signup,
        login,
        logout,
        error,
        loading,
        userTier,
        tierLimits,
        addressCount,
        subscriptionStatus,
        isSubscribed,
        refreshAccount,
    };

    return (
        <AuthContext.Provider value={value}>
            {!loading && children}
        </AuthContext.Provider>
    );
}
