import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

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

/// 구독 관련 서비스
class SubscriptionService extends ChangeNotifier {
  final String _baseUrl = ApiConfig.baseUrl;
  final String _token;
  final String _clubId;
  final String _userId;
  
  Subscription? _currentSubscription;
  List<SubscriptionPlan> _availablePlans = [];
  bool _isLoading = false;
  String? _error;
  
  // 인앱 결제 서비스
  final InAppPurchaseService _purchaseService;
  final http.Client _httpClient;

  // 기본 생성자
  SubscriptionService(this._token, [this._clubId = '', this._userId = '']) : 
    _purchaseService = InAppPurchaseService(),
    _httpClient = http.Client() {
    _loadAvailablePlans();
    _initializeInAppPurchase();
  }
  
  // 테스트용 생성자
  factory SubscriptionService.forTest({
    required http.Client client,
    required InAppPurchaseService purchaseService,
    required String userId,
    required String token,
    required String clubId,
  }) {
    return SubscriptionService._internal(
      token,
      clubId,
      userId,
      client,
      purchaseService,
    );
  }
  
  // 내부 생성자
  SubscriptionService._internal(
    this._token,
    this._clubId,
    this._userId,
    this._httpClient,
    this._purchaseService,
  ) {
    _loadAvailablePlans();
    _initializeInAppPurchase();
  }

  // 게터
  Subscription? get currentSubscription => _currentSubscription;
  List<SubscriptionPlan> get availablePlans => _availablePlans;
  bool get isLoading => _isLoading || _purchaseService.isLoading;
  String? get error => _error ?? _purchaseService.error;
  bool get hasSubscription => _currentSubscription != null;
  bool get isActive => _currentSubscription?.isActive ?? false;
  
  // 인앱 결제 관련 게터
  InAppPurchaseService get purchaseService => _purchaseService;
  List<dynamic> get products => _purchaseService.products;

