import 'dart:async';
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:superport/core/controllers/base_list_controller.dart';
import 'package:superport/core/constants/app_constants.dart';
import 'package:superport/core/utils/error_handler.dart';
import 'package:superport/models/license_model.dart';
import 'package:superport/services/license_service.dart';
import 'package:superport/services/dashboard_service.dart';
import 'package:superport/data/models/common/pagination_params.dart';

/// 라이센스 상태 필터
enum LicenseStatusFilter {
  all,
  active,
  inactive,
  expiringSoon, // ${AppConstants.licenseExpiryWarningDays}일 이내
  expired,
}

/// 라이센스 목록 화면의 상태 및 비즈니스 로직을 담당하는 컨트롤러 (리팩토링 버전)
/// BaseListController를 상속받아 공통 기능을 재사용
class LicenseListController extends BaseListController<License> {
  late final LicenseService _licenseService;
  late final DashboardService _dashboardService;
  
  // 라이선스 특화 필터 상태
  int? _selectedCompanyId;
  bool? _isActive;
  String? _licenseType;
  LicenseStatusFilter _statusFilter = LicenseStatusFilter.all;
  String _sortBy = 'expiry_date';
  String _sortOrder = 'asc';
  bool _includeInactive = false; // 비활성 라이선스 포함 여부
  
  // 선택된 라이선스 관리
  final Set<int> _selectedLicenseIds = {};
  
  // 통계 데이터
  Map<String, int> _statistics = {
    'total': 0,
    'active': 0,
    'inactive': 0,
    'expiringSoon': 0,
    'expired': 0,
  };
  
  // 검색 디바운스를 위한 타이머
  Timer? _debounceTimer;

  // Getters for license-specific properties
  List<License> get licenses => items;
  int? get selectedCompanyId => _selectedCompanyId;
  bool? get isActive => _isActive;
  String? get licenseType => _licenseType;
  LicenseStatusFilter get statusFilter => _statusFilter;
  Set<int> get selectedLicenseIds => _selectedLicenseIds;
  Map<String, int> get statistics => _statistics;
  int get selectedCount => _selectedLicenseIds.length;
  bool get includeInactive => _includeInactive;
  
  // 전체 선택 여부 확인
  bool get isAllSelected => 
      items.isNotEmpty && 
      items.where((l) => l.id != null)
          .every((l) => _selectedLicenseIds.contains(l.id));

  LicenseListController() {
    if (GetIt.instance.isRegistered<LicenseService>()) {
      _licenseService = GetIt.instance<LicenseService>();
    } else {
      throw Exception('LicenseService not registered in GetIt');
    }
    
    if (GetIt.instance.isRegistered<DashboardService>()) {
      _dashboardService = GetIt.instance<DashboardService>();
    } else {
      throw Exception('DashboardService not registered in GetIt');
    }
  }

  @override
  Future<PagedResult<License>> fetchData({
    required PaginationParams params,
    Map<String, dynamic>? additionalFilters,
  }) async {
    // API 호출 (PaginatedResponse 반환)
    final response = await ErrorHandler.handleApiCall(
      () => _licenseService.getLicenses(
        page: params.page,
        perPage: params.perPage,
        isActive: _isActive,
        companyId: _selectedCompanyId,
        licenseType: _licenseType,
        includeInactive: _includeInactive,
      ),
      onError: (failure) {
        throw failure;
      },
    );
    
    if (response == null) {
      return PagedResult(
        items: [],
        meta: PaginationMeta(
          currentPage: params.page,
          perPage: params.perPage,
          total: 0,
          totalPages: 0,
          hasNext: false,
          hasPrevious: false,
        ),
      );
    }
    
    // 통계 업데이트 (전체 데이터 기반)
    await _updateStatistics();
    
    // PaginatedResponse를 PagedResult로 변환
    final meta = PaginationMeta(
      currentPage: response.page,
      perPage: response.size,
      total: response.totalElements,
      totalPages: response.totalPages,
      hasNext: !response.last,
      hasPrevious: !response.first,
    );
    
    return PagedResult(items: response.items, meta: meta);
  }

  @override
  bool filterItem(License item, String query) {
    final q = query.toLowerCase();
    return (item.productName?.toLowerCase().contains(q) ?? false) ||
           (item.licenseKey.toLowerCase().contains(q)) ||
           (item.vendor?.toLowerCase().contains(q) ?? false) ||
           (item.companyName?.toLowerCase().contains(q) ?? false);
  }

