import 'package:flutter/material.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/core/utils/error_handler.dart';
import 'package:superport/core/controllers/base_list_controller.dart';
import 'package:superport/core/utils/equipment_status_converter.dart';
import 'package:superport/models/company_model.dart';
import 'package:superport/models/address_model.dart';
import 'package:superport/data/models/common/pagination_params.dart';
import 'package:superport/core/services/lookups_service.dart';
import 'package:superport/data/models/lookups/lookup_data.dart';
import 'package:superport/utils/constants.dart';

/// 장비 목록 화면의 상태 및 비즈니스 로직을 담당하는 컨트롤러 (리팩토링 버전)
/// BaseListController를 상속받아 공통 기능을 재사용
class EquipmentListController extends BaseListController<UnifiedEquipment> {
  late final EquipmentService _equipmentService;
  late final LookupsService _lookupsService;
  
  // 추가 상태 관리
  final Set<String> selectedEquipmentIds = {}; // 'id:status' 형식
  
  // 필터
  String? _statusFilter;
  String? _categoryFilter;
  int? _companyIdFilter;
  String? _selectedStatusFilter;
  bool _includeInactive = false; // 비활성(Disposed) 포함 여부
  
  // Getters
  List<UnifiedEquipment> get equipments => items;
  String? get statusFilter => _statusFilter;
  String? get categoryFilter => _categoryFilter;
  int? get companyIdFilter => _companyIdFilter;
  String? get selectedStatusFilter => _selectedStatusFilter;
  bool get includeInactive => _includeInactive;
  
  // Setters
  set selectedStatusFilter(String? value) {
    _selectedStatusFilter = value;
    notifyListeners();
  }

  // 비활성 포함 토글
  void toggleIncludeInactive() {
    _includeInactive = !_includeInactive;
    loadData(isRefresh: true);
  }

  EquipmentListController() {
    if (GetIt.instance.isRegistered<EquipmentService>()) {
      _equipmentService = GetIt.instance<EquipmentService>();
    } else {
      throw Exception('EquipmentService not registered in GetIt');
    }
    
    if (GetIt.instance.isRegistered<LookupsService>()) {
      _lookupsService = GetIt.instance<LookupsService>();
    } else {
      throw Exception('LookupsService not registered in GetIt');
    }
    
  }

