import 'package:flutter/material.dart';
import 'package:superport/screens/common/theme_shadcn.dart';
import 'package:superport/data/models/maintenance_dto.dart';
import 'package:superport/data/models/equipment_history_dto.dart';
import 'package:superport/data/repositories/equipment_history_repository.dart';
import 'package:superport/domain/usecases/maintenance_usecase.dart';

/// 정비 우선순위
enum MaintenancePriority { low, medium, high }

/// 정비 스케줄 상태
enum MaintenanceScheduleStatus { 
  scheduled, 
  inProgress, 
  completed, 
  overdue, 
  cancelled 
}

/// 정비 스케줄 모델 (UI 전용)
class MaintenanceSchedule {
  final String id;
  final String title;
  final DateTime date;
  final MaintenancePriority priority;
  final MaintenanceScheduleStatus status;
  final String description;

  MaintenanceSchedule({
    required this.id,
    required this.title,
    required this.date,
    required this.priority,
    required this.status,
    required this.description,
  });
}

/// 유지보수 컨트롤러 (백엔드 API 완전 호환)
class MaintenanceController extends ChangeNotifier {
  final MaintenanceUseCase _maintenanceUseCase;
  final EquipmentHistoryRepository _equipmentHistoryRepository;
  
  // 상태 관리
  List<MaintenanceDto> _maintenances = [];
  bool _isLoading = false;
  String? _error;
  
  // EquipmentHistory 캐시 (성능 최적화)
  final Map<int, EquipmentHistoryDto> _equipmentHistoryCache = {};
  
  // 페이지네이션
  int _currentPage = 1;
  int _totalCount = 0;
  int _totalPages = 0;
  static const int _perPage = 20;
  
  // 필터 (백엔드 API와 일치)
  int? _equipmentId;
  String? _maintenanceType;
  bool? _isExpired;
  int? _expiringDays;
  bool _includeDeleted = false;
  
  // 검색 및 정렬
  String _searchQuery = '';
  String _sortField = 'startedAt';
  bool _sortAscending = false;
  
  // 선택된 유지보수
  MaintenanceDto? _selectedMaintenance;
  
  // 만료 예정 유지보수
  List<MaintenanceDto> _expiringMaintenances = [];
  
  // Form 상태
  bool _isFormLoading = false;
  
  MaintenanceController({
    required MaintenanceUseCase maintenanceUseCase,
    required EquipmentHistoryRepository equipmentHistoryRepository,
  }) : _maintenanceUseCase = maintenanceUseCase,
       _equipmentHistoryRepository = equipmentHistoryRepository;

  // Getters
  List<MaintenanceDto> get maintenances => _maintenances;
  bool get isLoading => _isLoading;
  bool get isFormLoading => _isFormLoading;
  String? get error => _error;
  int get currentPage => _currentPage;
  int get totalPages => _totalPages;
  int get totalCount => _totalCount;
  MaintenanceDto? get selectedMaintenance => _selectedMaintenance;
  List<MaintenanceDto> get expiringMaintenances => _expiringMaintenances;
  
  // Filter getters
  int? get equipmentId => _equipmentId;
  String? get maintenanceType => _maintenanceType;
  bool? get isExpired => _isExpired;
  int? get expiringDays => _expiringDays;
  bool get includeDeleted => _includeDeleted;
  String get searchQuery => _searchQuery;
  String get sortField => _sortField;
  bool get sortAscending => _sortAscending;

