import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:in_app_purchase/in_app_purchase.dart';
import 'package:in_app_purchase_android/in_app_purchase_android.dart';
 

import '../config/api_config.dart';
import '../models/subscription_model.dart';

/// 인앱 결제 서비스
class InAppPurchaseService extends ChangeNotifier {
  final InAppPurchase _inAppPurchase = InAppPurchase.instance;
  StreamSubscription<List<PurchaseDetails>>? _subscription;
  
  List<ProductDetails> _products = [];
  List<PurchaseDetails> _purchases = [];
  bool _isAvailable = false;
  bool _isLoading = false;
  String? _error;
  
  // 구매 검증 관련 변수
  bool _purchaseVerified = false;
  
  // 구독 상품 ID (스토어에 등록된 ID와 일치해야 함)
  final Map<SubscriptionPlanType, String> _subscriptionIds = {
    SubscriptionPlanType.basic: Platform.isAndroid 
        ? 'com.bowlingmanager.subscription.basic' 
        : 'com.bowlingmanager.subscription.basic',
    SubscriptionPlanType.premium: Platform.isAndroid 
        ? 'com.bowlingmanager.subscription.premium' 
        : 'com.bowlingmanager.subscription.premium',
    SubscriptionPlanType.enterprise: Platform.isAndroid 
        ? 'com.bowlingmanager.subscription.enterprise' 
        : 'com.bowlingmanager.subscription.enterprise',
  };
  
  // 게터
  List<ProductDetails> get products => _products;
  List<PurchaseDetails> get purchases => _purchases;
  bool get isAvailable => _isAvailable;
  bool get isLoading => _isLoading;
  String? get error => _error;
  
  // 구매 검증 관련 게터/세터
  bool get isPurchaseVerified => _purchaseVerified;
  set isPurchaseVerified(bool value) => _purchaseVerified = value;
  PurchaseDetails? get lastVerifiedPurchase => _purchases.isNotEmpty ? _purchases.last : null;
  set lastVerifiedPurchase(PurchaseDetails? value) {
    if (value != null && !_purchases.contains(value)) {
      _purchases.add(value);
    }
  }
  
  InAppPurchaseService() {
    _initialize();
  }
  
  /// 초기화 및 결제 상태 리스너 설정
  Future<void> _initialize() async {
    _isLoading = true;
    notifyListeners();
    
    // 인앱 결제 가능 여부 확인
    _isAvailable = await _inAppPurchase.isAvailable();
    
    if (!_isAvailable) {
      _error = '인앱 결제를 사용할 수 없습니다.';
      _isLoading = false;
      notifyListeners();
      return;
    }
    
    // 결제 상태 변경 리스너 설정
    final purchaseUpdated = _inAppPurchase.purchaseStream;
    _subscription = purchaseUpdated.listen(
      _onPurchaseUpdate,
      onDone: _updateStreamOnDone,
      onError: _updateStreamOnError,
    );
    
    // 상품 정보 로드
    await _loadProducts();
    
    _isLoading = false;
    notifyListeners();
  }
  
  /// 상품 정보 로드
  Future<void> _loadProducts() async {
    try {
      final Set<String> ids = _subscriptionIds.values.toSet();
      final ProductDetailsResponse response = 
          await _inAppPurchase.queryProductDetails(ids);
      
      if (response.notFoundIDs.isNotEmpty) {
        _error = '일부 상품을 찾을 수 없습니다: ${response.notFoundIDs.join(", ")}';
      }
      
      _products = response.productDetails;
      notifyListeners();
    } catch (e) {
      _error = '상품 정보를 불러오는데 실패했습니다: $e';
    }
  }
  
  /// 구독 플랜 타입에 해당하는 상품 정보 가져오기
  ProductDetails? getProductByPlanType(SubscriptionPlanType planType) {
    final String? id = _subscriptionIds[planType];
    if (id == null) return null;
    
    try {
      return _products.firstWhere((product) => product.id == id);
    } catch (e) {
      return null;
    }
  }
  
  /// 구독 구매 시작
  Future<bool> purchaseSubscription(SubscriptionPlanType planType) async {
    final ProductDetails? product = getProductByPlanType(planType);
    
    if (product == null) {
      _error = '해당 구독 상품을 찾을 수 없습니다.';
      notifyListeners();
      return false;
    }
    
    try {
      // 구매 요청
      final PurchaseParam purchaseParam = PurchaseParam(
        productDetails: product,
        applicationUserName: null,
      );
      
      // 구독 상품 구매 요청
      await _inAppPurchase.buyNonConsumable(purchaseParam: purchaseParam);
      return true;
    } catch (e) {
      _error = '구독 구매 요청 중 오류가 발생했습니다: $e';
      notifyListeners();
      return false;
    }
  }
  
