/**
 * Firebase Web Implementation
 * Uses Firebase JS SDK for web platform
 */
import { initializeApp, getApps, getApp } from 'firebase/app';
import {
    getAuth,
    onAuthStateChanged as webOnAuthStateChanged,
    GoogleAuthProvider,
    signOut as webSignOut,
} from 'firebase/auth';
import type { User, ConfirmationResult } from 'firebase/auth';
import {
    getFirestore,
    collection as webCollection,
    doc as webDoc,
    getDoc,
    setDoc,
    updateDoc,
    deleteDoc,
    query,
    where,
    orderBy,
    limit,
    getDocs,
    onSnapshot,
    serverTimestamp,
    Timestamp as WebTimestamp,
    deleteField
} from 'firebase/firestore';
import { getMessaging, getToken, onMessage } from 'firebase/messaging';
import { getFunctions, httpsCallable as webHttpsCallable } from 'firebase/functions';

// Firebase configuration for web
const firebaseConfig = {
    apiKey: "AIzaSyCVprX0NvjjemRKRpG1ZJHyMwKsJmBuXHc",
    authDomain: "ambapaydemo.firebaseapp.com",
    databaseURL: "https://ambapaydemo-default-rtdb.europe-west1.firebasedatabase.app",
    projectId: "ambapaydemo",
    storageBucket: "ambapaydemo.firebasestorage.app",
    messagingSenderId: "613864011564",
    appId: "1:613864011564:web:e078c5990d3b2bff249e89",
    measurementId: "G-F8RVT1BHHC"
};

// Initialize Firebase (only once)
const app = getApps().length === 0 ? initializeApp(firebaseConfig) : getApp();
const authInstance = getAuth(app);
const firestoreInstance = getFirestore(app);

// Lazy initialization for messaging (requires browser support)
let messagingInstance: ReturnType<typeof getMessaging> | null = null;
const getMessagingInstanceInternal = () => {
    if (typeof window !== 'undefined' && 'Notification' in window) {
        if (!messagingInstance) {
            try {
                messagingInstance = getMessaging(app);
            } catch (e) {
                console.warn('Firebase Messaging not available:', e);
            }
        }
        return messagingInstance;
    }
    return null;
};

const functionsInstance = getFunctions(app);

// Type compatibility layer
export interface FirebaseAuthTypes {
    User: User;
    ConfirmationResult: ConfirmationResult;
}

// Status codes compatibility (for Google Sign-In error handling)
export const statusCodes = {
    SIGN_IN_CANCELLED: 'SIGN_IN_CANCELLED',
    IN_PROGRESS: 'IN_PROGRESS',
    PLAY_SERVICES_NOT_AVAILABLE: 'PLAY_SERVICES_NOT_AVAILABLE',
};

// Auth exports
export const firebaseAuth = { GoogleAuthProvider };
export const getAuthInstance = () => authInstance;
export const onAuthStateChanged = (callback: (user: User | null) => void) => {
    return webOnAuthStateChanged(authInstance, callback);
};

// Firestore exports
export const firebaseFirestore = {
    FieldValue: {
        serverTimestamp: () => serverTimestamp(),
        delete: () => deleteField(),
    }
};
export const getFirestoreInstance = () => firestoreInstance;
export const FieldValue = {
    serverTimestamp: () => serverTimestamp(),
    delete: () => deleteField(),
};
export const Timestamp = WebTimestamp;

// Collection helpers that return a Firestore-like interface
export const collection = (path: string) => {
    const collectionRef = webCollection(firestoreInstance, path);

    return {
        doc: (docId: string) => createDocRef(path, docId),
        where: (field: string, op: any, value: any) => {
            return createQueryBuilder(collectionRef, [where(field, op, value)]);
        },
        orderBy: (field: string, direction?: 'asc' | 'desc') => {
            return createQueryBuilder(collectionRef, [orderBy(field, direction)]);
        },
        get: async () => {
            const snapshot = await getDocs(collectionRef);
            return {
                docs: snapshot.docs.map(docItem => ({
                    id: docItem.id,
                    data: () => docItem.data(),
                    exists: docItem.exists(),
                })),
                empty: snapshot.empty,
                forEach: (callback: (docItem: any) => void) => {
                    snapshot.forEach(docItem => callback({
                        id: docItem.id,
                        data: () => docItem.data(),
                        exists: docItem.exists(),
                    }));
                },
            };
        },
    };
};