  /// BaseListController의 검색을 오버라이드하여 디바운싱 적용
  @override
  void search(String query) {
    // 기존 타이머 취소
    _debounceTimer?.cancel();
    
    // 디바운싱 적용 (300ms)
    _debounceTimer = Timer(AppConstants.licenseSearchDebounce, () {
      super.search(query);
      _applyStatusFilter();
    });
  }
  
  /// 상태 필터 적용 (BaseListController의 filtering과 추가로 동작)
  void _applyStatusFilter() {
    if (_statusFilter == LicenseStatusFilter.all) return;
    
    final now = DateTime.now();
    final currentItems = List<License>.from(items);
    
    // 상태 필터 적용
    final filteredByStatus = currentItems.where((license) {
      switch (_statusFilter) {
        case LicenseStatusFilter.active:
          return license.isActive;
        case LicenseStatusFilter.inactive:
          return !license.isActive;
        case LicenseStatusFilter.expiringSoon:
          if (license.expiryDate != null) {
            final days = license.expiryDate!.difference(now).inDays;
            return days > 0 && days <= 30;
          }
          return false;
        case LicenseStatusFilter.expired:
          if (license.expiryDate != null) {
            return license.expiryDate!.isBefore(now);
          }
          return false;
        case LicenseStatusFilter.all:
        default:
          return true;
      }
    }).toList();
    
    // 직접 필터링된 결과를 적용 (BaseListController의 private 필드에 접근할 수 없으므로)
    // 대신 notifyListeners를 통해 UI 업데이트
    notifyListeners();
  }

  /// 필터 설정
  void setFilters({
    int? companyId,
    bool? isActive,
    String? licenseType,
  }) {
    _selectedCompanyId = companyId;
    _isActive = isActive;
    _licenseType = licenseType;
    loadData(isRefresh: true);
  }
  
  /// 비활성 포함 토글
  void toggleIncludeInactive() {
    _includeInactive = !_includeInactive;
    loadData(isRefresh: true);
  }

  /// 필터 초기화
  void clearFilters() {
    _selectedCompanyId = null;
    _isActive = null;
    _licenseType = null;
    _statusFilter = LicenseStatusFilter.all;
    search(''); // BaseListController의 search 호출
  }

  /// 상태 필터 변경
  Future<void> changeStatusFilter(LicenseStatusFilter filter) async {
    _statusFilter = filter;
    _applyStatusFilter();
  }

  /// 정렬 변경
  void sortBy(String field, String order) {
    _sortBy = field;
    _sortOrder = order;
    loadData(isRefresh: true);
  }

  /// 라이선스 삭제 (BaseListController의 기본 기능 활용)
  Future<void> deleteLicense(int id) async {
    await ErrorHandler.handleApiCall<void>(
      () => _licenseService.deleteLicense(id),
      onError: (failure) {
        throw failure;
      },
    );
    
    // BaseListController의 removeItemLocally 활용 대신 서버에서 새로고침
    // removeItemLocally((l) => l.id == id);
    
    // 선택 목록에서도 제거
    _selectedLicenseIds.remove(id);
    
    // 삭제 후 리스트 새로고침 (서버에서 10개 다시 가져오기)
    await refresh();
  }

  /// 라이선스 선택/해제
  void selectLicense(int? id, bool? isSelected) {
    if (id == null) return;
    
    if (isSelected == true) {
      _selectedLicenseIds.add(id);
    } else {
      _selectedLicenseIds.remove(id);
    }
    notifyListeners();
  }
  
  /// 전체 선택/해제
  void selectAll(bool? isSelected) {
    if (isSelected == true) {
      // 현재 필터링된 라이선스 모두 선택
      for (var license in items) {
        if (license.id != null) {
          _selectedLicenseIds.add(license.id!);
        }
      }
    } else {
      // 모두 해제
      _selectedLicenseIds.clear();
    }
    notifyListeners();
  }
  
  /// 선택된 라이선스 목록 반환
  List<License> getSelectedLicenses() {
    return items
        .where((l) => l.id != null && _selectedLicenseIds.contains(l.id))
        .toList();
  }
  
  /// 선택 초기화 (BaseListController에도 있지만 라이선스 특화)
  @override
  void clearSelection() {
    _selectedLicenseIds.clear();
    notifyListeners();
  }