  /// 구매 상태 업데이트 처리
  void _onPurchaseUpdate(List<PurchaseDetails> purchaseDetailsList) async {
    _purchases = purchaseDetailsList;
    
    for (var purchaseDetails in purchaseDetailsList) {
      if (purchaseDetails.status == PurchaseStatus.pending) {
        // 결제 대기 중
        _handlePendingPurchase(purchaseDetails);
      } else if (purchaseDetails.status == PurchaseStatus.purchased || 
                 purchaseDetails.status == PurchaseStatus.restored) {
        // 결제 완료 또는 복원됨
        await _handleSuccessfulPurchase(purchaseDetails);
      } else if (purchaseDetails.status == PurchaseStatus.error) {
        // 결제 오류
        _handleFailedPurchase(purchaseDetails);
      } else if (purchaseDetails.status == PurchaseStatus.canceled) {
        // 결제 취소
        _handleCanceledPurchase(purchaseDetails);
      }
      
      // 구매 완료 처리 (iOS에서는 명시적으로 완료 처리 필요)
      if (purchaseDetails.pendingCompletePurchase) {
        await _inAppPurchase.completePurchase(purchaseDetails);
      }
    }
    
    notifyListeners();
  }
  
  /// 결제 대기 중 처리
  void _handlePendingPurchase(PurchaseDetails purchaseDetails) {
    // 결제 대기 중 UI 업데이트 등 필요한 처리
  }
  
  /// 결제 성공 처리
  Future<void> _handleSuccessfulPurchase(PurchaseDetails purchaseDetails) async {
    // 서버에 구독 정보 업데이트 요청
    await _verifyAndSavePurchase(purchaseDetails);
  }
  
  /// 결제 실패 처리
  void _handleFailedPurchase(PurchaseDetails purchaseDetails) {
    _error = '결제에 실패했습니다: ${purchaseDetails.error?.message ?? "알 수 없는 오류"}';
  }
  
  /// 결제 취소 처리
  void _handleCanceledPurchase(PurchaseDetails purchaseDetails) {
    _error = '결제가 취소되었습니다.';
  }
  
  /// 구매 검증 및 서버 저장
  Future<bool> _verifyAndSavePurchase(PurchaseDetails purchaseDetails) async {
    // 구매 영수증 정보 추출
    String? receiptData;
    String? transactionId = purchaseDetails.purchaseID;
    String? productId = purchaseDetails.productID;
    String platform = Platform.isIOS ? 'ios' : 'android';
    
    if (Platform.isIOS) {
      // iOS의 경우 구매 정보에서 직접 가져오기
      receiptData = purchaseDetails.verificationData.serverVerificationData;
    } else if (Platform.isAndroid) {
      if (purchaseDetails is GooglePlayPurchaseDetails) {
        receiptData = purchaseDetails.billingClientPurchase.originalJson;
      }
    }
    
    if (receiptData == null) {
      _error = '영수증 데이터를 추출할 수 없습니다.';
      notifyListeners();
      return false;
    }
    
    try {
      // API 설정 가져오기
      final String baseUrl = ApiConfig.baseUrl;
      final String verifyEndpoint = ApiConfig.verifyReceipt;
      
      // 서버에 영수증 검증 요청
      final response = await http.post(
        Uri.parse('$baseUrl$verifyEndpoint'),
        headers: {
          'Content-Type': 'application/json',
          // 인증 토큰은 SubscriptionService에서 처리
        },
        body: jsonEncode({
          'receipt': receiptData,
          'transactionId': transactionId,
          'productId': productId,
          'platform': platform,
        }),
      );
      
      if (response.statusCode == 200) {
        // 검증 성공
        jsonDecode(response.body);
        // 성공 이벤트 발생 (SubscriptionService에서 구독 정보 업데이트)
        _purchaseVerified = true;
        notifyListeners();
        return true;
      } else {
        // 검증 실패
        _error = '영수증 검증에 실패했습니다. (${response.statusCode})';
        notifyListeners();
        return false;
      }
    } catch (e) {
      _error = '영수증 검증 중 오류가 발생했습니다: $e';
      notifyListeners();
      return false;
    }
  }
  
  /// 구독 복원
  Future<bool> restorePurchases() async {
    try {
      await _inAppPurchase.restorePurchases();
      return true;
    } catch (e) {
      _error = '구독 복원 중 오류가 발생했습니다: $e';
      notifyListeners();
      return false;
    }
  }
  
  void _updateStreamOnDone() {
    _subscription?.cancel();
  }
  
  void _updateStreamOnError(dynamic error) {
    _error = '결제 스트림 오류: $error';
    notifyListeners();
  }
  
  @override
  void dispose() {
    _subscription?.cancel();
    super.dispose();
  }
}