// Query builder for chaining
const createQueryBuilder = (collectionRef: any, constraints: any[] = []) => {
    return {
        where: (field: string, op: any, value: any) => {
            return createQueryBuilder(collectionRef, [...constraints, where(field, op, value)]);
        },
        orderBy: (field: string, direction?: 'asc' | 'desc') => {
            return createQueryBuilder(collectionRef, [...constraints, orderBy(field, direction)]);
        },
        limit: (n: number) => {
            return createQueryBuilder(collectionRef, [...constraints, limit(n)]);
        },
        get: async () => {
            const q = query(collectionRef, ...constraints);
            const snapshot = await getDocs(q);
            return {
                docs: snapshot.docs.map(docItem => ({
                    id: docItem.id,
                    data: () => docItem.data(),
                    exists: docItem.exists(),
                })),
                empty: snapshot.empty,
                forEach: (callback: (docItem: any) => void) => {
                    snapshot.forEach(docItem => callback({
                        id: docItem.id,
                        data: () => docItem.data(),
                        exists: docItem.exists(),
                    }));
                },
            };
        },
        onSnapshot: (callback: (snapshot: any) => void, errorCallback?: (error: any) => void) => {
            const q = query(collectionRef, ...constraints);
            return onSnapshot(q, (snapshot) => {
                callback({
                    docs: snapshot.docs.map(docItem => ({
                        id: docItem.id,
                        data: () => docItem.data(),
                        exists: docItem.exists(),
                    })),
                    empty: snapshot.empty,
                    forEach: (cb: (docItem: any) => void) => {
                        snapshot.forEach(docItem => cb({
                            id: docItem.id,
                            data: () => docItem.data(),
                            exists: docItem.exists(),
                        }));
                    },
                });
            }, errorCallback);
        },
    };
};

// Document reference helper
const createDocRef = (collectionPath: string, docId: string) => {
    const docRef = webDoc(firestoreInstance, collectionPath, docId);

    return {
        get: async () => {
            const snapshot = await getDoc(docRef);
            return {
                exists: snapshot.exists(),
                data: () => snapshot.data(),
                id: snapshot.id,
            };
        },
        set: async (data: any, options?: { merge?: boolean }) => {
            await setDoc(docRef, data, options || {});
        },
        update: async (data: any) => {
            await updateDoc(docRef, data);
        },
        delete: async () => {
            await deleteDoc(docRef);
        },
        onSnapshot: (callback: (snapshot: any) => void, errorCallback?: (error: any) => void) => {
            return onSnapshot(docRef, (snapshot) => {
                callback({
                    exists: snapshot.exists(),
                    data: () => snapshot.data(),
                    id: snapshot.id,
                });
            }, errorCallback);
        },
    };
};

export const doc = (collectionPath: string, docId: string) => createDocRef(collectionPath, docId);

// Messaging exports (web-specific)
export const firebaseMessaging = {
    AuthorizationStatus: {
        AUTHORIZED: 1,
        PROVISIONAL: 2,
        DENIED: 0,
        NOT_DETERMINED: -1,
    },
};
export const getMessagingInstance = getMessagingInstanceInternal;
export const AuthorizationStatus = firebaseMessaging.AuthorizationStatus;

// Functions exports
export const firebaseFunctions = {};
export const getFunctionsInstance = () => functionsInstance;
export const httpsCallable = (name: string) => {
    const callable = webHttpsCallable(functionsInstance, name);
    return async (data: any) => {
        const result = await callable(data);
        return result;
    };
};

// Google Sign-In (Web)
export const signInWithGoogle = async (): Promise<{
    user: User | null;
    isNewUser: boolean;
    error?: string;
}> => {
    try {
        // Dynamic import for signInWithPopup (tree-shaking friendly)
        const authModule = await import('firebase/auth');
        const signInWithPopup = (authModule as any).signInWithPopup;

        if (!signInWithPopup) {
            return { user: null, isNewUser: false, error: 'signInWithPopup not available' };
        }

        const provider = new GoogleAuthProvider();
        provider.setCustomParameters({
            prompt: 'select_account'
        });

        const result = await signInWithPopup(authInstance, provider);
        // Check if new user - web SDK doesn't directly expose this, check metadata
        const isNewUser = result.user.metadata.creationTime === result.user.metadata.lastSignInTime;

        return { user: result.user, isNewUser };
    } catch (error: any) {
        console.error('Google Sign-In error:', error);

        if (error.code === 'auth/popup-closed-by-user') {
            return { user: null, isNewUser: false, error: 'Sign in was cancelled' };
        }
        if (error.code === 'auth/popup-blocked') {
            return { user: null, isNewUser: false, error: 'Popup was blocked. Please allow popups for this site.' };
        }

        return { user: null, isNewUser: false, error: error.message || 'Google Sign-In failed' };
    }
};