  /// 현재 구독 정보 로드
  Future<void> loadCurrentSubscription() async {
    _isLoading = true;
    _error = null;
    notifyListeners();

    try {
      final response = await _httpClient.post(
        Uri.parse('$_baseUrl${ApiConfig.currentSubscription}'),
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer $_token',
        },
        body: jsonEncode({
          'clubId': _clubId,
        }),
      );

      if (response.statusCode == 200) {
        final data = jsonDecode(response.body);
        _currentSubscription = Subscription.fromJson(data);
      } else if (response.statusCode == 404) {
        // 구독 정보가 없는 경우 (Free 플랜으로 간주)
        _currentSubscription = Subscription(
          id: 'free',
          userId: _userId,
          planType: SubscriptionPlanType.free,
          status: SubscriptionStatus.active,
          startDate: DateTime.now(),
          endDate: DateTime.now().add(const Duration(days: 36500)), // 100년
          price: 0,
          currency: 'KRW',
          autoRenew: false,
          createdAt: DateTime.now(),
          updatedAt: DateTime.now(),
        );
      } else {
        _error = '구독 정보를 불러오는데 실패했습니다. (${response.statusCode})';
      }
    } catch (e) {
      _error = '구독 정보를 불러오는데 실패했습니다: $e';
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  /// 사용 가능한 구독 플랜 목록 로드
  Future<void> _loadAvailablePlans() async {
    _isLoading = true;
    _error = null;
    notifyListeners();

    try {
      final response = await _httpClient.get(
        Uri.parse('$_baseUrl${ApiConfig.subscriptionPlans}'),
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer $_token',
        },
      );

      if (response.statusCode == 200) {
        final List<dynamic> data = jsonDecode(response.body);
        _availablePlans = data.map((plan) => SubscriptionPlan.fromJson(plan)).toList();
      } else {
        _error = '구독 플랜 정보를 불러오는데 실패했습니다. (${response.statusCode})';
        // 기본 플랜 정보 사용
        _availablePlans = SubscriptionPlan.getDefaultPlans();
      }
    } catch (e) {
      _error = '구독 플랜 정보를 불러오는데 실패했습니다: $e';
      // 기본 플랜 정보 사용
      _availablePlans = SubscriptionPlan.getDefaultPlans();
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  /// 인앱 결제 서비스 초기화
  Future<void> _initializeInAppPurchase() async {
    // 인앱 결제 서비스는 자체적으로 초기화됨
    // 필요한 경우 추가 설정
  }

  /// 구독 복원
  Future<bool> restoreSubscriptions() async {
    _isLoading = true;
    _error = null;
    notifyListeners();

    try {
      // 인앱 구매 복원 시도
      final restored = await _purchaseService.restorePurchases();
      
      if (restored) {
        // 서버에서 현재 구독 정보 가져오기
        await loadCurrentSubscription();
        return true;
      } else {
        _error = '구독을 복원할 수 없습니다.';
        return false;
      }
    } catch (e) {
      _error = '구독 복원 중 오류가 발생했습니다: $e';
      return false;
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  /// 구독 상태 검증
  Future<bool> verifySubscription() async {
    _isLoading = true;
    _error = null;
    notifyListeners();
    
    try {
      final response = await _httpClient.get(
        Uri.parse('$_baseUrl${ApiConfig.currentSubscription}'),
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer $_token',
        },
      );
      
      if (response.statusCode == 200) {
        final data = jsonDecode(response.body);
        _currentSubscription = Subscription.fromJson(data);
        notifyListeners();
        return true;
      } else {
        _error = '구독 검증에 실패했습니다. (${response.statusCode})';
        return false;
      }
    } catch (e) {
      _error = '구독 검증에 실패했습니다: $e';
      return false;
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  /// 새 구독 생성 (인앱 결제 통합)
  Future<bool> createSubscription(SubscriptionPlanType planType, bool isYearly) async {
    _isLoading = true;
    _error = null;
    notifyListeners();

    try {
      // 인앱 결제 시작
      final success = await _purchaseService.purchaseSubscription(planType);
      
      if (!success) {
        _error = '구독 구매 요청에 실패했습니다.';
        _isLoading = false;
        notifyListeners();
        return false;
      }
      
      // 구매 검증 결과 대기
      bool verified = false;
      int attempts = 0;
      const maxAttempts = 10;
      
      // 구매 검증이 완료될 때까지 최대 10회 확인
      while (!verified && attempts < maxAttempts) {
        await Future.delayed(const Duration(seconds: 1));
        verified = _purchaseService.isPurchaseVerified;
        attempts++;
        
        // 오류가 발생한 경우
        if (_purchaseService.error != null) {
          _error = _purchaseService.error;
          _isLoading = false;
          notifyListeners();
          return false;
        }
      }
      
      if (!verified) {
        _error = '구독 검증 시간이 초과되었습니다.';
        _isLoading = false;
        notifyListeners();
        return false;
      }
      
      // 검증된 구매 정보 가져오기
      final verifiedPurchase = _purchaseService.lastVerifiedPurchase;
      if (verifiedPurchase == null) {
        _error = '검증된 구매 정보를 찾을 수 없습니다.';
        _isLoading = false;
        notifyListeners();
        return false;
      }
      
      // 서버에 구독 생성 요청
      final response = await _httpClient.post(
        Uri.parse('$_baseUrl${ApiConfig.subscribeClub}'),
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer $_token',
        },
        body: jsonEncode({
          'planType': planType.toString().split('.').last,
          'isYearly': isYearly,
          'clubId': _clubId,
          'transactionId': verifiedPurchase.purchaseID,
          'productId': verifiedPurchase.productID,
          'verificationData': verifiedPurchase.verificationData.serverVerificationData,
        }),
      );

      if (response.statusCode == 200) {
        final data = jsonDecode(response.body);
        _currentSubscription = Subscription.fromJson(data);
        
        // 구매 검증 상태 초기화
        _purchaseService.isPurchaseVerified = false;
        _purchaseService.lastVerifiedPurchase = null;
        
        notifyListeners();
        return true;
      } else {
        _error = '구독 생성에 실패했습니다. (${response.statusCode})';
        return false;
      }
    } catch (e) {
      _error = '구독 생성 중 오류가 발생했습니다: $e';
      return false;
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  /// 구독 취소
  Future<bool> cancelSubscription() async {
    if (_currentSubscription == null) {
      _error = '취소할 구독이 없습니다.';
      notifyListeners();
      return false;
    }

    _isLoading = true;
    _error = null;
    notifyListeners();

    try {
      final response = await _httpClient.post(
        Uri.parse('$_baseUrl${ApiConfig.subscriptions}/${_currentSubscription!.id}/cancel'),
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer $_token',
        },
      );

      if (response.statusCode == 200) {
        final data = jsonDecode(response.body);
        _currentSubscription = Subscription.fromJson(data);
        notifyListeners();
        return true;
      } else {
        _error = '구독 취소에 실패했습니다. (${response.statusCode})';
        return false;
      }
    } catch (e) {
      _error = '구독 취소에 실패했습니다: $e';
      return false;
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  /// 구독 플랜 변경
  Future<bool> changePlan(SubscriptionPlanType newPlanType, bool isYearly) async {
    if (_currentSubscription == null) {
      _error = '변경할 구독이 없습니다.';
      notifyListeners();
      return false;
    }

    _isLoading = true;
    _error = null;
    notifyListeners();

    try {
      final response = await _httpClient.post(
        Uri.parse('$_baseUrl${ApiConfig.changePlan}'),
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer $_token',
        },
        body: jsonEncode({
          'subscriptionId': _currentSubscription!.id,
          'planType': newPlanType.toString().split('.').last,
          'isYearly': isYearly,
          'clubId': _clubId,
        }),
      );

      if (response.statusCode == 200) {
        final data = jsonDecode(response.body);
        _currentSubscription = Subscription.fromJson(data);
        notifyListeners();
        return true;
      } else {
        _error = '구독 플랜 변경에 실패했습니다. (${response.statusCode})';
        return false;
      }
    } catch (e) {
      _error = '구독 플랜 변경에 실패했습니다: $e';
      return false;
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  /// 자동 갱신 설정 변경
  Future<bool> toggleAutoRenew() async {
    if (_currentSubscription == null) {
      _error = '변경할 구독이 없습니다.';
      notifyListeners();
      return false;
    }

    _isLoading = true;
    _error = null;
    notifyListeners();

    try {
      final response = await _httpClient.post(
        Uri.parse('$_baseUrl${ApiConfig.subscriptions}/autorenew'),
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer $_token',
        },
        body: jsonEncode({
          'subscriptionId': _currentSubscription!.id,
          'autoRenew': !_currentSubscription!.autoRenew,
          'clubId': _clubId,
        }),
      );

      if (response.statusCode == 200) {
        final data = jsonDecode(response.body);
        _currentSubscription = Subscription.fromJson(data);
        notifyListeners();
        return true;
      } else {
        _error = '자동 갱신 설정 변경에 실패했습니다. (${response.statusCode})';
        return false;
      }
    } catch (e) {
      _error = '자동 갱신 설정 변경에 실패했습니다: $e';
      return false;
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  /// 특정 기능이 현재 구독에서 사용 가능한지 확인
  bool canUseFeature(String featureName) {
    if (_currentSubscription == null || !_currentSubscription!.isActive) {
      return false;
    }

    // 기능별 접근 권한 확인 로직
    switch (featureName) {
      case 'advancedStats':
        return _getSubscriptionPlan(_currentSubscription!.planType).hasAdvancedStats;
      case 'customization':
        return _getSubscriptionPlan(_currentSubscription!.planType).hasCustomization;
      case 'prioritySupport':
        return _getSubscriptionPlan(_currentSubscription!.planType).hasPriority;
      default:
        return false;
    }
  }

  /// 현재 구독으로 추가 가능한 최대 회원 수 확인
  int getMaxMembers() {
    if (_currentSubscription == null || !_currentSubscription!.isActive) {
      return SubscriptionPlan.getDefaultPlans().first.maxMembers; // 무료 플랜
    }
    return _getSubscriptionPlan(_currentSubscription!.planType).maxMembers;
  }

  /// 현재 구독으로 추가 가능한 최대 이벤트 수 확인
  int getMaxEvents() {
    if (_currentSubscription == null || !_currentSubscription!.isActive) {
      return SubscriptionPlan.getDefaultPlans().first.maxEvents; // 무료 플랜
    }
    return _getSubscriptionPlan(_currentSubscription!.planType).maxEvents;
  }

  /// 구독 플랜 타입에 해당하는 플랜 정보 가져오기
  SubscriptionPlan _getSubscriptionPlan(SubscriptionPlanType planType) {
    return _availablePlans.firstWhere(
      (plan) => plan.type == planType,
      orElse: () => SubscriptionPlan.getDefaultPlans().first,
    );
  }
}
