/**
 * Wallet Service - Platform-aware wallet management
 * Uses Firebase abstraction layer for cross-platform support
 */
import { doc, collection, FieldValue } from '../firebase';
import { useUserWalletStore } from '../stores/userWalletStore';
import { withGlobalLoading } from '../stores/uiStore';

export interface CreditCard {
  id: string;
  cardNumber: string;
  expiryDate: string;
  cardType?: string;
  lastFourDigits: string;
  createdAt: Date;
  isActive: boolean;
}

export interface UserWallet {
  uid: string;
  balance: number;
  currency: string;
  isActive: boolean;
  cards: CreditCard[];
  createdAt: Date;
  updatedAt: Date;
}

export class WalletService {
  private static snapshotExists(docSnap: any): boolean {
    const existsValue = docSnap?.exists;
    if (typeof existsValue === 'function') {
      try {
        return !!existsValue.call(docSnap);
      } catch {
        return false;
      }
    }
    return !!existsValue;
  }

  // Create User Wallet
  static async createUserWallet(uid: string): Promise<{ success: boolean; error?: string }> {
    return withGlobalLoading(async () => {
      try {
        const walletData: UserWallet = {
          uid,
          balance: 0,
          currency: 'USD',
          isActive: true,
          cards: [],
          createdAt: new Date(),
          updatedAt: new Date(),
        };

        const walletRef = doc('wallets', uid);
        await walletRef.set(walletData);
        console.log('Wallet created successfully for user:', uid);

        try {
          await useUserWalletStore.getState().invalidateWallet(uid);
        } catch (cacheError) {
          console.warn('Failed to refresh wallet cache after creation', cacheError);
        }

        return { success: true };
      } catch (error) {
        console.error('Wallet creation error:', error);
        return {
          success: false,
          error: error instanceof Error ? error.message : 'Failed to create wallet'
        };
      }
    });
  }

  // Update Wallet Balance
  static async updateWalletBalance(
    uid: string,
    newBalanceInCents: number
  ): Promise<{ success: boolean; error?: string }> {
    return withGlobalLoading(async () => {
      try {
        const walletDocRef = doc('wallets', uid);
        await walletDocRef.update({
          balance: newBalanceInCents,
          updatedAt: new Date(),
        });

        console.log('Wallet balance updated successfully');

        try {
          await useUserWalletStore.getState().invalidateWallet(uid);
        } catch (cacheError) {
          console.warn('Failed to refresh wallet cache after balance update', cacheError);
        }

        return { success: true };
      } catch (error) {
        console.error('Wallet balance update error:', error);
        return {
          success: false,
          error: error instanceof Error ? error.message : 'Failed to update wallet balance'
        };
      }
    });
  }

  // Add Credit Card to Wallet
  static async addCreditCard(
    uid: string,
    cardData: {
      cardNumber: string;
      expiryDate: string;
      cvv: string;
    }
  ): Promise<{ success: boolean; error?: string }> {
    return withGlobalLoading(async () => {
      try {
        // Basic validation
        if (!cardData.cardNumber || !cardData.expiryDate || !cardData.cvv) {
          return { success: false, error: 'All card fields are required' };
        }

        // Validate card number
        const cleanCardNumber = cardData.cardNumber.replace(/\s|-/g, '');
        if (!/^\d{16}$/.test(cleanCardNumber)) {
          return { success: false, error: 'Card number must be 16 digits' };
        }

        // Validate expiry date
        if (!/^(0[1-9]|1[0-2])\/\d{2}$/.test(cardData.expiryDate)) {
          return { success: false, error: 'Expiry date must be in MM/YY format' };
        }

        // Validate CVV
        if (!/^\d{3,4}$/.test(cardData.cvv)) {
          return { success: false, error: 'CVV must be 3 or 4 digits' };
        }

        // Detect card type
        const cardType = WalletService.detectCardType(cleanCardNumber);

        // Create card object
        const newCard: CreditCard = {
          id: `card_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
          cardNumber: WalletService.maskCardNumber(cleanCardNumber),
          expiryDate: cardData.expiryDate,
          cardType,
          lastFourDigits: cleanCardNumber.slice(-4),
          createdAt: new Date(),
          isActive: true,
        };

        // Get current wallet
        const walletDocRef = doc('wallets', uid);
        const walletDoc = await walletDocRef.get();

        if (!WalletService.snapshotExists(walletDoc)) {
          return { success: false, error: 'Wallet not found' };
        }

        const currentWallet = walletDoc.data() as UserWallet;
        const updatedCards = [...(currentWallet.cards || []), newCard];

        // Update wallet with new card
        await walletDocRef.update({
          cards: updatedCards,
          updatedAt: new Date(),
        });

        console.log('Credit card added successfully');

        try {
          await useUserWalletStore.getState().invalidateWallet(uid);
        } catch (cacheError) {
          console.warn('Failed to refresh wallet cache after adding card', cacheError);
        }

        return { success: true };
      } catch (error) {
        console.error('Add credit card error:', error);
        return {
          success: false,
          error: error instanceof Error ? error.message : 'Failed to add credit card'
        };
      }
    });
  }

  // Remove Credit Card from Wallet
  static async removeCreditCard(
    uid: string,
    cardId: string
  ): Promise<{ success: boolean; error?: string }> {
    return withGlobalLoading(async () => {
      try {
        const walletDocRef = doc('wallets', uid);
        const walletDoc = await walletDocRef.get();

        if (!WalletService.snapshotExists(walletDoc)) {
          return { success: false, error: 'Wallet not found' };
        }

        const currentWallet = walletDoc.data() as UserWallet;
        const updatedCards = (currentWallet.cards || []).filter(card => card.id !== cardId);

        await walletDocRef.update({
          cards: updatedCards,
          updatedAt: new Date(),
        });

        console.log('Credit card removed successfully');

        try {
          await useUserWalletStore.getState().invalidateWallet(uid);
        } catch (cacheError) {
          console.warn('Failed to refresh wallet cache after removing card', cacheError);
        }

        return { success: true };
      } catch (error) {
        console.error('Remove credit card error:', error);
        return {
          success: false,
          error: error instanceof Error ? error.message : 'Failed to remove credit card'
        };
      }
    });
  }

  // Helper: Detect card type
  private static detectCardType(cardNumber: string): string {
    if (cardNumber.startsWith('4')) {
      return 'Visa';
    } else if (cardNumber.startsWith('5') || cardNumber.startsWith('2')) {
      return 'MasterCard';
    } else if (cardNumber.startsWith('3')) {
      return 'American Express';
    } else if (cardNumber.startsWith('6')) {
      return 'Discover';
    }
    return 'Unknown';
  }

  // Helper: Mask card number
  private static maskCardNumber(cardNumber: string): string {
    return '**** **** **** ' + cardNumber.slice(-4);
  }

  // Get User Wallet
  static async getUserWallet(uid: string): Promise<{ success: boolean; wallet?: UserWallet; error?: string }> {
    try {
      const walletDocRef = doc('wallets', uid);
      const walletDoc = await walletDocRef.get();

      if (WalletService.snapshotExists(walletDoc)) {
        const wallet = walletDoc.data() as UserWallet;
        return { success: true, wallet };
      }
      return { success: false, error: 'Wallet not found' };
    } catch (error) {
      console.error('Error fetching user wallet:', error);
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Failed to fetch wallet'
      };
    }
  }
}

export default WalletService;