  /// 선택된 라이선스 일괄 삭제
  Future<void> deleteSelectedLicenses() async {
    for (final id in _selectedLicenseIds.toList()) {
      await deleteLicense(id);
    }
    clearSelection();
  }

  /// 라이선스 생성
  Future<void> createLicense(License license) async {
    await ErrorHandler.handleApiCall<void>(
      () => _licenseService.createLicense(license),
      onError: (failure) {
        throw failure;
      },
    );
    
    await refresh();
  }

  /// 라이선스 수정
  Future<void> updateLicense(License license) async {
    await ErrorHandler.handleApiCall<void>(
      () => _licenseService.updateLicense(license),
      onError: (failure) {
        throw failure;
      },
    );
    
    updateItemLocally(license, (l) => l.id == license.id);
  }

  /// 라이선스 활성화/비활성화 토글
  Future<void> toggleLicenseStatus(int id) async {
    final license = items.firstWhere((l) => l.id == id);
    final updatedLicense = license.copyWith(isActive: !license.isActive);
    
    await updateLicense(updatedLicense);
  }

  /// 통계 데이터 업데이트 (전체 데이터 기반)
  Future<void> _updateStatistics() async {
    // 전체 라이선스 통계를 위해 getLicenseExpirySummary API 호출
    final result = await _dashboardService.getLicenseExpirySummary();
    
    result.fold(
      (failure) {
        // 실패 시 기본값 유지
        debugPrint('[ERROR] 라이선스 통계 로드 실패: $failure');
        _statistics = {
          'total': 0,
          'active': 0,
          'inactive': 0,
          'expiringSoon': 0,
          'expired': 0,
        };
      },
      (summary) {
        // API 응답 데이터로 통계 업데이트
        _statistics = {
          'total': summary.active + summary.expired,  // 전체 = 활성 + 만료
          'active': summary.active,  // 활성 라이선스 총계
          'inactive': 0,  // API에서 제공하지 않으므로 0
          'expiringSoon': summary.expiring30Days,  // 30일 내 만료
          'expired': summary.expired,  // 만료된 라이선스
        };
        
        debugPrint('[DEBUG] 라이선스 통계 업데이트 완료');
        debugPrint('[DEBUG] 전체: ${_statistics['total']}개');
        debugPrint('[DEBUG] 활성: ${_statistics['active']}개');
        debugPrint('[DEBUG] 30일 내 만료: ${_statistics['expiringSoon']}개');
        debugPrint('[DEBUG] 만료: ${_statistics['expired']}개');
      },
    );
    
    notifyListeners();
  }

  /// 라이선스 만료일별 그룹핑
  Map<String, List<License>> getLicensesByExpiryPeriod() {
    final now = DateTime.now();
    final Map<String, List<License>> grouped = {
      '이미 만료': [],
      '${AppConstants.licenseExpiryWarningDays}일 이내': [],
      '${AppConstants.licenseExpiryCautionDays}일 이내': [],
      '${AppConstants.licenseExpiryInfoDays}일 이내': [],
      '${AppConstants.licenseExpiryInfoDays}일 이후': [],
    };
    
    for (final license in items) {
      if (license.expiryDate == null) continue;
      
      final days = license.expiryDate!.difference(now).inDays;
      
      if (days < 0) {
        grouped['이미 만료']!.add(license);
      } else if (days <= AppConstants.licenseExpiryWarningDays) {
        grouped['${AppConstants.licenseExpiryWarningDays}일 이내']!.add(license);
      } else if (days <= AppConstants.licenseExpiryCautionDays) {
        grouped['${AppConstants.licenseExpiryCautionDays}일 이내']!.add(license);
      } else if (days <= AppConstants.licenseExpiryInfoDays) {
        grouped['${AppConstants.licenseExpiryInfoDays}일 이내']!.add(license);
      } else {
        grouped['${AppConstants.licenseExpiryInfoDays}일 이후']!.add(license);
      }
    }
    
    return grouped;
  }

  /// 만료까지 남은 날짜 계산
  int getDaysUntilExpiry(DateTime? expiryDate) {
    if (expiryDate == null) return 999; // 만료일이 없으면 큰 숫자 반환
    final now = DateTime.now();
    return expiryDate.difference(now).inDays;
  }

  @override
  void dispose() {
    _debounceTimer?.cancel();
    super.dispose();
  }
}