import 'package:flutter/material.dart';
import '../../../data/models/maintenance_dto.dart';
import '../../../domain/usecases/maintenance_usecase.dart';
import '../../../utils/constants.dart';

/// 유지보수 컨트롤러 (백엔드 실제 스키마 기반)
class MaintenanceController extends ChangeNotifier {
  final MaintenanceUseCase _maintenanceUseCase;
  
  // 상태 관리 (단순화)
  List<MaintenanceDto> _maintenances = [];
  bool _isLoading = false;
  String? _error;
  
  // 페이지네이션
  int _currentPage = 1;
  int _totalCount = 0;
  static const int _pageSize = PaginationConstants.defaultPageSize;
  
  // 필터 (백엔드 실제 필드만)
  String? _maintenanceType;
  int? _equipmentHistoryId;
  
  // 선택된 유지보수
  MaintenanceDto? _selectedMaintenance;
  
  // Getters (단순화)
  List<MaintenanceDto> get maintenances => _maintenances;
  bool get isLoading => _isLoading;
  String? get error => _error;
  int get currentPage => _currentPage;
  int get totalPages => (_totalCount / _pageSize).ceil();
  int get totalCount => _totalCount;
  MaintenanceDto? get selectedMaintenance => _selectedMaintenance;
  
  MaintenanceController({required MaintenanceUseCase maintenanceUseCase})
      : _maintenanceUseCase = maintenanceUseCase;
  