  @override
  Future<PagedResult<UnifiedEquipment>> fetchData({
    required PaginationParams params,
    Map<String, dynamic>? additionalFilters,
  }) async {
    // API 호출 (페이지 크기를 명시적으로 10개로 고정)
    final apiEquipmentDtos = await ErrorHandler.handleApiCall(
      () => _equipmentService.getEquipmentsWithStatus(
        page: params.page,
        perPage: 10, // 🎯 장비 리스트는 항상 10개로 고정
        status: _statusFilter != null ? 
          EquipmentStatusConverter.clientToServer(_statusFilter) : null,
        search: params.search,
        companyId: _companyIdFilter,
        includeInactive: _includeInactive,
      ),
      onError: (failure) {
        throw failure;
      },
    );
    
    if (apiEquipmentDtos == null) {
      return PagedResult(
        items: [],
        meta: PaginationMeta(
          currentPage: params.page,
          perPage: params.perPage,
          total: 0,
          totalPages: 0,
          hasNext: false,
          hasPrevious: false,
        ),
      );
    }
    
    // DTO를 UnifiedEquipment로 변환
    print('DEBUG [EquipmentListController] Converting ${apiEquipmentDtos.items.length} DTOs to UnifiedEquipment');
    final items = apiEquipmentDtos.items.map((dto) {
      // 🔧 [DEBUG] JOIN된 데이터 로깅
      print('DEBUG [EquipmentListController] DTO ID: ${dto.id}, companyName: "${dto.companyName}", warehouseName: "${dto.warehouseName}"');
      final equipment = Equipment(
        id: dto.id,
        manufacturer: dto.manufacturer ?? 'Unknown',
        equipmentNumber: dto.equipmentNumber ?? 'Unknown', // name → equipmentNumber (required)
        modelName: dto.modelName ?? dto.equipmentNumber ?? 'Unknown', // 새로운 필수 필드 (required)
        category1: 'Equipment', // category → category1 (required)
        category2: 'General', // subCategory → category2 (required)
        category3: 'Standard', // subSubCategory → category3 (required)
        serialNumber: dto.serialNumber,
        quantity: 1, // 기본 수량
      );
      
      // 간단한 Company 정보 생성 (사용하지 않으므로 제거)
      // final company = dto.companyName != null ? ... : null;
      
      final unifiedEquipment = UnifiedEquipment(
        id: dto.id,
        equipment: equipment,
        date: dto.createdAt ?? DateTime.now(),
        status: EquipmentStatusConverter.serverToClient(dto.status),
        notes: null, // EquipmentListDto에 remark 필드 없음
        // 🔧 [BUG FIX] 누락된 위치 정보 필드들 추가
        // 문제: 장비 리스트에서 위치 정보(현재 위치, 창고 위치)가 표시되지 않음
        // 원인: UnifiedEquipment 생성 시 JOIN된 데이터(companyName, warehouseName) 누락
        // 해결: EquipmentListDto의 JOIN된 데이터를 UnifiedEquipment 필드로 매핑
        currentCompany: dto.companyName,      // API company_name → currentCompany
        warehouseLocation: dto.warehouseName,  // API warehouse_name → warehouseLocation
        // currentBranch는 EquipmentListDto에 없으므로 null (백엔드 API 구조 변경으로 지점 개념 제거)
        currentBranch: null,
      );
      // 🔧 [DEBUG] 변환된 UnifiedEquipment 로깅 (필요 시 활성화)
      // print('DEBUG [EquipmentListController] UnifiedEquipment ID: ${unifiedEquipment.id}, currentCompany: "${unifiedEquipment.currentCompany}", warehouseLocation: "${unifiedEquipment.warehouseLocation}"');
      return unifiedEquipment;
    }).toList();
    
    // API에서 반환한 실제 메타데이터 사용
    final meta = PaginationMeta(
      currentPage: apiEquipmentDtos.page,
      perPage: apiEquipmentDtos.size,
      total: apiEquipmentDtos.totalElements,
      totalPages: apiEquipmentDtos.totalPages,
      hasNext: !apiEquipmentDtos.last,
      hasPrevious: !apiEquipmentDtos.first,
    );
    
    return PagedResult(items: items, meta: meta);
  }

  @override
  bool filterItem(UnifiedEquipment item, String query) {
    final q = query.toLowerCase();
    return (item.equipment.name.toLowerCase().contains(q)) ||
           (item.equipment.serialNumber?.toLowerCase().contains(q) ?? false) ||
           (item.equipment.manufacturer.toLowerCase().contains(q)) ||
           (item.notes?.toLowerCase().contains(q) ?? false) ||
           (item.status.toLowerCase().contains(q));
  }

  /// 장비 선택/선택 해제
  void toggleSelection(UnifiedEquipment equipment) {
    final equipmentKey = '${equipment.equipment.id}:${equipment.status}';
    if (selectedEquipmentIds.contains(equipmentKey)) {
      selectedEquipmentIds.remove(equipmentKey);
    } else {
      selectedEquipmentIds.add(equipmentKey);
    }
    notifyListeners();
  }

  /// 모든 선택 해제
  void clearSelection() {
    selectedEquipmentIds.clear();
    notifyListeners();
  }

  /// 선택된 장비 정보 가져오기
  Map<String, List<UnifiedEquipment>> getSelectedEquipmentsByStatus() {
    final Map<String, List<UnifiedEquipment>> groupedEquipments = {};
    
    for (final equipment in items) {
      final equipmentKey = '${equipment.equipment.id}:${equipment.status}';
      if (selectedEquipmentIds.contains(equipmentKey)) {
        if (!groupedEquipments.containsKey(equipment.status)) {
          groupedEquipments[equipment.status] = [];
        }
        groupedEquipments[equipment.status]!.add(equipment);
      }
    }
    
    return groupedEquipments;
  }

