import 'package:get/get.dart';
import '../models/chit_group.dart';
import '../models/group_member.dart';
import '../models/payment.dart';
import '../models/monthly_draw.dart';
import '../models/financial_table_entry.dart';
import '../models/user.dart';
import 'api_service.dart';

class ChitGroupService extends GetxController {
  static ChitGroupService get to => Get.find();
  
  final _apiService = ApiService();
  
  final _isLoading = false.obs;
  final _chitGroups = <ChitGroup>[].obs;
  final _selectedGroup = Rxn<ChitGroup>();
  final _groupMembers = <GroupMember>[].obs;
  final _groupPayments = <Payment>[].obs;
  final _groupStats = Rxn<Map<String, dynamic>>();
  final _monthlyDraws = <MonthlyDraw>[].obs;
  final _drawStats = Rxn<Map<String, dynamic>>();
  final _financialData = <FinancialTableEntry>[].obs;

  RxBool get isLoading => _isLoading;
  RxList<ChitGroup> get chitGroups => _chitGroups;
  Rxn<ChitGroup> get selectedGroup => _selectedGroup;
  RxList<GroupMember> get groupMembers => _groupMembers;
  RxList<Payment> get groupPayments => _groupPayments;
  Rxn<Map<String, dynamic>> get groupStats => _groupStats;
  RxList<MonthlyDraw> get monthlyDraws => _monthlyDraws;
  Rxn<Map<String, dynamic>> get drawStats => _drawStats;
  RxList<FinancialTableEntry> get financialData => _financialData;

  // Load manager's chit groups
  Future<void> loadManagerChitGroups({String? status}) async {
    try {
      _isLoading.value = true;
      
      final response = await _apiService.getManagerChitGroups(status: status);
      
      if (response['success']) {
        final groupsData = response['data']['chitGroups'] as List;
        print('Loading ${groupsData.length} chit groups');
        _chitGroups.value = groupsData.map((json) {
          try {
            return ChitGroup.fromJson(json);
          } catch (e) {
            print('Error parsing chit group: $e');
            print('JSON data: $json');
            rethrow;
          }
        }).toList();
        print('Successfully loaded ${_chitGroups.length} chit groups');
      } else {
        print('API returned error: ${response['message']}');
        Get.snackbar('Error', response['message']);
      }
    } catch (e) {
      print('Error loading manager chit groups: $e');
      Get.snackbar('Error', 'Failed to load chit groups');
    } finally {
      _isLoading.value = false;
    }
  }

  // Load member's chit groups
  Future<void> loadMemberChitGroups({String? status}) async {
    try {
      _isLoading.value = true;
      
      final response = await _apiService.getMemberChitGroups(status: status);
      
      if (response['success']) {
        final groupsData = response['data']['chitGroups'] as List;
        _chitGroups.value = groupsData.map((json) => ChitGroup.fromJson(json)).toList();
      } else {
        Get.snackbar('Error', response['message']);
      }
    } catch (e) {
      print('Error loading member chit groups: $e');
      Get.snackbar('Error', 'Failed to load chit groups');
    } finally {
      _isLoading.value = false;
    }
  }

  // Create new chit group
  Future<bool> createChitGroup(Map<String, dynamic> data) async {
    try {
      _isLoading.value = true;
      
      final response = await _apiService.createChitGroup(data);
      
      if (response['success']) {
        final newGroup = ChitGroup.fromJson(response['data']);
        _chitGroups.add(newGroup);
        Get.snackbar('Success', 'Chitfund created successfully');
        return true;
      } else {
        Get.snackbar('Error', response['message']);
        return false;
      }
    } catch (e) {
      print('Error creating chit group: $e');
      Get.snackbar('Error', 'Failed to create chit group');
      return false;
    } finally {
      _isLoading.value = false;
    }
  }

  // Load chit group details
  Future<void> loadChitGroupDetails(String groupId) async {
    try {
      _isLoading.value = true;
      
      final response = await _apiService.getChitGroupDetails(groupId);
      
      if (response['success']) {
        final group = ChitGroup.fromJson(response['data']);
        _selectedGroup.value = group;
      } else {
        Get.snackbar('Error', response['message']);
      }
    } catch (e) {
      print('Error loading chit group details: $e');
      Get.snackbar('Error', 'Failed to load group details');
    } finally {
      _isLoading.value = false;
    }
  }

