"use client";

import React, { createContext, useContext, useState, useEffect } from "react";
import { api } from "@/lib/api";

interface User {
  id: number;
  name: string;
  email: string;
  phone?: string;
  address?: string;
  city?: string;
  zip?: string;
}

interface AuthContextType {
  user: User | null;
  token: string | null;
  isLoading: boolean;
  login: (credentials: any) => Promise<void>;
  register: (data: any) => Promise<void>;
  logout: () => Promise<void>;
}

const AuthContext = createContext<AuthContextType | undefined>(undefined);

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const [user, setUser] = useState<User | null>(null);
  const [token, setToken] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    const initAuth = async () => {
      // Check for token and user in localStorage immediately
      if (typeof window !== 'undefined') {
        const savedToken = localStorage.getItem("auth_token");
        const savedUser = localStorage.getItem("auth_user");
        
        if (savedToken) {
          setToken(savedToken);
          if (savedUser) {
            try {
              setUser(JSON.parse(savedUser));
            } catch (e) {
              console.error("Failed to parse saved user:", e);
            }
          }
          // Still fetch fresh user data to validate token
          await fetchUser(savedToken);
        } else {
          setIsLoading(false);
        }
      } else {
        setIsLoading(false);
      }
    };
    initAuth();
  }, []);

  const fetchUser = async (authToken: string) => {
    try {
      const response = await api.getUser(authToken);
      if (response && (response as any).data) {
        setUser((response as any).data);
        localStorage.setItem("auth_user", JSON.stringify((response as any).data));
      } else {
        // If server didn't return user but we have a cached user, keep it
        const cachedUser = localStorage.getItem("auth_user");
        if (cachedUser) {
          try {
            setUser(JSON.parse(cachedUser));
          } catch {}
        }
      }
    } catch (error) {
      // Network or transient error: keep existing session instead of logging out
      const cachedUser = localStorage.getItem("auth_user");
      if (cachedUser) {
        try {
          setUser(JSON.parse(cachedUser));
        } catch {}
      }
      console.warn("fetchUser failed, preserving local session");
    } finally {
      setIsLoading(false);
    }
  };

  const login = async (credentials: any) => {
    setIsLoading(true);
    try {
      const response = await api.login(credentials);
      if (response.data) {
        const { user: userData, access_token } = response.data;
        // Set local storage first to ensure it's there before state update
        localStorage.setItem("auth_token", access_token);
        localStorage.setItem("auth_user", JSON.stringify(userData));
        setToken(access_token);
        setUser(userData);
      }
    } catch (error) {
      console.error("Login failed:", error);
      throw error;
    } finally {
      setIsLoading(false);
    }
  };

  const register = async (data: any) => {
    setIsLoading(true);
    try {
      const response = await api.register(data);
      if (response.data) {
        const { user: userData, access_token } = response.data;
        // Set local storage first to ensure it's there before state update
        localStorage.setItem("auth_token", access_token);
        localStorage.setItem("auth_user", JSON.stringify(userData));
        setToken(access_token);
        setUser(userData);
      }
    } catch (error) {
      console.error("Registration failed:", error);
      throw error;
    } finally {
      setIsLoading(false);
    }
  };

  const logoutLocal = () => {
    setUser(null);
    setToken(null);
    if (typeof window !== 'undefined') {
      localStorage.removeItem("auth_token");
      localStorage.removeItem("auth_user");
    }
  };

  const logout = async () => {
    if (token) {
      try {
        await api.logout(token);
      } catch (error) {
        console.error("Logout failed on server:", error);
      }
    }
    logoutLocal();
  };

  return (
    <AuthContext.Provider
      value={{
        user,
        token,
        isLoading,
        login,
        register,
        logout,
      }}
    >
      {children}
    </AuthContext.Provider>
  );
}

export function useAuth() {
  const context = useContext(AuthContext);
  if (context === undefined) {
    throw new Error("useAuth must be used within an AuthProvider");
  }
  return context;
}
