import { create } from 'zustand';
import type { Session, User } from '@supabase/supabase-js';
import * as WebBrowser from 'expo-web-browser';
import * as Linking from 'expo-linking';
import { supabase } from '../lib/supabase';

WebBrowser.maybeCompleteAuthSession();

type AuthState = {
  user: User | null;
  session: Session | null;
  loading: boolean;

  init: () => Promise<void>;
  signInWithPassword: (email: string, password: string) => Promise<{ error?: string }>;
  signUp: (
    email: string,
    password: string,
    metadata: { username: string; firstName?: string; lastName?: string; avatarId: string; avatarUrl: string }
  ) => Promise<{ error?: string }>;
  signOut: () => Promise<void>;
  signInWithOAuth: (provider: 'google' | 'apple') => Promise<{ error?: string }>;
  resetPasswordForEmail: (email: string) => Promise<{ error?: string }>;
  verifyOtp: (email: string, token: string) => Promise<{ error?: string }>;
  resendConfirmation: (email: string) => Promise<{ error?: string }>;
};

export const useAuthStore = create<AuthState>((set) => ({
  user: null,
  session: null,
  loading: true,

  init: async () => {
    const { data } = await supabase.auth.getSession();
    set({
      session: data.session,
      user: data.session?.user ?? null,
      loading: false,
    });

    supabase.auth.onAuthStateChange((_event, session) => {
      set({ session, user: session?.user ?? null });
    });
  },

  signInWithPassword: async (email, password) => {
    const { data, error } = await supabase.auth.signInWithPassword({ email, password });
    if (error) return { error: error.message };
    set({ session: data.session, user: data.user });
    return {};
  },

  signUp: async (email, password, metadata) => {
    const { data, error } = await supabase.auth.signUp({
      email,
      password,
      options: {
        data: {
          username: metadata.username,
          first_name: metadata.firstName ?? '',
          last_name: metadata.lastName ?? '',
          avatar_id: metadata.avatarId,
          avatar_url: metadata.avatarUrl,
        },
        // Deep-link redirect for email confirmation — scheme registered in app.config.ts
        emailRedirectTo: 'rebreak://auth/confirm',
      },
    });
    if (error) return { error: error.message };
    set({ session: data.session, user: data.user ?? null });
    return {};
  },

  signOut: async () => {
    await supabase.auth.signOut();
    set({ session: null, user: null });
  },

  signInWithOAuth: async (provider) => {
    const redirectUri = Linking.createURL('auth/callback');

    if (provider === 'apple') {
      // TODO: configure Apple Sign-In
      // Requires expo-apple-authentication to be installed + Apple Developer entitlement.
      // Apple Client ID = Bundle ID (org.rebreak.app) for native flow.
      // For now we fall through to the Supabase OAuth web flow as a temporary path.
    }

    const { data, error } = await supabase.auth.signInWithOAuth({
      provider,
      options: {
        redirectTo: redirectUri,
        skipBrowserRedirect: true,
      },
    });

    if (error) return { error: error.message };
    if (!data.url) return { error: 'Kein OAuth-URL erhalten' };

    const result = await WebBrowser.openAuthSessionAsync(data.url, redirectUri);

    if (result.type !== 'success') {
      return result.type === 'cancel' ? {} : { error: 'OAuth fehlgeschlagen' };
    }

    // Extract tokens from the deep-link URL fragment
    const url = result.url;
    const params = new URLSearchParams(url.split('#')[1] ?? url.split('?')[1] ?? '');
    const accessToken = params.get('access_token');
    const refreshToken = params.get('refresh_token');

    if (!accessToken || !refreshToken) {
      // Session may already be set via onAuthStateChange — check
      const { data: sessionData } = await supabase.auth.getSession();
      if (sessionData.session) {
        set({ session: sessionData.session, user: sessionData.session.user });
        return {};
      }
      return { error: 'Session konnte nicht gelesen werden' };
    }

    const { data: sessionData, error: sessionError } = await supabase.auth.setSession({
      access_token: accessToken,
      refresh_token: refreshToken,
    });

    if (sessionError) return { error: sessionError.message };
    set({ session: sessionData.session, user: sessionData.session?.user ?? null });
    return {};
  },

  resetPasswordForEmail: async (email) => {
    const { error } = await supabase.auth.resetPasswordForEmail(email, {
      redirectTo: 'rebreak://auth/reset-password',
    });
    if (error) return { error: error.message };
    return {};
  },

  verifyOtp: async (email, token) => {
    const { data, error } = await supabase.auth.verifyOtp({
      email,
      token,
      type: 'signup',
    });
    if (error) return { error: error.message };
    if (!data.session) return { error: 'Bestätigung fehlgeschlagen – bitte erneut versuchen.' };
    set({ session: data.session, user: data.user ?? null });
    return {};
  },

  resendConfirmation: async (email) => {
    const { error } = await supabase.auth.resend({ type: 'signup', email });
    if (error) return { error: error.message };
    return {};
  },
}));
