import React, { useState, useEffect } from "react";

export interface User {
  id: string;
  email?: string;
  user_metadata?: any;
}

export interface AuthState {
  user: User | null;
  loading: boolean;
  authenticated: boolean;
}

export function useAuth() {
  const [authState, setAuthState] = useState<AuthState>({
    user: null,
    loading: true,
    authenticated: false,
  });

  const checkAuth = async () => {
    try {
      const response = await fetch("/api/auth/check", {
        method: "GET",
        credentials: "include",
      });

      if (response.ok) {
        const data = await response.json();
        if (data.authenticated) {
          setAuthState({
            user: data.user,
            loading: false,
            authenticated: true,
          });
          return data.user;
        }
      }

      setAuthState({
        user: null,
        loading: false,
        authenticated: false,
      });
      return null;
    } catch (error) {
      console.error("Auth check failed:", error);
      setAuthState({
        user: null,
        loading: false,
        authenticated: false,
      });
      return null;
    }
  };

  const login = async (accessToken: string, refreshToken?: string) => {
    try {
      const response = await fetch("/api/auth/callback", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        credentials: "include",
        body: JSON.stringify({
          access_token: accessToken,
          refresh_token: refreshToken,
        }),
      });

      if (response.ok) {
        const data = await response.json();
        setAuthState({
          user: data.user,
          loading: false,
          authenticated: true,
        });
        return data.user;
      } else {
        throw new Error("Login failed");
      }
    } catch (error) {
      console.error("Login failed:", error);
      setAuthState({
        user: null,
        loading: false,
        authenticated: false,
      });
      throw error;
    }
  };

  const logout = async () => {
    try {
      await fetch("/api/auth/logout", {
        method: "POST",
        credentials: "include",
      });
    } catch (error) {
      console.error("Logout request failed:", error);
    } finally {
      setAuthState({
        user: null,
        loading: false,
        authenticated: false,
      });
      // Redirect to login page
      window.location.href = "/login";
    }
  };

  const refreshToken = async () => {
    try {
      const response = await fetch("/api/auth/refresh", {
        method: "POST",
        credentials: "include",
      });

      if (response.ok) {
        const data = await response.json();
        setAuthState({
          user: data.user,
          loading: false,
          authenticated: true,
        });
        return data.user;
      } else {
        // Refresh failed, user needs to login again
        setAuthState({
          user: null,
          loading: false,
          authenticated: false,
        });
        return null;
      }
    } catch (error) {
      console.error("Token refresh failed:", error);
      setAuthState({
        user: null,
        loading: false,
        authenticated: false,
      });
      return null;
    }
  };

  const getUserFromCookie = () => {
    if (typeof window === "undefined") return null;

    try {
      const userInfoCookie = document.cookie
        .split("; ")
        .find((row) => row.startsWith("sb-user-info="));

      if (userInfoCookie) {
        const userInfo = decodeURIComponent(userInfoCookie.split("=")[1]);
        return JSON.parse(userInfo);
      }
    } catch (error) {
      console.error("Error reading user cookie:", error);
    }

    return null;
  };

  useEffect(() => {
    // Try to get user from cookie first for faster initial load
    const cachedUser = getUserFromCookie();
    if (cachedUser) {
      setAuthState({
        user: cachedUser,
        loading: true, // Still check with server
        authenticated: true,
      });
    }

    // Then verify with server
    checkAuth();
  }, []);

  return {
    ...authState,
    checkAuth,
    login,
    logout,
    refreshToken,
    getUserFromCookie,
  };
}

// Higher-order component for protecting routes
export function withAuth<T extends object>(Component: React.ComponentType<T>) {
  return function AuthenticatedComponent(props: T) {
    const { authenticated, loading, user } = useAuth();

    useEffect(() => {
      if (!loading && !authenticated) {
        // Redirect to login if not authenticated
        const currentPath = window.location.pathname;
        window.location.href = `/login?redirect_to=${encodeURIComponent(
          currentPath,
        )}`;
      }
    }, [authenticated, loading]);

    if (loading) {
      return <div>Loading...</div>;
    }

    if (!authenticated) {
      return <div>Redirecting to login...</div>;
    }

    return <Component {...props} user={user} />;
  };
}
