import 'package:flutter/foundation.dart';
import 'package:get_it/get_it.dart';
import 'package:superport/models/equipment_unified_model.dart';
import 'package:superport/services/equipment_service.dart';
import 'package:superport/services/mock_data_service.dart';
import 'package:superport/utils/constants.dart';
import 'package:superport/core/errors/failures.dart';
import 'package:superport/models/equipment_unified_model.dart' as legacy;
import 'package:superport/core/utils/debug_logger.dart';

// companyTypeToString 함수 import
import 'package:superport/utils/constants.dart'
    show companyTypeToString, CompanyType;
import 'package:superport/models/company_model.dart';
import 'package:superport/models/address_model.dart';
import 'package:superport/core/utils/equipment_status_converter.dart';

// 장비 목록 화면의 상태 및 비즈니스 로직을 담당하는 컨트롤러
class EquipmentListController extends ChangeNotifier {
  final MockDataService dataService;
  final EquipmentService _equipmentService = GetIt.instance<EquipmentService>();
  
  List<UnifiedEquipment> equipments = [];
  String? selectedStatusFilter;
  String searchKeyword = '';  // 검색어 추가
  final Set<String> selectedEquipmentIds = {}; // 'id:status' 형식
  
  bool _isLoading = false;
  String? _error;
  bool _useApi = true; // Feature flag for API usage
  
  // 페이지네이션
  int _currentPage = 1;
  final int _perPage = 20;
  bool _hasMore = true;
  
  // Getters
  bool get isLoading => _isLoading;
  String? get error => _error;
  bool get hasMore => _hasMore;
  int get currentPage => _currentPage;

  EquipmentListController({required this.dataService});