  /// 필터 설정
  void setFilters({
    String? status,
    String? category,
    int? companyId,
  }) {
    _statusFilter = status;
    _categoryFilter = category;
    _companyIdFilter = companyId;
    loadData(isRefresh: true);
  }

  /// 상태 필터 변경
  void filterByStatus(String? status) {
    _statusFilter = status;
    loadData(isRefresh: true);
  }

  /// 카테고리 필터 변경
  void filterByCategory(String? category) {
    _categoryFilter = category;
    loadData(isRefresh: true);
  }

  /// 회사 필터 변경
  void filterByCompany(int? companyId) {
    _companyIdFilter = companyId;
    loadData(isRefresh: true);
  }

  /// 필터 초기화
  void clearFilters() {
    _statusFilter = null;
    _categoryFilter = null;
    _companyIdFilter = null;
    search('');
    loadData(isRefresh: true);
  }

  /// 장비 삭제
  Future<void> deleteEquipment(int id, String status) async {
    await ErrorHandler.handleApiCall<void>(
      () => _equipmentService.deleteEquipment(id),
      onError: (failure) {
        throw failure;
      },
    );
    
    // removeItemLocally((e) => e.equipment.id == id && e.status == status);  // 로컬 삭제 대신 서버에서 새로고침
    
    // 선택 목록에서도 제거
    final equipmentKey = '$id:$status';
    selectedEquipmentIds.remove(equipmentKey);
    
    // 삭제 후 리스트 새로고침 (서버에서 데이터 다시 가져오기)
    await refresh();
  }

  /// 선택된 장비 일괄 삭제
  Future<void> deleteSelectedEquipments() async {
    final selectedGroups = getSelectedEquipmentsByStatus();
    
    for (final entry in selectedGroups.entries) {
      for (final equipment in entry.value) {
        if (equipment.equipment.id != null) {
          await deleteEquipment(equipment.equipment.id!, equipment.status);
        }
      }
    }
    
    clearSelection();
  }

  /// 장비 상태 변경
  Future<void> updateEquipmentStatus(int id, String currentStatus, String newStatus, {String? reason}) async {
    try {
      await ErrorHandler.handleApiCall<void>(
        () => _equipmentService.changeEquipmentStatus(
          id, 
          EquipmentStatusConverter.clientToServer(newStatus), 
          reason,
        ),
        onError: (failure) {
          throw failure;
        },
      );
      
      // 성공 후 데이터 새로고침
      await refresh();
    } catch (e) {
      debugPrint('장비 상태 변경 실패: $e');
      rethrow;
    }
  }

  /// 선택된 장비들을 폐기 처리
  Future<void> disposeSelectedEquipments({String? reason}) async {
    final selectedEquipments = getSelectedEquipments()
        .where((equipment) => equipment.status != EquipmentStatus.disposed)
        .toList();
    
    if (selectedEquipments.isEmpty) {
      throw Exception('폐기할 수 있는 장비가 선택되지 않았습니다.');
    }

    List<String> failedEquipments = [];
    
    for (final equipment in selectedEquipments) {
      try {
        await updateEquipmentStatus(
          equipment.equipment.id!,
          equipment.status,
          EquipmentStatus.disposed,
          reason: reason ?? '폐기 처리',
        );
      } catch (e) {
        failedEquipments.add('${equipment.equipment.manufacturer} ${equipment.equipment.name}');
      }
    }
    
    clearSelection();
    
    if (failedEquipments.isNotEmpty) {
      throw Exception('일부 장비 폐기에 실패했습니다: ${failedEquipments.join(', ')}');
    }
  }

