import {
  signInWithEmailAndPassword,
  createUserWithEmailAndPassword,
  signOut,
  updateProfile,
  sendEmailVerification,
  GoogleAuthProvider,
  signInWithPopup,
  User as FirebaseUser,
} from 'firebase/auth';
import {
  doc,
  setDoc,
  getDoc,
  updateDoc,
  serverTimestamp,
  collection,
  query,
  where,
  getDocs,
} from 'firebase/firestore';
import { auth, db } from './firebase';
import { User, MembershipTier, UserRole, LoginCredentials, SignupCredentials } from '../types/auth';

// Super Admin Configuration
const SUPER_ADMINS = [
  'twkeramik@gmail.com',
  'hrabina.wasowska@gmail.com'
] as const;

// Check if user is super admin
export const isSuperAdmin = (email: string): boolean => {
  return SUPER_ADMINS.includes(email as any);
};

// Get user role based on email
export const getUserRole = (email: string): UserRole => {
  return isSuperAdmin(email) ? UserRole.SUPER_ADMIN : UserRole.USER;
};

// Test function to verify Firebase connection
export const testFirebaseConnection = async () => {
  try {
    const currentUser = auth.currentUser;
    
    return {
      success: true,
      currentUser: currentUser ? currentUser.uid : null,
      config: {
        projectId: auth.app.options.projectId,
        authDomain: auth.app.options.authDomain,
        apiKey: auth.app.options.apiKey?.substring(0, 10) + '...',
      },
      projectId: auth.app.options.projectId,
      authDomain: auth.app.options.authDomain,
    };
  } catch (error: any) {
    return {
      success: false,
      error: error.message,
    };
  }
};

// Create user document in Firestore
const createUserDocument = async (user: FirebaseUser, additionalData?: any) => {
  if (!user) return;

  const userRef = doc(db, 'users', user.uid);
  const userSnap = await getDoc(userRef);

  if (!userSnap.exists()) {
    const { email, displayName, photoURL } = user;
    const createdAt = serverTimestamp();
    const userRole = getUserRole(email || '');

    try {
      await setDoc(userRef, {
        id: user.uid,
        email,
        name: displayName || additionalData?.name || 'Użytkownik',
        membershipTier: MembershipTier.ODDECH,
        role: userRole,
        createdAt,
        avatar: photoURL || null,
        isEmailVerified: user.emailVerified,
        ...additionalData,
      });
    } catch (error) {
      console.error('Error creating user document:', error);
      throw new Error('Błąd podczas tworzenia profilu użytkownika');
    }
  }

  return userRef;
};

// Get user data from Firestore
export const getUserData = async (userId: string): Promise<User | null> => {
  try {
    const userRef = doc(db, 'users', userId);
    const userSnap = await getDoc(userRef);

    if (userSnap.exists()) {
      const data = userSnap.data();
      return {
        ...data,
        role: data.role || UserRole.USER, // Default to USER if role is not set
        createdAt: data.createdAt?.toDate() || new Date(),
      } as User;
    }
    return null;
  } catch (error) {
    console.error('Error getting user data:', error);
    return null;
  }
};

// Email/Password Sign In
export const signInWithEmail = async ({ email, password }: LoginCredentials) => {
  try {
    // Validate inputs
    if (!email || !password) {
      throw new Error('Email i hasło są wymagane');
    }

    if (password.length < 6) {
      throw new Error('Hasło musi mieć co najmniej 6 znaków');
    }

    const result = await signInWithEmailAndPassword(auth, email, password);
    const userData = await getUserData(result.user.uid);
    return { user: result.user, userData };
  } catch (error: any) {
    console.error('Login error details:', {
      code: error.code,
      message: error.message,
      stack: error.stack
    });
    
    // Handle specific Firebase errors
    switch (error.code) {
      case 'auth/configuration-not-found':
        throw new Error('Problem z konfiguracją Firebase. Sprawdź ustawienia projektu.');
      case 'auth/user-not-found':
        throw new Error('Nie znaleziono użytkownika z tym adresem email');
      case 'auth/wrong-password':
        throw new Error('Nieprawidłowe hasło');
      case 'auth/invalid-email':
        throw new Error('Nieprawidłowy format email');
      case 'auth/too-many-requests':
        throw new Error('Za dużo prób logowania. Spróbuj później');
      case 'auth/user-disabled':
        throw new Error('Konto zostało wyłączone');
      case 'auth/operation-not-allowed':
        throw new Error('Logowanie email/hasło nie jest włączone w Firebase Console');
      case 'auth/network-request-failed':
        throw new Error('Problem z połączeniem internetowym');
      default:
        throw new Error('Błąd podczas logowania: ' + (error.message || 'Nieznany błąd'));
    }
  }
};

