/**
 * Recipient Service - Platform-aware recipient management
 * Uses Firebase abstraction layer for cross-platform support
 */
import { doc, collection } from '../firebase';

export interface Recipient {
  id: string;
  uid: string;
  fullName: string;
  phoneNumber: string;
  createdAt: Date;
  updatedAt: Date;
  isActive: boolean;
}

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

  // Add a new recipient
  static async addRecipient(
    uid: string,
    recipientData: {
      fullName: string;
      phoneNumber: string;
    }
  ): Promise<{ success: boolean; error?: string; recipientId?: string }> {
    try {
      // Validate input
      if (!recipientData.fullName.trim()) {
        return { success: false, error: 'Full name is required' };
      }

      if (!recipientData.phoneNumber.trim()) {
        return { success: false, error: 'Phone number is required' };
      }

      // Basic phone number validation
      const cleanPhone = recipientData.phoneNumber.replace(/[^+\d]/g, '');
      if (cleanPhone.length < 7) {
        return { success: false, error: 'Please enter a valid phone number' };
      }

      // Check if recipient already exists
      const existingRecipient = await RecipientService.getRecipientByPhone(uid, cleanPhone);
      if (existingRecipient) {
        return { success: false, error: 'This recipient already exists' };
      }

      // Generate recipient ID
      const recipientId = `recipient_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;

      const newRecipient: Recipient = {
        id: recipientId,
        uid,
        fullName: recipientData.fullName.trim(),
        phoneNumber: cleanPhone,
        createdAt: new Date(),
        updatedAt: new Date(),
        isActive: true,
      };

      // Save to Firestore
      const recipientRef = doc('recipients', recipientId);
      await recipientRef.set(newRecipient);

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

  // Get all recipients for a user
  static async getUserRecipients(uid: string): Promise<Recipient[]> {
    try {
      const recipientsCollection = collection('recipients');
      const querySnapshot = await recipientsCollection
        .where('uid', '==', uid)
        .where('isActive', '==', true)
        .get();

      const recipients: Recipient[] = [];

      querySnapshot.forEach((docData: any) => {
        recipients.push(docData.data() as Recipient);
      });

      // Sort by creation date (newest first)
      recipients.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());

      return recipients;
    } catch (error) {
      console.error('Error fetching user recipients:', error);
      throw error;
    }
  }

  // Get recipient by phone number for a specific user
  static async getRecipientByPhone(uid: string, phoneNumber: string): Promise<Recipient | null> {
    try {
      const recipientsCollection = collection('recipients');
      const querySnapshot = await recipientsCollection
        .where('uid', '==', uid)
        .where('phoneNumber', '==', phoneNumber)
        .where('isActive', '==', true)
        .get();

      if (querySnapshot.empty) {
        return null;
      }

      return querySnapshot.docs[0].data() as Recipient;
    } catch (error) {
      console.error('Error fetching recipient by phone:', error);
      throw error;
    }
  }

  // Update recipient
  static async updateRecipient(
    recipientId: string,
    updates: {
      fullName?: string;
      phoneNumber?: string;
    }
  ): Promise<{ success: boolean; error?: string }> {
    try {
      const recipientRef = doc('recipients', recipientId);
      const recipientDoc = await recipientRef.get();

      if (!RecipientService.snapshotExists(recipientDoc)) {
        return { success: false, error: 'Recipient not found' };
      }

      const updateData: any = {
        updatedAt: new Date(),
      };

      if (updates.fullName) {
        updateData.fullName = updates.fullName.trim();
      }

      if (updates.phoneNumber) {
        const cleanPhone = updates.phoneNumber.replace(/[^+\d]/g, '');
        if (cleanPhone.length < 7) {
          return { success: false, error: 'Please enter a valid phone number' };
        }
        updateData.phoneNumber = cleanPhone;
      }

      await recipientRef.update(updateData);

      console.log('Recipient updated successfully');
      return { success: true };
    } catch (error) {
      console.error('Update recipient error:', error);
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Failed to update recipient'
      };
    }
  }

  // Delete recipient (soft delete)
  static async deleteRecipient(recipientId: string): Promise<{ success: boolean; error?: string }> {
    try {
      const recipientRef = doc('recipients', recipientId);

      await recipientRef.update({
        isActive: false,
        updatedAt: new Date(),
      });

      console.log('Recipient deleted successfully');
      return { success: true };
    } catch (error) {
      console.error('Delete recipient error:', error);
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Failed to delete recipient'
      };
    }
  }

  // Hard delete recipient (permanent)
  static async permanentDeleteRecipient(recipientId: string): Promise<{ success: boolean; error?: string }> {
    try {
      const recipientRef = doc('recipients', recipientId);
      await recipientRef.delete();

      console.log('Recipient permanently deleted');
      return { success: true };
    } catch (error) {
      console.error('Permanent delete recipient error:', error);
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Failed to permanently delete recipient'
      };
    }
  }

  static async getRecipientById(recipientId: string): Promise<{ success: boolean; recipient?: Recipient; error?: string }> {
    try {
      const recipientRef = doc('recipients', recipientId);
      const docSnap = await recipientRef.get();

      if (!RecipientService.snapshotExists(docSnap)) {
        return { success: false, error: 'Recipient not found' };
      }

      const data = docSnap.data() as Recipient | undefined;
      if (!data) {
        return { success: false, error: 'Recipient data unavailable' };
      }

      const recipient: Recipient = {
        ...data,
        id: data.id ?? recipientId,
        createdAt: (data.createdAt as any)?.toDate?.() ?? data.createdAt ?? new Date(),
        updatedAt: (data.updatedAt as any)?.toDate?.() ?? data.updatedAt ?? new Date(),
      };

      return { success: true, recipient };
    } catch (error) {
      console.error('Error fetching recipient by id:', error);
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Failed to fetch recipient',
      };
    }
  }
}

export default RecipientService;
