import { useUser, useAuth as useClerkAuth } from '@clerk/clerk-react';
import { supabase, setSupabaseToken } from '@/db/supabase';
import { useEffect, useState } from 'react';
import type { Profile } from '@/types/types';

// Implementation of useAuth when Clerk is available
export function useClerkAuthImplementation() {
  const { user: clerkUser, isLoaded: clerkLoaded, isSignedIn } = useUser();
  const { signOut: clerkSignOut, getToken } = useClerkAuth();
  const [profile, setProfile] = useState<Profile | null>(null);
  const [profileLoading, setProfileLoading] = useState(true);

  useEffect(() => {
    async function updateSupabaseSession() {
      if (isSignedIn) {
        // Get token for Supabase (requires 'supabase' template to be set in Clerk dashboard)
        // If template is not set, Clerk returns a generic JWT
        try {
          const token = await getToken({ template: 'supabase' });
          if (token) setSupabaseToken(token);
        } catch (err) {
          console.error('Error getting Clerk token for Supabase:', err);
          // Fallback to regular token if template is missing
          try {
            const token = await getToken();
            if (token) setSupabaseToken(token);
          } catch (tokenErr) {
            console.error('Error getting regular Clerk token:', tokenErr);
          }
        }
      } else {
        setSupabaseToken(null);
      }
    }
    updateSupabaseSession();
  }, [isSignedIn, getToken]);

  useEffect(() => {
    async function fetchProfile() {
      if (!clerkUser?.id) {
        setProfile(null);
        setProfileLoading(false);
        return;
      }

      try {
        // 1. Try to find by clerk_user_id
        let { data, error } = await supabase
          .from('profiles')
          .select('*')
          .eq('clerk_user_id', clerkUser.id)
          .maybeSingle();

        // 2. If not found, try to find by email and link it
        if (!data && !error && clerkUser.primaryEmailAddress?.emailAddress) {
          const email = clerkUser.primaryEmailAddress.emailAddress;
          const { data: emailData, error: emailError } = await supabase
            .from('profiles')
            .select('*')
            .eq('email', email)
            .maybeSingle();
          
          if (emailData && !emailError) {
            console.log('Linking Clerk user to existing profile by email:', email);
            const { data: updatedData, error: updateError } = await supabase
              .from('profiles')
              .update({ 
                clerk_user_id: clerkUser.id,
                avatar_url: clerkUser.imageUrl,
                updated_at: new Date().toISOString()
              })
              .eq('id', emailData.id)
              .select()
              .single();
            
            if (updatedData && !updateError) {
              data = updatedData;
            }
          } else if (!emailData && !emailError) {
            // 3. No profile found -> create one
            console.log('Creating new profile for:', email);

            const username = (
              clerkUser.username ||
              email.split('@')[0].replace(/[^a-zA-Z0-9_]/g, '_') ||
              `user_${clerkUser.id.slice(-8)}`
            );

            // Get role from metadata
            const role = (clerkUser.unsafeMetadata?.role as string) || 'user';

            // Refresh token if missing or expired
            let currentToken: string | null = null;
            try {
              currentToken = await getToken({ template: 'supabase' });
            } catch {
              try { currentToken = await getToken(); } catch { /* ignore */ }
            }
            if (currentToken) setSupabaseToken(currentToken);

            const { data: newData, error: insertError } = await supabase
              .from('profiles')
              .insert({
                clerk_user_id: clerkUser.id,
                email: email,
                username: username,
                full_name: `${clerkUser.firstName || ''} ${clerkUser.lastName || ''}`.trim() || null,
                avatar_url: clerkUser.imageUrl,
                role: role,
                is_active: true,
              })
              .select()
              .single();

            if (newData && !insertError) {
              data = newData;
              // Set profile ID for Supabase auth.getUser() override
              if (typeof window !== 'undefined') {
                (window as any).__CURRENT_PROFILE_ID = newData.id;
              }
              console.log('✅ Profile created:', newData.id);
            } else if (insertError) {
              console.error('❌ Profile creation error:', insertError.message, insertError.code);
            }
          }
        }

        if (error) {
          console.error('Profile fetching error:', error);
        }
        
        // Also set window.__CURRENT_PROFILE_ID when profile is found
        if (data?.id && typeof window !== 'undefined') {
          (window as any).__CURRENT_PROFILE_ID = data.id;
        }
        setProfile(data);
      } catch (err) {
        console.error('Error in useAuth profile fetch:', err);
      } finally {
        setProfileLoading(false);
      }
    }

    if (clerkLoaded) {
      if (isSignedIn) {
        fetchProfile();

        // Handle anonymous trip claim
        const claimTrip = async () => {
          const currentTripId = localStorage.getItem('currentTripId');
          if (currentTripId) {
            try {
              const { tripsApi } = await import('@/db/api');
              await tripsApi.claimAnonymousTrip(currentTripId);
              console.log('✅ Anonymous trip successfully transferred to user');
            } catch (error) {
              console.error('❌ Failed to transfer anonymous trip:', error);
            }
          }
        };
        claimTrip();
      } else {
        setProfile(null);
        setProfileLoading(false);
      }
    }
  }, [clerkUser?.id, clerkLoaded, isSignedIn]);

  const signOut = async () => {
    await clerkSignOut();
  };

  return {
    user: profile,
    clerkUser,
    isLoading: !clerkLoaded || profileLoading,
    isAuthenticated: isSignedIn && !!profile,
    signOut,
    refreshProfile: async () => {
      if (!clerkUser?.id) return;
      const { data } = await supabase
        .from('profiles')
        .select('*')
        .eq('clerk_user_id', clerkUser.id)
        .maybeSingle();
      setProfile(data);
    }
  };
}

// Implementation of useAuth when Clerk is NOT available
export function useGuestAuthImplementation() {
  const [profile, setProfile] = useState<Profile | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const mockSession = localStorage.getItem('mock_session');
    if (mockSession) {
      const fetchMockProfile = async () => {
        try {
          const { data, error } = await supabase
            .from('profiles')
            .select('*')
            .eq('id', mockSession)
            .maybeSingle();
          if (data) setProfile(data);
        } catch (err) {
          console.error('Error fetching mock profile:', err);
        } finally {
          setLoading(false);
        }
      };
      fetchMockProfile();
    } else {
      setLoading(false);
    }
  }, []);

  const signOut = async () => {
    localStorage.removeItem('mock_session');
    setProfile(null);
  };

  const refreshProfile = async () => {
    if (!profile?.id) return;
    const { data } = await supabase
      .from('profiles')
      .select('*')
      .eq('id', profile.id)
      .maybeSingle();
    setProfile(data);
  };

  const mockLogin = async (id: string) => {
    localStorage.setItem('mock_session', id);
    const { data } = await supabase
      .from('profiles')
      .select('*')
      .eq('id', id)
      .maybeSingle();
    if (data) setProfile(data);
  };

  return {
    user: profile,
    clerkUser: null,
    isLoading: loading,
    isAuthenticated: !!profile,
    signOut,
    refreshProfile,
    mockLogin
  };
}