  /// 장비 정보 수정
  Future<void> updateEquipment(int id, UnifiedEquipment equipment) async {
    await ErrorHandler.handleApiCall<void>(
      () => _equipmentService.updateEquipment(id, equipment.equipment),
      onError: (failure) {
        throw failure;
      },
    );
    
    updateItemLocally(equipment, (e) => 
      e.equipment.id == equipment.equipment.id && 
      e.status == equipment.status
    );
  }

  /// 상태 필터 변경
  void changeStatusFilter(String? status) {
    _selectedStatusFilter = status;
    _statusFilter = status;
    notifyListeners();
  }

  /// 검색 키워드 업데이트
  void updateSearchKeyword(String keyword) {
    search(keyword); // BaseListController의 search 메서드 사용
  }

  /// 장비 선택 (토글 선택을 위한 별칭)
  void selectEquipment(UnifiedEquipment equipment) {
    toggleSelection(equipment);
  }

  /// 선택된 입고 상태 장비 개수
  int getSelectedInStockCount() {
    return selectedEquipmentIds
        .where((key) => key.endsWith(':입고'))
        .length;
  }

  /// 선택된 장비들 가져오기
  List<UnifiedEquipment> getSelectedEquipments() {
    return items.where((equipment) {
      final equipmentKey = '${equipment.equipment.id}:${equipment.status}';
      return selectedEquipmentIds.contains(equipmentKey);
    }).toList();
  }

  /// 선택된 장비들 요약 정보
  String getSelectedEquipmentsSummary() {
    final selectedEquipments = getSelectedEquipments();
    if (selectedEquipments.isEmpty) return '선택된 장비가 없습니다';
    
    final Map<String, int> statusCounts = {};
    for (final equipment in selectedEquipments) {
      statusCounts[equipment.status] = (statusCounts[equipment.status] ?? 0) + 1;
    }
    
    final summaryParts = statusCounts.entries
        .map((entry) => '${entry.key}: ${entry.value}개')
        .toList();
    
    return summaryParts.join(', ');
  }

  /// 선택된 장비 총 개수
  int getSelectedEquipmentCount() {
    return selectedEquipmentIds.length;
  }

  /// 특정 상태의 선택된 장비 개수
  int getSelectedEquipmentCountByStatus(String status) {
    return selectedEquipmentIds
        .where((key) => key.endsWith(':$status'))
        .length;
  }

  /// 캐시된 제조사 목록 조회
  List<LookupItem> getCachedManufacturers() {
    final result = _lookupsService.getManufacturers();
    return result.fold(
      (failure) => [],
      (manufacturers) => manufacturers,
    );
  }

  /// 캐시된 장비명 목록 조회
  List<EquipmentNameItem> getCachedEquipmentNames() {
    final result = _lookupsService.getEquipmentNames();
    return result.fold(
      (failure) => [],
      (equipmentNames) => equipmentNames,
    );
  }

  /// 캐시된 장비 카테고리 조합 목록 조회
  List<CategoryCombinationItem> getCachedEquipmentCategories() {
    final result = _lookupsService.getEquipmentCategories();
    return result.fold(
      (failure) => [],
      (categories) => categories,
    );
  }

  /// 캐시된 장비 상태 목록 조회
  List<StatusItem> getCachedEquipmentStatuses() {
    final result = _lookupsService.getEquipmentStatuses();
    return result.fold(
      (failure) => [],
      (statuses) => statuses,
    );
  }

  /// 드롭다운용 장비 상태 맵 (id → name)
  Map<String, String> getEquipmentStatusDropdownItems() {
    final result = _lookupsService.getEquipmentStatusDropdownItems();
    return result.fold(
      (failure) => {},
      (items) => items,
    );
  }

  /// 특정 상태 ID에 해당하는 StatusItem 조회
  StatusItem? getEquipmentStatusById(String statusId) {
    final result = _lookupsService.getEquipmentStatusById(statusId);
    return result.fold(
      (failure) => null,
      (statusItem) => statusItem,
    );
  }
}