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

export interface MoneyRequest {
  id?: string;
  requestorName: string;
  requesteeName: string;
  requestorPhoneNumber: string;
  requesteePhoneNumber: string;
  requestorType: 'saved' | 'contact';
  amount: number;
  note?: string;
  notificationMethod: 'SMS' | 'WhatsApp';
  status: 'pending' | 'accepted' | 'declined' | 'expired';
  createdAt: Date;
  updatedAt: Date;
}

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

  /**
   * Find user UID by phone number
   */
  static async findUserByPhoneNumber(phoneNumber: string): Promise<string | null> {
    try {
      const usersCollection = collection('users');
      const querySnapshot = await usersCollection
        .where('phoneNumber', '==', phoneNumber)
        .get();

      if (querySnapshot.empty) {
        return null;
      }

      return querySnapshot.docs[0].id;
    } catch (error) {
      console.error('Error finding user by phone number:', error);
      return null;
    }
  }

  /**
   * Get user details by phone number
   */
  static async getUserByPhoneNumber(phoneNumber: string): Promise<{ success: boolean; user?: { uid: string; displayName: string; phoneNumber: string }; error?: string }> {
    try {
      const usersCollection = collection('users');
      const querySnapshot = await usersCollection
        .where('phoneNumber', '==', phoneNumber)
        .get();

      if (querySnapshot.empty) {
        return { success: false, error: 'User not found' };
      }

      const userDoc = querySnapshot.docs[0];
      const userData = userDoc.data();

      return {
        success: true,
        user: {
          uid: userDoc.id,
          displayName: userData.displayName || userData.name || 'Unknown',
          phoneNumber: userData.phoneNumber
        }
      };
    } catch (error) {
      console.error('Error getting user by phone number:', error);
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Failed to get user'
      };
    }
  }

  /**
   * Get request by ID
   */
  static async getRequestById(requestId: string): Promise<{ success: boolean; request?: MoneyRequest; error?: string }> {
    try {
      const requestRef = doc('requests', requestId);
      const requestSnapshot = await requestRef.get();

      if (!RequestService.snapshotExists(requestSnapshot)) {
        return { success: false, error: 'Request not found' };
      }

      const requestData = requestSnapshot.data() as any;
      const request: MoneyRequest = {
        id: requestSnapshot.id,
        requestorName: requestData.requestorName,
        requesteeName: requestData.requesteeName,
        requestorPhoneNumber: requestData.requestorPhoneNumber,
        requesteePhoneNumber: requestData.requesteePhoneNumber,
        requestorType: requestData.requestorType,
        amount: requestData.amount,
        note: requestData.note,
        notificationMethod: requestData.notificationMethod || 'SMS',
        status: requestData.status,
        createdAt: requestData.createdAt?.toDate?.() || new Date(),
        updatedAt: requestData.updatedAt?.toDate?.() || new Date(),
      };

      return {
        success: true,
        request
      };
    } catch (error) {
      console.error('Error getting request by ID:', error);
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Failed to get request'
      };
    }
  }

  /**
   * Update request status
   */
  static async updateRequestStatus(
    requestId: string,
    status: 'pending' | 'accepted' | 'declined' | 'expired'
  ): Promise<{ success: boolean; error?: string }> {
    return withGlobalLoading(async () => {
      try {
        const requestRef = doc('requests', requestId);
        await requestRef.update({
          status,
          updatedAt: FieldValue.serverTimestamp(),
        });

        return {
          success: true,
        };
      } catch (error) {
        console.error('Error updating request status:', error);
        return {
          success: false,
          error: error instanceof Error ? error.message : 'Failed to update request status',
        };
      }
    });
  }

  /**
   * Create a new money request
   */
  static async createRequest(
    uid: string,
    requestData: Omit<MoneyRequest, 'id' | 'createdAt' | 'updatedAt'>
  ): Promise<{ success: boolean; requestId?: string; error?: string }> {
    return withGlobalLoading(async () => {
      try {
        // Generate a unique request ID
        const requestId = `request_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;

        const request = {
          ...requestData,
          uid,
          createdAt: FieldValue.serverTimestamp(),
          updatedAt: FieldValue.serverTimestamp(),
        };

        const requestRef = doc('requests', requestId);
        await requestRef.set(request);

        return {
          success: true,
          requestId,
        };
      } catch (error) {
        console.error('Error creating money request:', error);
        return {
          success: false,
          error: error instanceof Error ? error.message : 'Failed to create request',
        };
      }
    });
  }
}