export const signOutFromGoogle = async (): Promise<void> => {
    // No separate Google sign out needed on web
};

// Phone Auth (Web) - requires reCAPTCHA
let recaptchaVerifier: any = null;

export const initRecaptcha = async (containerId: string): Promise<any> => {
    if (typeof window !== 'undefined' && !recaptchaVerifier) {
        // Dynamic import for RecaptchaVerifier
        const authModule = await import('firebase/auth');
        const RecaptchaVerifier = (authModule as any).RecaptchaVerifier;

        if (RecaptchaVerifier) {
            recaptchaVerifier = new RecaptchaVerifier(authInstance, containerId, {
                size: 'invisible',
                callback: () => {
                    console.log('reCAPTCHA verified');
                },
            });
        }
    }
    return recaptchaVerifier;
};

export const signInWithPhoneNumber = async (phoneNumber: string): Promise<ConfirmationResult> => {
    if (!recaptchaVerifier) {
        throw new Error('reCAPTCHA not initialized. Call initRecaptcha first.');
    }
    // Dynamic import for signInWithPhoneNumber
    const authModule = await import('firebase/auth');
    const webSignInWithPhoneNumber = (authModule as any).signInWithPhoneNumber;

    if (!webSignInWithPhoneNumber) {
        throw new Error('signInWithPhoneNumber not available');
    }

    return webSignInWithPhoneNumber(authInstance, phoneNumber, recaptchaVerifier);
};

// Email/Password Authentication (Web)
export const createUserWithEmailAndPassword = async (
  email: string,
  password: string
): Promise<{ user: User | null; error?: string }> => {
  try {
    const authModule = await import('firebase/auth');
    const createUser = (authModule as any).createUserWithEmailAndPassword;

    if (!createUser) {
      return { user: null, error: 'createUserWithEmailAndPassword not available' };
    }

    const userCredential = await createUser(authInstance, email, password);
    return { user: userCredential.user };
  } catch (error: any) {
    console.error('Email/Password signup error:', error);
    return {
      user: null,
      error: error.message || 'Failed to create account',
    };
  }
};

export const signInWithEmailAndPassword = async (
  email: string,
  password: string
): Promise<{ user: User | null; error?: string }> => {
  try {
    const authModule = await import('firebase/auth');
    const signIn = (authModule as any).signInWithEmailAndPassword;

    if (!signIn) {
      return { user: null, error: 'signInWithEmailAndPassword not available' };
    }

    const userCredential = await signIn(authInstance, email, password);
    return { user: userCredential.user };
  } catch (error: any) {
    console.error('Email/Password signin error:', error);
    return {
      user: null,
      error: error.message || 'Failed to sign in',
    };
  }
};

// Firebase Auth sign out
export const signOut = async (): Promise<void> => {
  await webSignOut(authInstance);
};

// Web FCM helpers
export const requestNotificationPermission = async (): Promise<boolean> => {
    if (typeof window === 'undefined' || !('Notification' in window)) {
        return false;
    }

    try {
        const permission = await Notification.requestPermission();
        return permission === 'granted';
    } catch (error) {
        console.error('Error requesting notification permission:', error);
        return false;
    }
};

export const getWebFCMToken = async (): Promise<string | null> => {
    const messaging = getMessagingInstanceInternal();
    if (!messaging) return null;

    try {
        // You'll need to add your VAPID key here for web push
        const token = await getToken(messaging, {
            vapidKey: 'YOUR_VAPID_KEY_HERE' // TODO: Add your VAPID key
        });
        return token;
    } catch (error) {
        console.error('Error getting FCM token:', error);
        return null;
    }
};

export const onWebMessage = (callback: (payload: any) => void) => {
    const messaging = getMessagingInstanceInternal();
    if (!messaging) return () => { };

    return onMessage(messaging, callback);
};

// Platform identifier
export const isNative = false;
export const isWeb = true;