  // 데이터 로드 및 상태 필터 적용
  Future<void> loadData({bool isRefresh = false, String? search}) async {
    if (isRefresh) {
      _currentPage = 1;
      _hasMore = true;
      equipments.clear();
    }
    
    if (_isLoading || (!_hasMore && !isRefresh)) return;
    
    _isLoading = true;
    _error = null;
    notifyListeners();
    
    try {
      if (_useApi) {
        // API 호출
        DebugLogger.log('장비 목록 API 호출 시작', tag: 'EQUIPMENT', data: {
          'page': _currentPage,
          'perPage': _perPage,
          'statusFilter': selectedStatusFilter,
        });
        
        // DTO 형태로 가져와서 status 정보 유지
        final apiEquipmentDtos = await _equipmentService.getEquipmentsWithStatus(
          page: _currentPage,
          perPage: _perPage,
          status: selectedStatusFilter != null ? EquipmentStatusConverter.clientToServer(selectedStatusFilter) : null,
          search: search ?? searchKeyword,
        );
        
        DebugLogger.log('장비 목록 API 응답', tag: 'EQUIPMENT', data: {
          'count': apiEquipmentDtos.length,
          'firstItem': apiEquipmentDtos.isNotEmpty ? {
            'id': apiEquipmentDtos.first.id,
            'equipmentNumber': apiEquipmentDtos.first.equipmentNumber,
            'manufacturer': apiEquipmentDtos.first.manufacturer,
            'status': apiEquipmentDtos.first.status,
          } : null,
        });
        
        // DTO를 UnifiedEquipment로 변환 (status 정보 포함)
        final List<UnifiedEquipment> unifiedEquipments = apiEquipmentDtos.map((dto) {
          final equipment = Equipment(
            id: dto.id,
            manufacturer: dto.manufacturer,
            name: dto.modelName ?? dto.equipmentNumber,
            category: '', // 세부 정보는 상세 조회에서 가져와야 함
            subCategory: '',
            subSubCategory: '',
            serialNumber: dto.serialNumber,
            quantity: 1,
            inDate: dto.createdAt,
          );
          
          return UnifiedEquipment(
            id: dto.id,
            equipment: equipment,
            date: dto.createdAt,
            status: EquipmentStatusConverter.serverToClient(dto.status), // 서버 status를 클라이언트 status로 변환
          );
        }).toList();
        
        if (isRefresh) {
          equipments = unifiedEquipments;
        } else {
          equipments.addAll(unifiedEquipments);
        }
        
        _hasMore = unifiedEquipments.length == _perPage;
        if (_hasMore) _currentPage++;
      } else {
        // Mock 데이터 사용
        equipments = dataService.getAllEquipments();
        if (selectedStatusFilter != null) {
          equipments =
              equipments.where((e) => e.status == selectedStatusFilter).toList();
        }
        _hasMore = false;
      }
      
      selectedEquipmentIds.clear();
    } on Failure catch (e) {
      _error = e.message;
    } catch (e) {
      _error = 'An unexpected error occurred: $e';
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  // 상태 필터 변경
  Future<void> changeStatusFilter(String? status) async {
    selectedStatusFilter = status;
    await loadData(isRefresh: true);
  }
  
  // 검색어 변경
  Future<void> updateSearchKeyword(String keyword) async {
    searchKeyword = keyword;
    await loadData(isRefresh: true, search: keyword);
  }

  // 장비 선택/해제 (모든 상태 지원)
  void selectEquipment(int? id, String status, bool? isSelected) {
    if (id == null || isSelected == null) return;
    final key = '$id:$status';
    if (isSelected) {
      selectedEquipmentIds.add(key);
    } else {
      selectedEquipmentIds.remove(key);
    }
    notifyListeners();
  }

  // 선택된 입고 장비 수 반환
  int getSelectedInStockCount() {
    int count = 0;
    for (final idStatusPair in selectedEquipmentIds) {
      final parts = idStatusPair.split(':');
      if (parts.length == 2 && parts[1] == EquipmentStatus.in_) {
        count++;
      }
    }
    return count;
  }

  // 선택된 전체 장비 수 반환
  int getSelectedEquipmentCount() {
    return selectedEquipmentIds.length;
  }

  // 선택된 특정 상태의 장비 수 반환
  int getSelectedEquipmentCountByStatus(String status) {
    int count = 0;
    for (final idStatusPair in selectedEquipmentIds) {
      final parts = idStatusPair.split(':');
      if (parts.length == 2 && parts[1] == status) {
        count++;
      }
    }
    return count;
  }

  // 선택된 장비들의 UnifiedEquipment 객체 목록 반환
  List<UnifiedEquipment> getSelectedEquipments() {
    List<UnifiedEquipment> selected = [];
    for (final idStatusPair in selectedEquipmentIds) {
      final parts = idStatusPair.split(':');
      if (parts.length == 2) {
        final id = int.tryParse(parts[0]);
        if (id != null) {
          final equipment = equipments.firstWhere(
            (e) => e.id == id && e.status == parts[1],
            orElse: () => null as UnifiedEquipment,
          );
          if (equipment != null) {
            selected.add(equipment);
          }
        }
      }
    }
    return selected;
  }

  // 선택된 특정 상태의 장비들의 UnifiedEquipment 객체 목록 반환
  List<UnifiedEquipment> getSelectedEquipmentsByStatus(String status) {
    List<UnifiedEquipment> selected = [];
    for (final idStatusPair in selectedEquipmentIds) {
      final parts = idStatusPair.split(':');
      if (parts.length == 2 && parts[1] == status) {
        final id = int.tryParse(parts[0]);
        if (id != null) {
          final equipment = equipments.firstWhere(
            (e) => e.id == id && e.status == status,
            orElse: () => null as UnifiedEquipment,
          );
          if (equipment != null) {
            selected.add(equipment);
          }
        }
      }
    }
    return selected;
  }

  // 선택된 장비들의 요약 정보를 Map 형태로 반환 (출고/대여/폐기 폼에서 사용)
  List<Map<String, dynamic>> getSelectedEquipmentsSummary() {
    List<Map<String, dynamic>> summaryList = [];
    List<UnifiedEquipment> selectedEquipmentsInStock =
        getSelectedEquipmentsByStatus(EquipmentStatus.in_);

    for (final equipment in selectedEquipmentsInStock) {
      summaryList.add({
        'equipment': equipment.equipment,
        'equipmentInId': equipment.id,
        'status': equipment.status,
      });
    }

    return summaryList;
  }

  // 출고 정보(회사, 담당자, 라이센스 등) 반환
  String getOutEquipmentInfo(int equipmentId, String infoType) {
    final equipmentOut = dataService.getEquipmentOutById(equipmentId);
    if (equipmentOut != null) {
      switch (infoType) {
        case 'company':
          final company = equipmentOut.company ?? '-';
          if (company != '-') {
            final companyObj = dataService.getAllCompanies().firstWhere(
              (c) => c.name == company,
              orElse:
                  () => Company(
                    name: company,
                    address: Address(),
                    companyTypes: [CompanyType.customer], // 기본값 고객사
                  ),
            );
            // 여러 유형 중 첫 번째만 표시 (대표 유형)
            final typeText =
                companyObj.companyTypes.isNotEmpty
                    ? companyTypeToString(companyObj.companyTypes.first)
                    : '-';
            return '$company (${typeText})';
          }
          return company;
        case 'manager':
          return equipmentOut.manager ?? '-';
        case 'license':
          return equipmentOut.license ?? '-';
        default:
          return '-';
      }
    }
    return '-';
  }
  
  // 장비 삭제
  Future<bool> deleteEquipment(UnifiedEquipment equipment) async {
    try {
      if (_useApi) {
        // API를 통한 삭제
        if (equipment.equipment.id != null) {
          await _equipmentService.deleteEquipment(equipment.equipment.id!);
        } else {
          throw Exception('Equipment ID is null');
        }
      } else {
        // Mock 데이터 삭제
        if (equipment.status == EquipmentStatus.in_) {
          dataService.deleteEquipmentIn(equipment.id!);
        } else if (equipment.status == EquipmentStatus.out) {
          dataService.deleteEquipmentOut(equipment.id!);
        } else if (equipment.status == EquipmentStatus.rent) {
          // TODO: 대여 상태 삭제 구현
          throw UnimplementedError('Rent status deletion not implemented');
        }
      }
      
      // 로컬 리스트에서도 제거
      equipments.removeWhere((e) => e.id == equipment.id && e.status == equipment.status);
      notifyListeners();
      
      return true;
    } on Failure catch (e) {
      _error = e.message;
      notifyListeners();
      return false;
    } catch (e) {
      _error = 'Failed to delete equipment: $e';
      notifyListeners();
      return false;
    }
  }
  
  // API 사용 여부 토글 (테스트용)
  void toggleApiUsage() {
    _useApi = !_useApi;
    loadData(isRefresh: true);
  }
  
  // 에러 처리
  void clearError() {
    _error = null;
    notifyListeners();
  }
  
  @override
  void dispose() {
    super.dispose();
  }
}
