import { supabaseClient, supabaseAdmin } from "../config/supabaseClient";
import { Provider, Session } from "@supabase/supabase-js";

// Client-side auth operations
export const authService = {
  /**
   * Authenticates a user with email and password
   * @param email - User's email address
   * @param password - User's password
   * @returns Promise containing the sign in response
   * @example
   * const { data, error } = await authService.signIn('user@example.com', 'password123')
   */
  async signIn(email: string, password: string) {
    return await supabaseClient.auth.signInWithPassword({ email, password });
  },

  /**
   * Signs out the currently authenticated user
   * @returns Promise containing the sign out response
   * @example
   * await authService.signOutCurrentUser()
   */
  async signOutCurrentUser() {
    return await supabaseClient.auth.signOut();
  },

  /**
   * Retrieves the currently authenticated user's details
   * @returns Promise containing the current user data
   * @example
   * const { data: { user }, error } = await authService.getCurrentUser()
   */
  async getCurrentUser() {
    return await supabaseClient.auth.getUser();
  },

   async signUp(email: string, password: string) {
    // Check if user exists
    const { data: existingUser } = await supabaseClient
      .from('users')
      .select()
      .eq('email', email)
      .single();

    if (existingUser) {
      throw new Error('User with this email already exists');
    }

    return await supabaseClient.auth.signUp({
      email,
      password,
      options: {
        emailRedirectTo: `${window.location.origin}/auth/callback`,
      },
    });
  },

  /**
   * Signs in with a third-party provider
   * @param provider - The authentication provider (google, github, etc.)
   * @returns Promise containing the sign in response
   * @example
   * await authService.signInWithProvider('google')
   */
  async signInWithProvider(provider: Provider) {
    return await supabaseClient.auth.signInWithOAuth({
      provider,
      options: {
        redirectTo: `${window.location.origin}/auth/callback`,
        scopes: 'email profile',
      },
    });
  },

  /**
   * Sends a password reset email
   * @param email - User's email address
   * @returns Promise containing the reset response
   * @example
   * const { data, error } = await authService.resetPassword('user@example.com')
   */
  async resetPassword(email: string) {
    return await supabaseClient.auth.resetPasswordForEmail(email, {
      redirectTo: `${window.location.origin}/auth/reset-password`,
    });
  },

  /**
   * Updates user's password
   * @param newPassword - New password
   * @returns Promise containing the update response
   * @example
   * const { data, error } = await authService.updatePassword('newPassword123')
   */
  async updatePassword(newPassword: string) {
    return await supabaseClient.auth.updateUser({
      password: newPassword,
    });
  },
};

// Server-side admin auth operations
export const authAdminService = {
  /**
   * Creates a new user account (Server-side only)
   * @param email - New user's email address
   * @param password - New user's password
   * @returns Promise containing the created user data
   * @throws Error if called from client-side
   * @example
   * // Only in API routes or server-side code
   * const { data, error } = await authAdminService.createUser('newuser@example.com', 'password123')
   */
  async createUser(email: string, password: string) {
    if (!supabaseAdmin) {
      throw new Error("Admin operations can only be performed server-side");
    }
    return await supabaseAdmin.auth.admin.createUser({ 
      email, 
      password, 
      email_confirm: true 
    });
  },

  /**
   * Deletes a user account by ID (Server-side only)
   * @param userId - The UUID of the user to delete
   * @returns Promise containing the deletion response
   * @throws Error if called from client-side
   * @example
   * // Only in API routes or server-side code
   * await authAdminService.deleteUser('user-uuid-here')
   */
  async deleteUser(userId: string) {
    if (!supabaseAdmin) {
      throw new Error("Admin operations can only be performed server-side");
    }
    return await supabaseAdmin.auth.admin.deleteUser(userId);
  },

  /**
   * Retrieves user details by ID (Server-side only)
   * @param userId - The UUID of the user to fetch
   * @returns Promise containing the user data
   * @throws Error if called from client-side
   * @example
   * // Only in API routes or server-side code
   * const { data: { user }, error } = await authAdminService.getUserById('user-uuid-here')
   */
  async getUserById(userId: string) {
    if (!supabaseAdmin) {
      throw new Error("Admin operations can only be performed server-side");
    }
    return await supabaseAdmin.auth.admin.getUserById(userId);
  },

  /**
   * Forces sign out for a specific user (Server-side only)
   * @param userId - The UUID of the user to sign out
   * @returns Promise containing the sign out response
   * @throws Error if called from client-side
   * @example
   * // Only in API routes or server-side code
   * await authAdminService.signOutUser('user-uuid-here')
   */
  async signOutUser(userId: string) {
    if (!supabaseAdmin) {
      throw new Error("Admin operations can only be performed server-side");
    }
    return await supabaseAdmin.auth.admin.signOut(userId);
  },

  async checkUserExists(email: string) {
    if (!supabaseAdmin) {
      throw new Error("Admin operations can only be performed server-side");
    }
    const { data, error } = await supabaseAdmin
      .from('users')
      .select('id')
      .eq('email', email)
      .single();
    
    return { exists: !!data, error };
  },

  /**
   * Updates user's email verification status (Server-side only)
   * @param userId - The UUID of the user
   * @param verified - Boolean indicating verification status
   * @throws Error if called from client-side
   * @example
   * await authAdminService.updateEmailVerification('user-uuid', true)
   */
  async updateEmailVerification(userId: string, verified: boolean) {
    if (!supabaseAdmin) {
      throw new Error("Admin operations can only be performed server-side");
    }
    return await supabaseAdmin.auth.admin.updateUserById(userId, {
      email_confirm: verified,
    });
  },

  /**
   * Initialize auth session from existing session data
   * @returns Promise containing the session data
   * @example
   * const { data: { session }, error } = await authService.initializeSession()
   */
  async initializeSession() {
    return await supabaseClient.auth.getSession();
  },

  /**
   * Set up an auth state change listener
   * @param callback - Function to handle auth state changes
   * @returns Cleanup function to remove the listener
   * @example
   * const unsubscribe = authService.onAuthStateChange((event, session) => {
   *   console.log('Auth event:', event, session)
   * })
   */
  onAuthStateChange(callback: (event: string, session: Session | null) => void) {
    return supabaseClient.auth.onAuthStateChange(callback);
  },
};