  // Load group members
  Future<void> loadGroupMembers(String groupId, {String? status}) async {
    try {
      _isLoading.value = true;
      
      final response = await _apiService.getGroupMembers(groupId, status: status);
      
      if (response['success']) {
        final membersData = response['data']['members'] as List;
        _groupMembers.value = membersData.map((json) => GroupMember.fromJson(json)).toList();
      } else {
        Get.snackbar('Error', response['message']);
      }
    } catch (e) {
      print('Error loading group members: $e');
      Get.snackbar('Error', 'Failed to load group members');
    } finally {
      _isLoading.value = false;
    }
  }

  // Add member to group
  Future<bool> addMemberToGroup(String groupId, Map<String, dynamic> memberData) async {
    try {
      _isLoading.value = true;
      
      final response = await _apiService.addMemberToGroup(groupId, memberData);
      
      if (response['success']) {
        // Reload group members
        await loadGroupMembers(groupId);
        Get.snackbar('Success', 'Member added successfully');
        return true;
      } else {
        Get.snackbar('Error', response['message']);
        return false;
      }
    } catch (e) {
      print('Error adding member: $e');
      Get.snackbar('Error', 'Failed to add member');
      return false;
    } finally {
      _isLoading.value = false;
    }
  }

  // Remove member from group
  Future<bool> removeMemberFromGroup(String groupId, String memberId) async {
    try {
      _isLoading.value = true;
      
      final response = await _apiService.removeMemberFromGroup(groupId, memberId);
      
      if (response['success']) {
        // Reload group members
        await loadGroupMembers(groupId);
        Get.snackbar('Success', 'Member removed successfully');
        return true;
      } else {
        Get.snackbar('Error', response['message']);
        return false;
      }
    } catch (e) {
      print('Error removing member: $e');
      Get.snackbar('Error', 'Failed to remove member');
      return false;
    } finally {
      _isLoading.value = false;
    }
  }

  // Get all users for adding to groups
  Future<List<User>> getAllUsers({String? search, int page = 1, int limit = 50}) async {
    try {
      final response = await _apiService.getAllUsers(search: search, page: page, limit: limit);
      print('API Response: $response');
      
      if (response['success'] == true && response['data'] != null) {
        final usersData = response['data']['users'] as List;
        print('Users data: $usersData');
        return usersData.map((userData) => User.fromJson(userData)).toList();
      } else {
        print('API returned success: false or no data');
        print('Response: $response');
      }
      return [];
    } catch (e) {
      print('Error getting all users: $e');
      print('Error type: ${e.runtimeType}');
      return [];
    }
  }

  Future<List<User>> getAvailableUsersForGroup(String groupId) async {
    try {
      final response = await _apiService.getAvailableUsersForGroup(groupId);
      print('Available users API Response: $response');
      
      if (response['success'] == true && response['data'] != null) {
        final usersData = response['data']['users'] as List;
        print('Available users data: $usersData');
        return usersData.map((userData) => User.fromJson(userData)).toList();
      } else {
        print('Available users API returned success: false or no data');
        print('Response: $response');
      }
      return [];
    } catch (e) {
      print('Error getting available users for group: $e');
      print('Error type: ${e.runtimeType}');
      return [];
    }
  }

  // Update member status
  Future<bool> updateMemberStatus(String groupId, String memberId, String status) async {
    try {
      _isLoading.value = true;
      
      final response = await _apiService.updateMemberStatus(groupId, memberId, status);
      
      if (response['success']) {
        // Reload group members
        await loadGroupMembers(groupId);
        Get.snackbar('Success', 'Member status updated successfully');
        return true;
      } else {
        Get.snackbar('Error', response['message']);
        return false;
      }
    } catch (e) {
      print('Error updating member status: $e');
      Get.snackbar('Error', 'Failed to update member status');
      return false;
    } finally {
      _isLoading.value = false;
    }
  }