  // 유지보수 목록 로드 (백엔드 단순 구조)
  Future<void> loadMaintenances({bool refresh = false}) async {
    if (refresh) {
      _currentPage = 1;
      _maintenances.clear();
    }
    
    _isLoading = true;
    _error = null;
    notifyListeners();
    
    try {
      final response = await _maintenanceUseCase.getMaintenances(
        page: _currentPage,
        pageSize: _pageSize,
        equipmentHistoryId: _equipmentHistoryId,
        maintenanceType: _maintenanceType,
      );
      
      // response는 List<MaintenanceDto> 타입 (단순한 배열)
      final maintenanceList = response as List<MaintenanceDto>;
      if (refresh) {
        _maintenances = maintenanceList;
      } else {
        _maintenances.addAll(maintenanceList);
      }
      
      _totalCount = maintenanceList.length;
      
      notifyListeners();
    } catch (e) {
      _error = e.toString();
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }
  
  // 특정 장비 이력의 유지보수 로드
  Future<void> loadMaintenancesByEquipmentHistory(int equipmentHistoryId) async {
    _isLoading = true;
    _error = null;
    _equipmentHistoryId = equipmentHistoryId;
    notifyListeners();
    
    try {
      _maintenances = await _maintenanceUseCase.getMaintenancesByEquipmentHistory(
        equipmentHistoryId,
      );
      notifyListeners();
    } catch (e) {
      _error = e.toString();
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }
  
  // 간단한 통계 (백엔드 데이터 기반)
  int get totalMaintenances => _maintenances.length;
  int get activeMaintenances => _maintenances.where((m) => !(m.isDeleted ?? false)).length;
  int get completedMaintenances => _maintenances.where((m) => m.endedAt != null && m.endedAt!.isBefore(DateTime.now())).length;
  
  // 유지보수 생성 (백엔드 실제 스키마)
  Future<bool> createMaintenance({
    required int equipmentHistoryId,
    required DateTime startedAt,
    required DateTime endedAt,
    required int periodMonth,
    required String maintenanceType,
  }) async {
    _isLoading = true;
    _error = null;
    notifyListeners();
    
    try {
      final maintenance = await _maintenanceUseCase.createMaintenance(
        MaintenanceRequestDto(
          equipmentHistoryId: equipmentHistoryId,
          startedAt: startedAt,
          endedAt: endedAt,
          periodMonth: periodMonth,
          maintenanceType: maintenanceType,
        ),
      );
      
      _maintenances.insert(0, maintenance);
      _totalCount++;
      
      notifyListeners();
      return true;
    } catch (e) {
      _error = '유지보수 등록 실패: ${e.toString()}';
      return false;
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }
  
  // 유지보수 수정 (백엔드 실제 스키마)
  Future<bool> updateMaintenance({
    required int id,
    DateTime? startedAt,
    DateTime? endedAt,
    int? periodMonth,
    String? maintenanceType,
  }) async {
    _isLoading = true;
    _error = null;
    notifyListeners();
    
    try {
      final updatedMaintenance = await _maintenanceUseCase.updateMaintenance(
        id,
        MaintenanceUpdateRequestDto(
          startedAt: startedAt,
          endedAt: endedAt,
          periodMonth: periodMonth,
          maintenanceType: maintenanceType,
        ),
      );
      
      final index = _maintenances.indexWhere((m) => m.id == id);
      if (index != -1) {
        _maintenances[index] = updatedMaintenance;
      }
      
      if (_selectedMaintenance != null && _selectedMaintenance!.id == id) {
        _selectedMaintenance = updatedMaintenance;
      }
      
      notifyListeners();
      return true;
    } catch (e) {
      _error = '유지보수 수정 실패: ${e.toString()}';
      return false;
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }
  
  // 유지보수 삭제 (백엔드 실제 구조)
  Future<bool> deleteMaintenance(int id) async {
    _isLoading = true;
    _error = null;
    notifyListeners();
    
    try {
      await _maintenanceUseCase.deleteMaintenance(id);
      
      _maintenances.removeWhere((m) => m.id == id);
      _totalCount--;
      
      if (_selectedMaintenance != null && _selectedMaintenance!.id == id) {
        _selectedMaintenance = null;
      }
      
      notifyListeners();
      return true;
    } catch (e) {
      _error = '유지보수 삭제 실패: ${e.toString()}';
      return false;
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }
  
  // 유지보수 상세 조회
  Future<MaintenanceDto?> getMaintenanceDetail(int id) async {
    try {
      return await _maintenanceUseCase.getMaintenance(id);
    } catch (e) {
      _error = '유지보수 상세 조회 실패: ${e.toString()}';
      return null;
    }
  }
  
  // 유지보수 선택
  void selectMaintenance(MaintenanceDto? maintenance) {
    _selectedMaintenance = maintenance;
    notifyListeners();
  }
  
  // 장비 이력별 유지보수 설정
  void setEquipmentHistoryFilter(int equipmentHistoryId) {
    _equipmentHistoryId = equipmentHistoryId;
    loadMaintenances(refresh: true);
  }
  
  // 필터 설정
  void setMaintenanceType(String? type) {
    if (_maintenanceType != type) {
      _maintenanceType = type;
      loadMaintenances(refresh: true);
    }
  }
  
  // 필터 초기화
  void clearFilters() {
    _maintenanceType = null;
    _equipmentHistoryId = null;
    loadMaintenances(refresh: true);
  }
  
  // 페이지 변경
  void goToPage(int page) {
    if (page >= 1 && page <= totalPages) {
      _currentPage = page;
      loadMaintenances();
    }
  }
  
  void nextPage() {
    if (_currentPage < totalPages) {
      _currentPage++;
      loadMaintenances();
    }
  }
  
  void previousPage() {
    if (_currentPage > 1) {
      _currentPage--;
      loadMaintenances();
    }
  }
  
  // 오류 초기화
  void clearError() {
    _error = null;
    notifyListeners();
  }
  
  // 유지보수 상태 표시명 (UI 호환성)
  String getMaintenanceStatusDisplayName(String status) {
    switch (status.toLowerCase()) {
      case '예정':
      case 'scheduled':
        return '예정';
      case '진행중':
      case 'in_progress':
        return '진행중';
      case '완료':
      case 'completed':
        return '완료';
      case '취소':
      case 'cancelled':
        return '취소';
      default:
        return status;
    }
  }
  
  // 유지보수 상태 간단 판단 (백엔드 데이터 기반)
  String getMaintenanceStatus(MaintenanceDto maintenance) {
    final now = DateTime.now();
    
    if (maintenance.isDeleted ?? false) return '취소';
    if (maintenance.startedAt.isAfter(now)) return '예정';
    if (maintenance.endedAt != null && maintenance.endedAt!.isBefore(now)) return '완료';
    
    return '진행중';
  }
  
  // ================== 누락된 메서드들 추가 ==================
  
  // 추가된 필드들
  List<MaintenanceDto> _upcomingAlerts = [];
  List<MaintenanceDto> _overdueAlerts = [];
  Map<String, dynamic> _statistics = {};
  String _searchQuery = '';
  String _currentSortField = '';
  bool _isAscending = true;
  
  // 추가 Getters
  List<MaintenanceDto> get upcomingAlerts => _upcomingAlerts;
  List<MaintenanceDto> get overdueAlerts => _overdueAlerts;
  Map<String, dynamic> get statistics => _statistics;
  int get upcomingCount => _upcomingAlerts.length;
  int get overdueCount => _overdueAlerts.length;
  
  // ID로 유지보수 조회 (호환성)
  Future<MaintenanceDto?> getMaintenanceById(int id) async {
    return await getMaintenanceDetail(id);
  }
  
  // 알람 로드 (백엔드 스키마 기반)
  Future<void> loadAlerts() async {
    _isLoading = true;
    notifyListeners();
    
    try {
      final now = DateTime.now();
      
      // 예정된 유지보수 (시작일이 미래인 것)
      _upcomingAlerts = _maintenances.where((maintenance) {
        return maintenance.startedAt.isAfter(now) && 
               !(maintenance.isDeleted ?? false);
      }).take(10).toList();
      
      // 연체된 유지보수 (종료일이 과거이고 아직 완료되지 않은 것)
      _overdueAlerts = _maintenances.where((maintenance) {
        return maintenance.endedAt.isBefore(now) && 
               maintenance.startedAt.isBefore(now) &&
               !(maintenance.isDeleted ?? false);
      }).take(10).toList();
      
      notifyListeners();
    } catch (e) {
      _error = '알람 로드 실패: ${e.toString()}';
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }
  
  // 통계 로드 (백엔드 데이터 기반)
  Future<void> loadStatistics() async {
    _isLoading = true;
    notifyListeners();
    
    try {
      final now = DateTime.now();
      
      final scheduled = _maintenances.where((m) => 
        m.startedAt.isAfter(now) && !(m.isDeleted ?? false)).length;
      final inProgress = _maintenances.where((m) => 
        m.startedAt.isBefore(now) && m.endedAt.isAfter(now) && !(m.isDeleted ?? false)).length;
      final completed = _maintenances.where((m) => 
        m.endedAt.isBefore(now) && !(m.isDeleted ?? false)).length;
      final cancelled = _maintenances.where((m) => 
        m.isDeleted ?? false).length;
      
      _statistics = {
        'total': _maintenances.length,
        'scheduled': scheduled,
        'inProgress': inProgress,
        'completed': completed,
        'cancelled': cancelled,
        'upcoming': upcomingCount,
        'overdue': overdueCount,
      };
      
      notifyListeners();
    } catch (e) {
      _error = '통계 로드 실패: ${e.toString()}';
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }
  
  // 검색 쿼리 설정
  void setSearchQuery(String query) {
    if (_searchQuery != query) {
      _searchQuery = query;
      // TODO: 실제 검색 구현 시 백엔드 API 호출 필요
      loadMaintenances(refresh: true);
    }
  }
  
  // 유지보수 필터 설정 (호환성)
  void setMaintenanceFilter(String? type) {
    setMaintenanceType(type);
  }
  
  // 정렬 설정
  void setSorting(String field, bool ascending) {
    if (_currentSortField != field || _isAscending != ascending) {
      _currentSortField = field;
      _isAscending = ascending;
      
      // 클라이언트 사이드 정렬 (백엔드 정렬 API가 없는 경우)
      _maintenances.sort((a, b) {
        dynamic valueA, valueB;
        
        switch (field) {
          case 'startedAt':
            valueA = a.startedAt;
            valueB = b.startedAt;
            break;
          case 'endedAt':
            valueA = a.endedAt;
            valueB = b.endedAt;
            break;
          case 'maintenanceType':
            valueA = a.maintenanceType;
            valueB = b.maintenanceType;
            break;
          case 'periodMonth':
            valueA = a.periodMonth;
            valueB = b.periodMonth;
            break;
          default:
            valueA = a.id;
            valueB = b.id;
        }
        
        if (valueA == null && valueB == null) return 0;
        if (valueA == null) return ascending ? -1 : 1;
        if (valueB == null) return ascending ? 1 : -1;
        
        final comparison = valueA.compareTo(valueB);
        return ascending ? comparison : -comparison;
      });
      
      notifyListeners();
    }
  }
  
  // 유지보수 일정 조회 (백엔드 스키마 기반)
  List<MaintenanceDto> getScheduleForMaintenance(DateTime date) {
    return _maintenances.where((maintenance) {
      final startDate = DateTime(
        maintenance.startedAt.year,
        maintenance.startedAt.month,
        maintenance.startedAt.day,
      );
      final endDate = DateTime(
        maintenance.endedAt.year,
        maintenance.endedAt.month,  
        maintenance.endedAt.day,
      );
      final targetDate = DateTime(date.year, date.month, date.day);
      
      return (targetDate.isAfter(startDate) || targetDate.isAtSameMomentAs(startDate)) &&
             (targetDate.isBefore(endDate) || targetDate.isAtSameMomentAs(endDate)) &&
             !(maintenance.isDeleted ?? false);
    }).toList();
  }
  
  // 초기화 (백엔드 실제 구조)
  void reset() {
    _maintenances.clear();
    _selectedMaintenance = null;
    _currentPage = 1;
    _totalCount = 0;
    _maintenanceType = null;
    _equipmentHistoryId = null;
    _error = null;
    _isLoading = false;
    _upcomingAlerts.clear();
    _overdueAlerts.clear();
    _statistics.clear();
    _searchQuery = '';
    _currentSortField = '';
    _isAscending = true;
    notifyListeners();
  }
  
  @override
  void dispose() {
    reset();
    super.dispose();
  }
}