  /// 유지보수 목록 로드
  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,
        perPage: _perPage,
        equipmentId: _equipmentId,
        maintenanceType: _maintenanceType,
        isExpired: _isExpired,
        expiringDays: _expiringDays,
        includeDeleted: _includeDeleted,
      );
      
      if (refresh) {
        _maintenances = response.items;
      } else {
        _maintenances.addAll(response.items);
      }
      
      _totalCount = response.totalCount;
      _totalPages = response.totalPages;
      
      // TODO: V/R 시스템에서는 maintenance API에서 직접 company_name 제공
      // 기존 equipment-history 개별 호출 비활성화
      // if (_maintenances.isNotEmpty) {
      //   preloadEquipmentData();
      // }
      
    } catch (e) {
      _error = e.toString();
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  /// 유지보수 상세 조회
  Future<MaintenanceDto?> getMaintenanceDetail(int id) async {
    try {
      _isLoading = true;
      notifyListeners();
      
      final maintenance = await _maintenanceUseCase.getMaintenanceDetail(id);
      _selectedMaintenance = maintenance;
      
      return maintenance;
    } catch (e) {
      _error = '유지보수 상세 조회 실패: ${e.toString()}';
      return null;
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  /// 유지보수 생성
  Future<bool> createMaintenance({
    int? equipmentHistoryId,
    required DateTime startedAt,
    required DateTime endedAt,
    required int periodMonth,
    required String maintenanceType,
  }) async {
    _isFormLoading = true;
    _error = null;
    notifyListeners();
    
    try {
      final request = MaintenanceRequestDto(
        equipmentHistoryId: equipmentHistoryId,
        startedAt: startedAt,
        endedAt: endedAt,
        periodMonth: periodMonth,
        maintenanceType: maintenanceType,
      );
      
      final newMaintenance = await _maintenanceUseCase.createMaintenance(request);
      
      // 리스트 업데이트
      _maintenances.insert(0, newMaintenance);
      _totalCount++;
      
      return true;
    } catch (e) {
      _error = '유지보수 생성 실패: ${e.toString()}';
      return false;
    } finally {
      _isFormLoading = false;
      notifyListeners();
    }
  }

  /// 유지보수 수정
  Future<bool> updateMaintenance({
    required int id,
    DateTime? startedAt,
    DateTime? endedAt,
    int? periodMonth,
    String? maintenanceType,
  }) async {
    _isFormLoading = true;
    _error = null;
    notifyListeners();
    
    try {
      final request = MaintenanceUpdateRequestDto(
        startedAt: startedAt,
        endedAt: endedAt,
        periodMonth: periodMonth,
        maintenanceType: maintenanceType,
      );
      
      final updatedMaintenance = await _maintenanceUseCase.updateMaintenance(id, request);
      
      // 리스트 업데이트
      final index = _maintenances.indexWhere((m) => m.id == id);
      if (index != -1) {
        _maintenances[index] = updatedMaintenance;
      }
      
      // 선택된 항목 업데이트
      if (_selectedMaintenance != null && _selectedMaintenance!.id == id) {
        _selectedMaintenance = updatedMaintenance;
      }
      
      return true;
    } catch (e) {
      _error = '유지보수 수정 실패: ${e.toString()}';
      return false;
    } finally {
      _isFormLoading = false;
      notifyListeners();
    }
  }

  /// 유지보수 삭제 (Soft Delete)
  Future<bool> deleteMaintenance(int id) async {
    _isFormLoading = true;
    _error = null;
    notifyListeners();
    
    try {
      await _maintenanceUseCase.deleteMaintenance(id);
      
      // 리스트에서 제거
      _maintenances.removeWhere((m) => m.id == id);
      _totalCount--;
      
      // 선택된 항목 해제
      if (_selectedMaintenance != null && _selectedMaintenance!.id == id) {
        _selectedMaintenance = null;
      }
      
      return true;
    } catch (e) {
      _error = '유지보수 삭제 실패: ${e.toString()}';
      return false;
    } finally {
      _isFormLoading = false;
      notifyListeners();
    }
  }

  /// 만료 예정 유지보수 조회
  Future<void> loadExpiringMaintenances({int days = 30}) async {
    try {
      _expiringMaintenances = await _maintenanceUseCase.getExpiringMaintenances(days: days);
      notifyListeners();
    } catch (e) {
      _error = '만료 예정 유지보수 조회 실패: ${e.toString()}';
      notifyListeners();
    }
  }

  /// 특정 장비의 유지보수 조회
  Future<void> loadMaintenancesByEquipment(int equipmentId) async {
    _equipmentId = equipmentId;
    await loadMaintenances(refresh: true);
  }

  /// 활성 유지보수만 조회
  Future<void> loadActiveMaintenances() async {
    _includeDeleted = false;
    await loadMaintenances(refresh: true);
  }

  /// 만료된 유지보수 조회
  Future<void> loadExpiredMaintenances() async {
    _isExpired = true;
    await loadMaintenances(refresh: true);
  }

  // 필터 설정 메서드들
  void setEquipmentFilter(int? equipmentId) {
    if (_equipmentId != equipmentId) {
      _equipmentId = equipmentId;
      loadMaintenances(refresh: true);
    }
  }

  void setMaintenanceTypeFilter(String? maintenanceType) {
    if (_maintenanceType != maintenanceType) {
      _maintenanceType = maintenanceType;
      loadMaintenances(refresh: true);
    }
  }

  void setExpiredFilter(bool? isExpired) {
    if (_isExpired != isExpired) {
      _isExpired = isExpired;
      loadMaintenances(refresh: true);
    }
  }

  void setExpiringDaysFilter(int? days) {
    if (_expiringDays != days) {
      _expiringDays = days;
      loadMaintenances(refresh: true);
    }
  }

  void setIncludeDeleted(bool includeDeleted) {
    if (_includeDeleted != includeDeleted) {
      _includeDeleted = includeDeleted;
      loadMaintenances(refresh: true);
    }
  }

  /// 모든 필터 초기화
  void clearFilters() {
    _equipmentId = null;
    _maintenanceType = null;
    _isExpired = null;
    _expiringDays = null;
    _includeDeleted = false;
    _searchQuery = '';
    loadMaintenances(refresh: true);
  }
  
  /// 검색어 설정
  void setSearchQuery(String query) {
    if (_searchQuery != query) {
      _searchQuery = query;
      // 검색어가 변경되면 0.5초 후에 검색 실행 (디바운스)
      Future.delayed(const Duration(milliseconds: 500), () {
        if (_searchQuery == query) {
          _filterMaintenancesBySearch();
        }
      });
    }
  }
  
  /// 상태 필터 설정
  void setMaintenanceFilter(String? status) {
    switch (status) {
      case 'active':
        _isExpired = false;
        break;
      case 'completed':
      case 'expired':
        _isExpired = true;
        break;
      case 'upcoming':
        _isExpired = false;
        break;
      default:
        _isExpired = null;
        break;
    }
    loadMaintenances(refresh: true);
  }
  
  /// 정렬 설정
  void setSorting(String field, bool ascending) {
    if (_sortField != field || _sortAscending != ascending) {
      _sortField = field;
      _sortAscending = ascending;
      _sortMaintenances();
      notifyListeners();
    }
  }
  
  /// 검색어로 유지보수 필터링 (로컬 필터링)
  void _filterMaintenancesBySearch() {
    if (_searchQuery.trim().isEmpty) {
      notifyListeners();
      return;
    }
    
    // 검색어가 있으면 로컬에서 필터링
    final query = _searchQuery.toLowerCase();
    // 여기서는 간단히 notifyListeners만 호출 (실제 필터링은 UI에서 수행)
    notifyListeners();
  }
  
  /// 유지보수 목록 정렬
  void _sortMaintenances() {
    _maintenances.sort((a, b) {
      int comparison = 0;
      
      switch (_sortField) {
        case 'startedAt':
          comparison = a.startedAt.compareTo(b.startedAt);
          break;
        case 'endedAt':
          comparison = a.endedAt.compareTo(b.endedAt);
          break;
        case 'maintenanceType':
          comparison = a.maintenanceType.compareTo(b.maintenanceType);
          break;
        case 'periodMonth':
          comparison = a.periodMonth.compareTo(b.periodMonth);
          break;
        default:
          comparison = a.startedAt.compareTo(b.startedAt);
      }
      
      return _sortAscending ? comparison : -comparison;
    });
  }
  
  /// 특정 날짜의 유지보수 스케줄 생성
  MaintenanceSchedule? getScheduleForMaintenance(DateTime date) {
    if (_maintenances.isEmpty) return null;
    
    MaintenanceDto? maintenance;
    try {
      maintenance = _maintenances.firstWhere(
        (m) => m.startedAt.year == date.year &&
               m.startedAt.month == date.month &&
               m.startedAt.day == date.day,
      );
    } catch (e) {
      // 해당 날짜의 정비가 없으면 가장 가까운 정비를 찾거나 null 반환
      maintenance = _maintenances.isNotEmpty ? _maintenances.first : null;
    }
    
    if (maintenance == null) return null;
    
    return MaintenanceSchedule(
      id: maintenance.id.toString(),
      title: _getMaintenanceTitle(maintenance),
      date: maintenance.startedAt,
      priority: _getMaintenancePriority(maintenance),
      status: _getMaintenanceScheduleStatus(maintenance),
      description: _getMaintenanceDescription(maintenance),
    );
  }
  
  String _getMaintenanceTitle(MaintenanceDto maintenance) {
    final typeDisplay = _getMaintenanceTypeDisplayName(maintenance.maintenanceType);
    return '$typeDisplay 정비';
  }
  
  String _getMaintenanceTypeDisplayName(String maintenanceType) {
    switch (maintenanceType) {
      case 'V':
        return '방문';
      case 'R':
        return '원격';
      default:
        return maintenanceType;
    }
  }
  
  MaintenancePriority _getMaintenancePriority(MaintenanceDto maintenance) {
    if (maintenance.isExpired) return MaintenancePriority.high;
    
    final now = DateTime.now();
    final daysUntilStart = maintenance.startedAt.difference(now).inDays;
    
    if (daysUntilStart <= 7) return MaintenancePriority.high;
    if (daysUntilStart <= 30) return MaintenancePriority.medium;
    return MaintenancePriority.low;
  }
  
  MaintenanceScheduleStatus _getMaintenanceScheduleStatus(MaintenanceDto maintenance) {
    if (maintenance.isDeleted) return MaintenanceScheduleStatus.cancelled;
    if (maintenance.isExpired) return MaintenanceScheduleStatus.overdue;
    
    final now = DateTime.now();
    if (maintenance.startedAt.isAfter(now)) return MaintenanceScheduleStatus.scheduled;
    if (maintenance.endedAt.isBefore(now)) return MaintenanceScheduleStatus.completed;
    return MaintenanceScheduleStatus.inProgress;
  }
  
  String _getMaintenanceDescription(MaintenanceDto maintenance) {
    final status = getMaintenanceStatusText(maintenance);
    return '상태: $status\n주기: ${maintenance.periodMonth}개월';
  }

  // 페이지네이션 메서드들
  void goToPage(int page) {
    if (page >= 1 && page <= _totalPages && page != _currentPage) {
      _currentPage = page;
      loadMaintenances();
    }
  }

  void nextPage() {
    if (_currentPage < _totalPages) {
      _currentPage++;
      loadMaintenances();
    }
  }

  void previousPage() {
    if (_currentPage > 1) {
      _currentPage--;
      loadMaintenances();
    }
  }

  void goToFirstPage() {
    if (_currentPage != 1) {
      _currentPage = 1;
      loadMaintenances();
    }
  }

  void goToLastPage() {
    if (_currentPage != _totalPages && _totalPages > 0) {
      _currentPage = _totalPages;
      loadMaintenances();
    }
  }

  // 선택 관리
  void selectMaintenance(MaintenanceDto? maintenance) {
    _selectedMaintenance = maintenance;
    notifyListeners();
  }

  // 유틸리티 메서드들
  String getMaintenanceStatusText(MaintenanceDto maintenance) {
    if (maintenance.isDeleted) return '삭제됨';
    if (maintenance.isExpired) return '만료됨';
    
    final now = DateTime.now();
    if (maintenance.startedAt.isAfter(now)) return '예정';
    if (maintenance.endedAt.isBefore(now)) return '완료';
    return '진행중';
  }

  Color getMaintenanceStatusColor(MaintenanceDto maintenance) {
    final status = getMaintenanceStatusText(maintenance);
    switch (status) {
      case '예정': return Colors.blue;
      case '진행중': return Colors.green;
      case '완료': return Colors.grey;
      case '만료됨': return Colors.red;
      case '삭제됨': return Colors.grey.withValues(alpha: 0.5);
      default: return ShadcnTheme.foreground;
    }
  }

  // Alert 시스템 (기존 화면 호환성)
  List<MaintenanceDto> get upcomingAlerts => _expiringMaintenances;
  List<MaintenanceDto> get overdueAlerts => _maintenances
      .where((m) => m.isExpired && m.isActive)
      .toList();
  
  int get upcomingCount => upcomingAlerts.length;
  int get overdueCount => overdueAlerts.length;

  /// Alert 데이터 로드 (기존 화면 호환성)
  Future<void> loadAlerts() async {
    await loadExpiringMaintenances();
    notifyListeners();
  }

  // 통계 정보
  int get activeMaintenanceCount => _maintenances.where((m) => m.isActive).length;
  int get expiredMaintenanceCount => _maintenances.where((m) => m.isExpired).length;
  int get visitMaintenanceCount => _maintenances.where((m) => m.maintenanceType == 'V').length;
  int get remoteMaintenanceCount => _maintenances.where((m) => m.maintenanceType == 'R').length;

  // Equipment 정보 조회 (캐시 지원)
  Future<EquipmentHistoryDto?> getEquipmentHistoryForMaintenance(MaintenanceDto maintenance) async {
    if (maintenance.equipmentHistoryId == null) return null;
    
    final equipmentHistoryId = maintenance.equipmentHistoryId!;
    
    // 캐시에서 먼저 확인
    if (_equipmentHistoryCache.containsKey(equipmentHistoryId)) {
      return _equipmentHistoryCache[equipmentHistoryId];
    }
    
    try {
      // API에서 조회
      final equipmentHistory = await _equipmentHistoryRepository.getEquipmentHistoryById(equipmentHistoryId);
      
      // 캐시에 저장
      _equipmentHistoryCache[equipmentHistoryId] = equipmentHistory;
      
      return equipmentHistory;
    } catch (e) {
      debugPrint('Equipment History 조회 실패: $e');
      return null;
    }
  }
  
  // 장비명 조회 (UI용 헬퍼)
  String getEquipmentName(MaintenanceDto maintenance) {
    // 백엔드에서 직접 제공하는 equipment_model 사용
    if (maintenance.equipmentModel != null && maintenance.equipmentModel!.isNotEmpty) {
      return maintenance.equipmentModel!;
    }
    return 'Equipment #${maintenance.equipmentHistoryId ?? 'N/A'}';
  }
  
  // 시리얼번호 조회 (UI용 헬퍼)  
  String getEquipmentSerial(MaintenanceDto maintenance) {
    // 백엔드에서 직접 제공하는 equipment_serial 사용
    if (maintenance.equipmentSerial != null && maintenance.equipmentSerial!.isNotEmpty) {
      return maintenance.equipmentSerial!;
    }
    return '-';
  }
  
  // 고객사명 조회 (UI용 헬퍼)
  String getCompanyName(MaintenanceDto maintenance) {
    // 백엔드에서 직접 제공하는 company_name 사용
    debugPrint('getCompanyName - ID: ${maintenance.id}, companyName: "${maintenance.companyName}", companyId: ${maintenance.companyId}');
    
    final name = maintenance.companyName;
    if (name != null) {
      final trimmed = name.trim();
      // 백엔드가 문자열 'null'을 반환하는 케이스 방지
      if (trimmed.isNotEmpty && trimmed.toLowerCase() != 'null') {
        return trimmed;
      }
    }
    return '-';
  }
  
  // 특정 maintenance의 equipment 정보가 로드되었는지 확인
  bool isEquipmentDataLoaded(MaintenanceDto maintenance) {
    return maintenance.equipmentHistoryId != null && 
           _equipmentHistoryCache.containsKey(maintenance.equipmentHistoryId!);
  }
  
  // 모든 maintenance의 equipment 정보 미리 로드
  Future<void> preloadEquipmentData() async {
    final maintenancesWithHistoryId = _maintenances
        .where((m) => m.equipmentHistoryId != null && !_equipmentHistoryCache.containsKey(m.equipmentHistoryId!))
        .toList();
    
    if (maintenancesWithHistoryId.isEmpty) return;
    
    // 동시에 최대 5개씩만 로드 (API 부하 방지)
    const batchSize = 5;
    for (int i = 0; i < maintenancesWithHistoryId.length; i += batchSize) {
      final batch = maintenancesWithHistoryId
          .skip(i)
          .take(batchSize)
          .toList();
      
      await Future.wait(
        batch.map((maintenance) => getEquipmentHistoryForMaintenance(maintenance)),
      );
      
      // UI 업데이트
      notifyListeners();
    }
  }

  // 오류 관리
  void clearError() {
    _error = null;
    notifyListeners();
  }

  // 초기화
  void reset() {
    _maintenances.clear();
    _expiringMaintenances.clear();
    _selectedMaintenance = null;
    _currentPage = 1;
    _totalCount = 0;
    _totalPages = 0;
    _equipmentId = null;
    _maintenanceType = null;
    _isExpired = null;
    _expiringDays = null;
    _includeDeleted = false;
    _searchQuery = '';
    _sortField = 'startedAt';
    _sortAscending = false;
    _error = null;
    _isLoading = false;
    _isFormLoading = false;
    _equipmentHistoryCache.clear();  // 캐시도 초기화
    notifyListeners();
  }

  @override
  void dispose() {
    reset();
    super.dispose();
  }
}