  // Load group payments
  Future<void> loadGroupPayments(String groupId, {String? status, int? month, int? year}) async {
    try {
      _isLoading.value = true;
      
      final response = await _apiService.getGroupPayments(groupId, status: status, month: month, year: year);
      
      if (response['success']) {
        final paymentsData = response['data']['payments'] as List;
        _groupPayments.value = paymentsData.map((json) => Payment.fromJson(json)).toList();
      } else {
        Get.snackbar('Error', response['message']);
      }
    } catch (e) {
      print('Error loading group payments: $e');
      Get.snackbar('Error', 'Failed to load payments');
    } finally {
      _isLoading.value = false;
    }
  }

  // Record payment
  Future<bool> recordPayment(Map<String, dynamic> data) async {
    try {
      _isLoading.value = true;
      
      final response = await _apiService.recordPayment(data);
      
      if (response['success']) {
        // Reload group payments
        await loadGroupPayments(data['group_id']);
        Get.snackbar('Success', 'Payment recorded successfully');
        return true;
      } else {
        Get.snackbar('Error', response['message']);
        return false;
      }
    } catch (e) {
      print('Error recording payment: $e');
      Get.snackbar('Error', 'Failed to record payment');
      return false;
    } finally {
      _isLoading.value = false;
    }
  }

  // Load group statistics
  Future<void> loadGroupStats(String groupId) async {
    try {
      _isLoading.value = true;
      
      final response = await _apiService.getChitGroupStats(groupId);
      
      if (response['success']) {
        _groupStats.value = response['data'];
      } else {
        Get.snackbar('Error', response['message']);
      }
    } catch (e) {
      print('Error loading group stats: $e');
      Get.snackbar('Error', 'Failed to load group statistics');
    } finally {
      _isLoading.value = false;
    }
  }

  // Start chit group
  Future<bool> startChitGroup(String groupId) async {
    try {
      _isLoading.value = true;
      
      final response = await _apiService.startChitGroup(groupId);
      
      if (response['success']) {
        // Update the group in the list
        final index = _chitGroups.indexWhere((group) => group.id == groupId);
        if (index != -1) {
          final updatedGroup = ChitGroup.fromJson(response['data']);
          _chitGroups[index] = updatedGroup;
        }
        Get.snackbar('Success', 'Chitfund started successfully');
        return true;
      } else {
        Get.snackbar('Error', response['message']);
        return false;
      }
    } catch (e) {
      print('Error starting chit group: $e');
      Get.snackbar('Error', 'Failed to start chit group');
      return false;
    } finally {
      _isLoading.value = false;
    }
  }

  // Clear selected group
  void clearSelectedGroup() {
    _selectedGroup.value = null;
    _groupMembers.clear();
    _groupPayments.clear();
    _groupStats.value = null;
    _monthlyDraws.clear();
    _drawStats.value = null;
  }

  // Load group monthly draws
  Future<void> loadGroupMonthlyDraws(String groupId, {String? status}) async {
    try {
      _isLoading.value = true;
      
      final response = await _apiService.getGroupMonthlyDraws(groupId, status: status);
      
      if (response['success']) {
        final drawsData = response['data']['monthlyDraws'] as List;
        _monthlyDraws.value = drawsData.map((json) => MonthlyDraw.fromJson(json)).toList();
      } else {
        Get.snackbar('Error', response['message']);
      }
    } catch (e) {
      print('Error loading group monthly draws: $e');
      Get.snackbar('Error', 'Failed to load monthly draws');
    } finally {
      _isLoading.value = false;
    }
  }

  // Create monthly draw
  Future<bool> createMonthlyDraw(String groupId, int month, int year, {String? clientSeed}) async {
    try {
      _isLoading.value = true;
      
      final drawData = {
        'group_id': groupId,
        'month': month,
        'year': year,
        if (clientSeed != null) 'client_seed': clientSeed,
      };

      final response = await _apiService.createMonthlyDraw(drawData);
      
      if (response['success']) {
        // Reload monthly draws
        await loadGroupMonthlyDraws(groupId);
        Get.snackbar('Success', 'Monthly draw completed successfully');
        return true;
      } else {
        Get.snackbar('Error', response['message']);
        return false;
      }
    } catch (e) {
      print('Error creating monthly draw: $e');
      Get.snackbar('Error', 'Failed to create monthly draw');
      return false;
    } finally {
      _isLoading.value = false;
    }
  }

