import React, { createContext, useContext, useEffect, useMemo, useState } from 'react';
import type { ReactNode } from 'react';
import { mobileTelemetry, trackMobileError } from '@/lib/telemetry';
import {
  clearPlatformSession,
  loginPlatformSession,
  restorePlatformSession,
  type PlatformAuthUser,
  type StoredPlatformSession,
} from '@/lib/platformAuth';

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

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

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

export function MobileAuthProvider({ children }: { children: ReactNode }) {
  const [session, setSession] = useState<StoredPlatformSession | null>(null);
  const [user, setUser] = useState<PlatformAuthUser | 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() {
      try {
        if (!active) {
          return;
        }
        const restored = await restorePlatformSession();
        setSession(restored);
        setUser(restored?.user ?? null);
        if (restored?.user) {
          mobileTelemetry.trackEvent('info', 'auth', 'session_restored', {
            userId: restored.user.id,
          });
          setProfile(buildProfile(restored.user));
          setError(null);
          setLoading(false);
        } else {
          setLoading(false);
        }
      } catch (bootstrapError) {
        trackMobileError('auth', 'session_restore_failed', bootstrapError);
        setError(bootstrapError instanceof Error ? bootstrapError.message : 'Failed to restore session');
        setLoading(false);
      }
    }

    void bootstrap();

    return () => {
      active = false;
    };
  }, []);

  function buildProfile(nextUser: PlatformAuthUser | null): MobileUserProfile | null {
    if (!nextUser?.id) {
      return null;
    }

    const displayName = String(nextUser.displayName || '').trim();
    const parts = displayName ? displayName.split(/\s+/) : [];

    return {
      user_id: nextUser.id,
      first_name: parts[0] || undefined,
      last_name: parts.slice(1).join(' ') || undefined,
      email: nextUser.email,
      role: nextUser.role,
      trade_enable: true,
    };
  }

  async function signIn(email: string, password: string) {
    setLoading(true);
    setError(null);
    try {
      const nextSession = await loginPlatformSession(email, password);
      setSession(nextSession);
      setUser(nextSession.user);
      setProfile(buildProfile(nextSession.user));
      setError(null);
      mobileTelemetry.trackEvent('info', 'auth', 'sign_in_succeeded', {
        message: email,
        userId: nextSession.user.id,
      });
      return {};
    } catch (authError) {
      const message = authError instanceof Error ? authError.message : 'Sign in failed';
      setError(message);
      trackMobileError('auth', 'sign_in_failed', authError, { email });
      return { error: message };
    } finally {
      setLoading(false);
    }
  }

  async function signOut() {
    setLoading(true);
    try {
      await clearPlatformSession();
      mobileTelemetry.trackEvent('info', 'auth', 'sign_out_succeeded', {
        userId: user?.id,
      });
    } finally {
      setProfile(null);
      setSession(null);
      setUser(null);
      setLoading(false);
    }
  }

  async function invalidateSession(reason: string) {
    setLoading(true);
    mobileTelemetry.trackEvent('warn', 'auth', 'session_invalidated', {
      message: reason,
      userId: user?.id,
    });

    try {
      await clearPlatformSession();
    } catch (invalidateError) {
      trackMobileError('auth', 'session_invalidation_signout_failed', invalidateError);
    } finally {
      setProfile(null);
      setSession(null);
      setUser(null);
      setError(reason);
      setLoading(false);
    }
  }

  async function refreshProfile() {
    if (!session) {
      return;
    }
    setLoading(true);
    try {
      const restored = await restorePlatformSession();
      const nextUser = restored?.user ?? null;
      setSession(restored);
      setUser(nextUser);
      setProfile(buildProfile(nextUser));
      setError(null);
    } catch (refreshError) {
      setError(refreshError instanceof Error ? refreshError.message : 'Failed to refresh profile');
      trackMobileError('auth', 'profile_refresh_failed', refreshError, { userId: user?.id || 'unknown' });
    } finally {
      setLoading(false);
    }
  }

  const value = useMemo<MobileAuthContextValue>(
    () => ({
      session,
      user,
      profile,
      loading,
      error,
      signIn,
      signOut,
      invalidateSession,
      refreshProfile,
      accessToken: session?.accessToken ?? 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;
}
