'use client';

import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
import { useRouter, usePathname } from 'next/navigation';
import {
  getCurrentSession,
  getCurrentProfile,
  logoutUploader,
  isLoggedIn as checkIsLoggedIn,
} from '@/lib/services/uploadPortalService';
import { AuthSession, UploaderProfile } from '@/types';

interface AuthContextType {
  session: AuthSession | null;
  profile: UploaderProfile | null;
  isLoading: boolean;
  isAuthenticated: boolean;
  login: (session: AuthSession) => void;
  logout: () => void;
  refreshProfile: () => Promise<void>;
}

const AuthContext = createContext<AuthContextType | undefined>(undefined);

// Pages that don't require authentication
const PUBLIC_PATHS = [
  '/artist-portal',
  '/artist-portal/login',
  '/artist-portal/register',
];

export function AuthProvider({ children }: { children: React.ReactNode }) {
  const router = useRouter();
  const pathname = usePathname();
  const [session, setSession] = useState<AuthSession | null>(null);
  const [profile, setProfile] = useState<UploaderProfile | null>(null);
  const [isLoading, setIsLoading] = useState(true);

  const isAuthenticated = session !== null;

  // Check authentication on mount and route changes
  useEffect(() => {
    const checkAuth = async () => {
      setIsLoading(true);
      
      const currentSession = getCurrentSession();
      setSession(currentSession);
      
      if (currentSession) {
        const userProfile = await getCurrentProfile();
        setProfile(userProfile);
      } else {
        setProfile(null);
      }
      
      setIsLoading(false);
    };

    checkAuth();
  }, [pathname]);

  // Redirect logic
  useEffect(() => {
    if (isLoading) return;

    const isPublicPath = PUBLIC_PATHS.some(
      (path) => pathname === path || pathname?.startsWith(path + '/')
    );

    // If not authenticated and trying to access protected page
    if (!isAuthenticated && !isPublicPath && pathname?.startsWith('/artist-portal')) {
      // Check if it's a protected path (dashboard, upload, etc.)
      if (
        pathname?.includes('/dashboard') ||
        pathname?.includes('/upload') ||
        pathname?.includes('/artists/') ||
        pathname?.includes('/albums/') ||
        pathname?.includes('/submissions/')
      ) {
        router.push('/artist-portal/login');
      }
    }
  }, [isAuthenticated, isLoading, pathname, router]);

  const login = useCallback((newSession: AuthSession) => {
    setSession(newSession);
  }, []);

  const logout = useCallback(() => {
    logoutUploader();
    setSession(null);
    setProfile(null);
    router.push('/artist-portal/login');
  }, [router]);

  const refreshProfile = useCallback(async () => {
    if (session) {
      const userProfile = await getCurrentProfile();
      setProfile(userProfile);
    }
  }, [session]);

  return (
    <AuthContext.Provider
      value={{
        session,
        profile,
        isLoading,
        isAuthenticated,
        login,
        logout,
        refreshProfile,
      }}
    >
      {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;
}

// HOC for protecting pages
export function withAuth<P extends object>(
  Component: React.ComponentType<P>
): React.FC<P> {
  return function AuthenticatedComponent(props: P) {
    const { isAuthenticated, isLoading } = useAuth();
    const router = useRouter();

    useEffect(() => {
      if (!isLoading && !isAuthenticated) {
        router.push('/artist-portal/login');
      }
    }, [isAuthenticated, isLoading, router]);

    if (isLoading) {
      return (
        <div className="min-h-screen bg-background flex items-center justify-center">
          <div className="text-center">
            <div className="w-8 h-8 border-2 border-primary border-t-transparent rounded-full animate-spin mx-auto mb-4" />
            <p className="text-gray-400">Loading...</p>
          </div>
        </div>
      );
    }

    if (!isAuthenticated) {
      return null;
    }

    return <Component {...props} />;
  };
}