  // Load draw statistics
  Future<void> loadDrawStatistics(String groupId) async {
    try {
      _isLoading.value = true;
      
      final response = await _apiService.getDrawStatistics(groupId);
      
      if (response['success']) {
        _drawStats.value = response['data'];
      } else {
        Get.snackbar('Error', response['message']);
      }
    } catch (e) {
      print('Error loading draw statistics: $e');
      Get.snackbar('Error', 'Failed to load draw statistics');
    } finally {
      _isLoading.value = false;
    }
  }

  // Load group financial data
  Future<void> loadGroupFinancialData(String groupId) async {
    try {
      _isLoading.value = true;
      
      final response = await _apiService.getGroupFinancialData(groupId);
      
      if (response['success']) {
        print('Financial data response: ${response['data']}');
        final financialData = response['data']['financial_data'] as List<dynamic>;
        print('Financial data list length: ${financialData.length}');
        
        final entries = financialData.map((json) {
          print('Processing entry: $json');
          return FinancialTableEntry.fromJson(json as Map<String, dynamic>);
        }).toList();
        
        print('Created ${entries.length} financial entries');
        _financialData.value = entries;
      } else {
        print('API returned error: ${response['message']}');
        Get.snackbar('Error', response['message']);
      }
    } catch (e) {
      print('Error loading group financial data: $e');
      print('Error stack trace: ${e.toString()}');
      Get.snackbar('Error', 'Failed to load financial data');
    } finally {
      _isLoading.value = false;
    }
  }

  // Generate sample financial data for testing
  List<FinancialTableEntry> generateSampleFinancialData(ChitGroup group) {
    final List<FinancialTableEntry> entries = [];
    final int totalMonths = group.durationMonths;
    final double chitValue = group.totalValue;
    final double monthlyInstallment = group.monthlyInstallment;
    final double commission = group.foremanCommissionAmount;
    final startDate = group.startDate;
    
    // Return empty data if startDate is null
    if (startDate == null) {
      return entries;
    }
    
    // Calculate bid amounts using the same logic as schedule screen
    // Starting at 87.65% of chit value and increasing by ₹2,600 each month
    final double bidIncrement = 2600;
    double currentBidAmount = chitValue * 0.8765; // Starting at 87.65% of chit value
    
    for (int i = 0; i < totalMonths; i++) {
      final monthDate = DateTime(startDate.year, startDate.month + i);
      final monthName = _getMonthName(monthDate.month - 1);
      final monthYear = '$monthName-${monthDate.year.toString().substring(2)}';
      
      // Calculate dividend (difference between chit value and bid amount)
      final dividend = chitValue - currentBidAmount;
      
      entries.add(FinancialTableEntry(
        monthYear: monthYear,
        chitValue: chitValue,
        bidAmount: currentBidAmount,
        subscriptionAmount: monthlyInstallment,
        commissionInstallment: commission,
        totalPayableInstallment: monthlyInstallment + commission,
        dividendAmount: dividend,
      ));
      
      // Increase bid amount for next month
      currentBidAmount += bidIncrement;
    }
    
    // Add total row
    final totalChitValue = chitValue * totalMonths;
    final totalBidAmount = entries.fold(0.0, (sum, entry) => sum + entry.bidAmount);
    final totalSubscription = monthlyInstallment * totalMonths;
    final totalCommission = commission * totalMonths;
    final totalPayable = (monthlyInstallment + commission) * totalMonths;
    final totalDividend = entries.fold(0.0, (sum, entry) => sum + entry.dividendAmount);
    
    entries.add(FinancialTableEntry(
      monthYear: 'Total',
      chitValue: totalChitValue,
      bidAmount: totalBidAmount,
      subscriptionAmount: totalSubscription,
      commissionInstallment: totalCommission,
      totalPayableInstallment: totalPayable,
      dividendAmount: totalDividend,
    ));
    
    return entries;
  }

  String _getMonthName(int monthIndex) {
    const months = [
      'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
      'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
    ];
    return months[monthIndex];
  }
}