// Email/Password Sign Up
export const signUpWithEmail = async ({ email, password, name }: SignupCredentials) => {
  try {
    // Test Firebase connection first
    const connectionTest = await testFirebaseConnection();
    if (!connectionTest.success) {
      throw new Error(`Firebase connection failed: ${connectionTest.error}`);
    }
    
    // Validate inputs
    if (!email || !password || !name) {
      throw new Error('Wszystkie pola są wymagane');
    }

    if (password.length < 6) {
      throw new Error('Hasło musi mieć co najmniej 6 znaków');
    }

    if (name.trim().length < 2) {
      throw new Error('Imię musi mieć co najmniej 2 znaki');
    }

    // Validate email format
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(email)) {
      throw new Error('Nieprawidłowy format email');
    }

    // Create user account
    const result = await createUserWithEmailAndPassword(auth, email, password);
    
    // Update profile with display name
    await updateProfile(result.user, { displayName: name });
    
    // Send email verification
    await sendEmailVerification(result.user);
    
    // Create user document
    await createUserDocument(result.user, { name });
    
    const userData = await getUserData(result.user.uid);
    return { user: result.user, userData };
  } catch (error: any) {
    console.error('🔥 Registration error details:', {
      code: error.code,
      message: error.message,
      fullError: error
    });
    
    // Handle specific Firebase errors
    switch (error.code) {
      case 'auth/configuration-not-found':
        throw new Error('Problem z konfiguracją Firebase. Sprawdź ustawienia projektu w Firebase Console. Upewnij się, że Email/Password jest włączone w Authentication → Sign-in method.');
      case 'auth/email-already-in-use':
        throw new Error('Ten email jest już zarejestrowany. Spróbuj się zalogować.');
      case 'auth/invalid-email':
        throw new Error('Nieprawidłowy format adresu email.');
      case 'auth/operation-not-allowed':
        throw new Error('Rejestracja email/hasło nie jest włączona w Firebase Console. Włącz metodę Email/Password w Authentication → Sign-in method');
      case 'auth/weak-password':
        throw new Error('Hasło jest za słabe. Użyj minimum 6 znaków.');
      case 'auth/network-request-failed':
        throw new Error('Problem z połączeniem internetowym. Spróbuj ponownie.');
      case 'auth/too-many-requests':
        throw new Error('Za dużo prób rejestracji. Poczekaj chwilę i spróbuj ponownie.');
      case 'auth/unauthorized-domain':
        throw new Error('Domena nie jest autoryzowana. Dodaj localhost do autoryzowanych domen w Firebase Console → Authentication → Settings → Authorized domains');
      default:
        throw new Error(`Błąd podczas rejestracji: ${error.message}`);
    }
  }
};

// Google Sign In
export const signInWithGoogle = async () => {
  try {
    const provider = new GoogleAuthProvider();
    const result = await signInWithPopup(auth, provider);
    
    // Create user document if it doesn't exist
    await createUserDocument(result.user);
    
    const userData = await getUserData(result.user.uid);
    return { user: result.user, userData };
  } catch (error: any) {
    console.error('Google sign-in error:', error);
    
    switch (error.code) {
      case 'auth/configuration-not-found':
        throw new Error('Problem z konfiguracją Firebase. Sprawdź ustawienia projektu.');
      case 'auth/popup-closed-by-user':
        throw new Error('Okno logowania zostało zamknięte');
      case 'auth/popup-blocked':
        throw new Error('Okno logowania zostało zablokowane. Sprawdź ustawienia przeglądarki');
      case 'auth/cancelled-popup-request':
        throw new Error('Logowanie zostało anulowane');
      case 'auth/operation-not-allowed':
        throw new Error('Logowanie przez Google nie jest włączone w Firebase Console');
      default:
        throw new Error('Błąd podczas logowania przez Google: ' + (error.message || 'Nieznany błąd'));
    }
  }
};

// Sign Out
export const signOutUser = async () => {
  try {
    await signOut(auth);
  } catch (error: any) {
    console.error('Sign out error:', error);
    throw new Error('Błąd podczas wylogowania: ' + (error.message || 'Nieznany błąd'));
  }
};

// Update user profile
export const updateUserProfile = async (userId: string, updates: Partial<User>) => {
  try {
    const userRef = doc(db, 'users', userId);
    await updateDoc(userRef, {
      ...updates,
      updatedAt: serverTimestamp(),
    });
    
    return await getUserData(userId);
  } catch (error: any) {
    throw new Error(error.message);
  }
};

// Update membership tier
export const updateMembershipTier = async (userId: string, tier: MembershipTier) => {
  try {
    const userRef = doc(db, 'users', userId);
    await updateDoc(userRef, {
      membershipTier: tier,
      updatedAt: serverTimestamp(),
    });
    
    return await getUserData(userId);
  } catch (error: any) {
    throw new Error(error.message);
  }
};

// Check if user has access to premium content
export const hasPremiumAccess = (user: User | null): boolean => {
  if (!user) return false;
  return user.membershipTier === MembershipTier.CZUŁOŚĆ || user.membershipTier === MembershipTier.WOLNOŚĆ;
};

// Check if user has VIP access
export const hasVipAccess = (user: User | null): boolean => {
  if (!user) return false;
  return user.membershipTier === MembershipTier.WOLNOŚĆ;
}; 