import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
import type { ReactNode } from 'react';
import type { Session, User } from '@supabase/supabase-js';
import { mobileSupabase } from '@/lib/supabase';
import { tableNameUsers } from '@/lib/tables';

export interface MobileUserProfile {
  user_id: string;
  first_name?: string;
  last_name?: string;
  email?: string;
  role?: string;
  trade_enable?: boolean;
}

interface MobileAuthContextValue {
  session: Session | null;
  user: User | null;
  profile: MobileUserProfile | null;
  loading: boolean;
  error: string | null;
  signIn: (email: string, password: string) => Promise<{ error?: string }>;
  signOut: () => Promise<void>;
  refreshProfile: () => Promise<void>;
  accessToken: string | null;
}

const MobileAuthContext = createContext<MobileAuthContextValue | null>(null);

export function MobileAuthProvider({ children }: { children: ReactNode }) {
  const [session, setSession] = useState<Session | null>(null);
  const [user, setUser] = useState<User | null>(null);
  const [profile, setProfile] = useState<MobileUserProfile | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    let active = true;

    async function bootstrap() {
      const { data } = await mobileSupabase.auth.getSession();
      if (!active) {
        return;
      }
      setSession(data.session ?? null);
      setUser(data.session?.user ?? null);
      if (data.session?.user) {
        await fetchProfile(data.session.user.id);
      } else {
        setLoading(false);
      }
    }

    void bootstrap();

    const { data: authListener } = mobileSupabase.auth.onAuthStateChange((_event, nextSession) => {
      setSession(nextSession);
      setUser(nextSession?.user ?? null);
      if (nextSession?.user) {
        void fetchProfile(nextSession.user.id);
      } else {
        setProfile(null);
        setLoading(false);
      }
    });

    return () => {
      active = false;
      authListener.subscription.unsubscribe();
    };
  }, []);

  async function fetchProfile(userId: string) {
    try {
      const { data, error: profileError } = await mobileSupabase
        .from(tableNameUsers)
        .select('user_id,first_name,last_name,email,role,trade_enable')
        .eq('user_id', userId)
        .single();

      if (profileError) {
        setError(profileError.message);
      } else {
        setProfile((data || null) as MobileUserProfile | null);
        setError(null);
      }
    } catch (fetchError) {
      setError(fetchError instanceof Error ? fetchError.message : 'Failed to load profile');
    } finally {
      setLoading(false);
    }
  }

  async function signIn(email: string, password: string) {
    setLoading(true);
    setError(null);
    const { error: authError } = await mobileSupabase.auth.signInWithPassword({ email, password });
    if (authError) {
      setError(authError.message);
      setLoading(false);
      return { error: authError.message };
    }
    return {};
  }

  async function signOut() {
    setLoading(true);
    await mobileSupabase.auth.signOut();
    setProfile(null);
    setSession(null);
    setUser(null);
    setLoading(false);
  }

  async function refreshProfile() {
    if (!user) {
      return;
    }
    setLoading(true);
    await fetchProfile(user.id);
  }

  const value = useMemo<MobileAuthContextValue>(
    () => ({
      session,
      user,
      profile,
      loading,
      error,
      signIn,
      signOut,
      refreshProfile,
      accessToken: session?.access_token ?? null,
    }),
    [session, user, profile, loading, error]
  );

  return <MobileAuthContext.Provider value={value}>{children}</MobileAuthContext.Provider>;
}

export function useMobileAuth() {
  const context = useContext(MobileAuthContext);
  if (!context) {
    throw new Error('useMobileAuth must be used within a MobileAuthProvider');
  }
  return context;
}
