import 'dart:async' show unawaited;
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/errors/failures.dart';
import 'package:superport/core/utils/debug_logger.dart';
import 'package:superport/core/services/lookups_service.dart';
import 'package:superport/data/models/equipment/equipment_dto.dart';
import 'package:superport/data/repositories/equipment_history_repository.dart';

/// 장비 입고 폼 컨트롤러
///
/// 폼의 전체 상태, 유효성, 저장, 데이터 로딩 등 비즈니스 로직을 담당한다.
class EquipmentInFormController extends ChangeNotifier {
  bool _disposed = false;
  final EquipmentService _equipmentService = GetIt.instance<EquipmentService>();
  // final WarehouseService _warehouseService = GetIt.instance<WarehouseService>(); // 사용되지 않음 - 제거
  // final CompanyService _companyService = GetIt.instance<CompanyService>(); // 사용되지 않음 - 제거
  final LookupsService _lookupsService = GetIt.instance<LookupsService>();
  final EquipmentHistoryRepository _equipmentHistoryRepository = GetIt.instance<EquipmentHistoryRepository>();
  final int? equipmentInId; // 실제로는 장비 ID (입고 ID가 아님)
  int? actualEquipmentId; // API 호출용 실제 장비 ID
  EquipmentDto? preloadedEquipment; // 사전 로드된 장비 데이터
  
  bool _isLoading = false;
  String? _error;
  bool _isSaving = false;
  // API만 사용
  
  // Getters
  bool get isLoading => _isLoading;
  String? get error => _error;
  bool get isSaving => _isSaving;
  
  // 저장 가능 상태를 별도 변수로 관리 (성능 개선 및 UI 동기화)
  bool _canSave = false;
  bool get canSave => _canSave;
  
  /// canSave 상태 업데이트 (UI 렌더링 문제 해결)
  void _updateCanSave() {
    if (_disposed) return; // dispose된 경우 업데이트 방지
    
    final hasEquipmentNumber = _serialNumber.trim().isNotEmpty;
    final hasModelsId = _modelsId != null;  // models_id 필수
    final hasWarrantyNumber = warrantyNumberController.text.trim().isNotEmpty; // warranty_number 필수
    final isNotSaving = !_isSaving;
    
    final newCanSave = isNotSaving && hasEquipmentNumber && hasModelsId && hasWarrantyNumber;
    
    if (_canSave != newCanSave) {
      _canSave = newCanSave;
      print('🚀 [canSave 상태 변경] $_canSave → serialNumber: "$_serialNumber", modelsId: $_modelsId, warrantyNumber: "${warrantyNumberController.text}"');
      notifyListeners(); // 명시적 UI 업데이트
    }
  }

  // 폼 키
  final GlobalKey<FormState> formKey = GlobalKey<FormState>();

  // 입력 상태 변수 (백엔드 API 구조에 맞게 수정)
  String _serialNumber = ''; // 장비번호 (필수) - private으로 변경
  String _barcode = '';       // 바코드 (선택사항) - 새로 추가
  int? _modelsId;               // 모델 ID (필수) - Vendor→Model cascade에서 선택
  int? _vendorId;               // 벤더 ID (UI용, API에는 전송 안함)
  
  // Legacy 필드 (UI 호환성 유지용)
  String _manufacturer = '';    // 제조사 (Legacy) - ModelDto에서 가져옴
  String _name = '';       // 모델명 (Legacy) - ModelDto에서 가져옴

  // Getters and Setters for reactive fields
  String get serialNumber => _serialNumber;
  set serialNumber(String value) {
    if (_serialNumber != value) {
      _serialNumber = value;
      _updateCanSave(); // canSave 상태 업데이트
      print('DEBUG [Controller] serialNumber updated: "$_serialNumber"');
    }
  }

  String get barcode => _barcode;
  set barcode(String value) {
    if (_barcode != value) {
      _barcode = value;
      print('DEBUG [Controller] barcode updated: "$_barcode"');
    }
  }

  String get manufacturer => _manufacturer;
  set manufacturer(String value) {
    if (_manufacturer != value) {
      _manufacturer = value;
      _updateCanSave(); // canSave 상태 업데이트
      print('DEBUG [Controller] manufacturer updated: "$_manufacturer"');
    }
  }

  String get name => _name;
  set name(String value) {
    if (_name != value) {
      _name = value;
      _updateCanSave(); // canSave 상태 업데이트
      print('DEBUG [Controller] name updated: "$_name"');
    }
  }


  // 새로운 필드 getters/setters
  int? get modelsId => _modelsId;
  set modelsId(int? value) {
    if (_modelsId != value) {
      _modelsId = value;
      _updateCanSave(); // canSave 상태 업데이트
      print('DEBUG [Controller] modelsId updated: $_modelsId');
    }
  }

  int? get vendorId => _vendorId;
  set vendorId(int? value) {
    if (_vendorId != value) {
      _vendorId = value;
      // vendor 변경 시 model 초기화
      if (_modelsId != null) {
        _modelsId = null;
        _updateCanSave();
      }
      print('DEBUG [Controller] vendorId updated: $_vendorId');
    }
  }

  // Vendor→Model 선택 콜백
  void onVendorModelChanged(int? vendorId, int? modelId) {
    if (_disposed) return;
    _vendorId = vendorId;
    _modelsId = modelId;
    _updateCanSave();
    notifyListeners();
  }
  DateTime? purchaseDate = DateTime.now();      // 구매일 (기본값: 현재 날짜)
  double? purchasePrice;       // 구매가격
  
  // 삭제된 필드들 (백엔드 미지원)
  // barcode, quantity, inDate, equipmentType, hasSerialNumber
  // warranty 관련 모든 필드들

  // Lookups API 데이터 (매번 API 호출)
  List<String> manufacturers = [];
  List<String> equipmentNames = [];
  Map<int, String> companies = {};
  Map<int, String> warehouses = {};
  
  // 선택된 ID 값들
  int? selectedCompanyId;      // 구매처 ID
  int? selectedWarehouseId;    // 입고지 ID
  
  // 재고 초기화 필드
  int _initialStock = 1;        // 초기 재고 수량 (기본값: 1)
  int get initialStock => _initialStock;
  set initialStock(int value) {
    if (_disposed) return;
    if (_initialStock != value && value > 0) {
      _initialStock = value;
      notifyListeners();
    }
  }
  
  // 창고 위치 전체 데이터 (이름-ID 매핑용)
  Map<String, int> warehouseLocationMap = {};

  // 편집 모드 여부
  bool isEditMode = false;

  // 수정불가 필드 목록 (수정 모드에서만 적용)
  static const List<String> _readOnlyFields = [
    'serialNumber',  // 장비번호
    'manufacturer',     // 제조사
    'name',        // 모델명
    'serialNumber',     // 시리얼번호
    'purchaseDate',     // 구매일
    'purchasePrice',    // 구매가격
  ];

  /// 특정 필드가 수정불가인지 확인
  bool isFieldReadOnly(String fieldName) {
    return isEditMode && _readOnlyFields.contains(fieldName);
  }

  // 입고지, 파트너사 관련 상태
  String? warehouseLocation;
  String? partnerCompany;
  List<String> warehouseLocations = [];
  List<String> partnerCompanies = [];

  // 기존 필드들은 위로 이동, 삭제된 필드들
  // currentCompanyId, currentBranchId, lastInspectionDate, nextInspectionDate, equipmentStatus는 입고 시 불필요
  
  // 워런티 관련 필드들 (필요 시 사용)
  String? warrantyLicense;
  DateTime warrantyStartDate = DateTime.now();
  DateTime warrantyEndDate = DateTime.now().add(const Duration(days: 365));

  final TextEditingController remarkController = TextEditingController();
  final TextEditingController warrantyNumberController = TextEditingController();

  EquipmentInFormController({this.equipmentInId}) {
    isEditMode = equipmentInId != null;
    
    // 워런티 번호 기본값 설정
    if (warrantyNumberController.text.isEmpty) {
      warrantyNumberController.text = 'WR-${DateTime.now().millisecondsSinceEpoch}';
    }
    
    _updateCanSave(); // 초기 canSave 상태 설정
    
    // ✅ 비동기 드롭다운 데이터 로드 시작 (await 불가능하므로 별도 처리)
    unawaited(_loadDropdownData());
    
    // 수정 모드일 때 초기 데이터 로드는 initializeForEdit() 메서드로 이동
  }
  
  // 사전 로드된 데이터로 초기화하는 생성자
  EquipmentInFormController.withPreloadedData({
    required Map<String, dynamic> preloadedData,
  }) : equipmentInId = preloadedData['equipmentId'] as int?,
       actualEquipmentId = preloadedData['equipmentId'] as int? {
    print('DEBUG [withPreloadedData] preloadedData keys: ${preloadedData.keys.toList()}');
    print('DEBUG [withPreloadedData] equipmentId from args: ${preloadedData['equipmentId']}');
    print('DEBUG [withPreloadedData] equipmentInId after assignment: $equipmentInId');
    print('DEBUG [withPreloadedData] actualEquipmentId: $actualEquipmentId');
    isEditMode = equipmentInId != null;
    print('DEBUG [withPreloadedData] isEditMode: $isEditMode');
    
    // 전달받은 데이터로 즉시 초기화
    print('DEBUG [withPreloadedData] equipment 데이터 타입: ${preloadedData['equipment'].runtimeType}');
    print('DEBUG [withPreloadedData] equipment 원시 데이터: ${preloadedData['equipment']}');
    
    try {
      preloadedEquipment = preloadedData['equipment'] as EquipmentDto?;
      print('DEBUG [withPreloadedData] EquipmentDto 캐스팅 성공');
      print('DEBUG [withPreloadedData] preloadedEquipment: ${preloadedEquipment != null ? "있음 (id: ${preloadedEquipment!.id})" : "null"}');
    } catch (e, stackTrace) {
      print('DEBUG [withPreloadedData] EquipmentDto 캐스팅 실패: $e');
      print('DEBUG [withPreloadedData] StackTrace: $stackTrace');
      preloadedEquipment = null;
    }
    
    final dropdownData = preloadedData['dropdownData'] as Map<String, dynamic>?;
    print('DEBUG [withPreloadedData] dropdownData: ${dropdownData != null ? "있음 (${dropdownData.keys.length}개 키)" : "null"}');
    
    if (dropdownData != null) {
      _processDropdownData(dropdownData);
    }
    
    if (preloadedEquipment != null) {
      print('DEBUG [withPreloadedData] _loadFromEquipment() 호출 예정');
      _loadFromEquipment(preloadedEquipment!);
    } else {
      print('DEBUG [withPreloadedData] preloadedEquipment가 null이어서 _loadFromEquipment() 호출 안함');
    }
    
    _updateCanSave();
  }

  // 수정 모드 초기화 (외부에서 호출)
  Future<void> initializeForEdit() async {
    print('DEBUG [initializeForEdit] 호출됨 - isEditMode: $isEditMode, equipmentInId: $equipmentInId');
    if (!isEditMode || equipmentInId == null) {
      print('DEBUG [initializeForEdit] 조건 미충족으로 return');
      return;
    }
    
    print('DEBUG [initializeForEdit] 드롭다운 데이터와 장비 데이터 병렬 로드 시작');
    // 드롭다운 데이터와 장비 데이터를 병렬로 로드
    await Future.wait([
      _waitForDropdownData(),
      _loadEquipmentIn(),
    ]);
    print('DEBUG [initializeForEdit] 병렬 로드 완료');
  }
  
  // 드롭다운 데이터 로드 대기
  Future<void> _waitForDropdownData() async {
    int retryCount = 0;
    while ((companies.isEmpty || warehouses.isEmpty) && retryCount < 10) {
      await Future.delayed(const Duration(milliseconds: 300));
      retryCount++;
      if (retryCount % 3 == 0) {
        print('DEBUG [_waitForDropdownData] Waiting for dropdown data... retry: $retryCount');
      }
    }
    print('DEBUG [_waitForDropdownData] Dropdown data loaded - companies: ${companies.length}, warehouses: ${warehouses.length}');
  }

  // 드롭다운 데이터 처리 (사전 로드된 데이터에서)
  void _processDropdownData(Map<String, dynamic> data) {
    manufacturers = data['manufacturers'] as List<String>? ?? [];
    equipmentNames = data['equipment_names'] as List<String>? ?? [];
    
    // ✅ List<Map> → Map<int, String> 안전한 변환 (사전 로드된 데이터)
    try {
      final companiesList = data['companies'] as List<dynamic>? ?? [];
      companies = Map<int, String>.fromIterable(
        companiesList.where((item) => item != null && item['id'] != null && item['name'] != null),
        key: (item) => item['id'] as int,
        value: (item) => item['name'] as String,
      );
      
      final warehousesList = data['warehouses'] as List<dynamic>? ?? [];
      warehouses = Map<int, String>.fromIterable(
        warehousesList.where((item) => item != null && item['id'] != null && item['name'] != null),
        key: (item) => item['id'] as int,
        value: (item) => item['name'] as String,
      );
      
    } catch (e) {
      DebugLogger.logError('사전 로드된 드롭다운 데이터 변환 실패', error: e);
      companies = {};
      warehouses = {};
    }
    
    DebugLogger.log('드롭다운 데이터 처리 완료', tag: 'EQUIPMENT_IN', data: {
      'manufacturers_count': manufacturers.length,
      'equipment_names_count': equipmentNames.length,
      'companies_count': companies.length,
      'warehouses_count': warehouses.length,
    });
  }
  
  // 드롭다운 데이터 로드 (매번 API 호출)
  Future<void> _loadDropdownData() async {
    try {
      DebugLogger.log('Equipment 폼 드롭다운 데이터 로드 시작', tag: 'EQUIPMENT_IN');
      final result = await _lookupsService.getEquipmentFormDropdownData();
      
      result.fold(
        (failure) {
          DebugLogger.logError('드롭다운 데이터 로드 실패', error: failure.message);
          // API 실패 시 빈 데이터
          manufacturers = [];
          equipmentNames = [];
          companies = {};
          warehouses = {};
          if (!_disposed) notifyListeners();
        },
        (data) {
          manufacturers = data['manufacturers'] as List<String>;
          equipmentNames = data['equipment_names'] as List<String>;
          
          // ✅ List<Map> → Map<int, String> 안전한 변환
          try {
            final companiesList = data['companies'] as List<dynamic>? ?? [];
            companies = Map<int, String>.fromIterable(
              companiesList.where((item) => item != null && item['id'] != null && item['name'] != null),
              key: (item) => item['id'] as int,
              value: (item) => item['name'] as String,
            );
            
            final warehousesList = data['warehouses'] as List<dynamic>? ?? [];
            warehouses = Map<int, String>.fromIterable(
              warehousesList.where((item) => item != null && item['id'] != null && item['name'] != null),
              key: (item) => item['id'] as int,
              value: (item) => item['name'] as String,
            );
            
          } catch (e) {
            DebugLogger.logError('드롭다운 데이터 변환 실패', error: e);
            companies = {};
            warehouses = {};
          }
          
          DebugLogger.log('드롭다운 데이터 로드 성공', tag: 'EQUIPMENT_IN', data: {
            'manufacturers_count': manufacturers.length,
            'equipment_names_count': equipmentNames.length,
            'companies_count': companies.length,
            'warehouses_count': warehouses.length,
          });
          
          if (!_disposed) notifyListeners();
        },
      );
    } catch (e) {
      DebugLogger.logError('드롭다운 데이터 로드 예외', error: e);
      manufacturers = [];
      equipmentNames = [];
      companies = {};
      warehouses = {};
      if (!_disposed) notifyListeners();
    }
  }

  // 기존의 개별 로드 메서드들은 _loadDropdownData()로 통합됨
  // warehouseLocations, partnerCompanies 리스트 변수들도 제거됨

  // 전달받은 장비 데이터로 폼 초기화 (간소화: 백엔드 JOIN 데이터 직접 활용)
  void _loadFromEquipment(EquipmentDto equipment) {
    print('DEBUG [_loadFromEquipment] 호출됨 - equipment.id: ${equipment.id}');
    print('DEBUG [_loadFromEquipment] equipment.warehousesId: ${equipment.warehousesId}');
    
    serialNumber = equipment.serialNumber;
    barcode = equipment.barcode ?? '';
    modelsId = equipment.modelsId;
    purchasePrice = equipment.purchasePrice > 0 ? equipment.purchasePrice.toDouble() : null;
    initialStock = 1;
    selectedCompanyId = equipment.companiesId;
    selectedWarehouseId = equipment.warehousesId;  // ✅ 기존 창고 ID 복원 (항상 null)
    print('DEBUG [_loadFromEquipment] selectedWarehouseId after assignment: $selectedWarehouseId');
    
    // 🔧 창고 정보가 null이므로 Equipment History에서 비동기로 로드 필요
    if (selectedWarehouseId == null) {
      print('DEBUG [_loadFromEquipment] 창고 정보 null - 비동기 로드 예약');
      // 비동기 메서드는 동기 메서드에서 직접 호출 불가 -> Future 예약
      Future.microtask(() => _loadWarehouseFromHistory(equipment.id));
    }
    
    // ✅ 간소화: 백엔드 JOIN 데이터 직접 사용 (복잡한 Controller 조회 제거)
    manufacturer = equipment.vendorName ?? '제조사 정보 없음';
    name = equipment.modelName ?? '모델 정보 없음';
    
    // 날짜 필드 설정
    purchaseDate = equipment.purchasedAt;
    warrantyStartDate = equipment.warrantyStartedAt;
    warrantyEndDate = equipment.warrantyEndedAt;
    
    // TextEditingController 동기화
    remarkController.text = equipment.remark ?? '';
    warrantyNumberController.text = equipment.warrantyNumber;
    
    // ✅ 수정 모드에서는 기존 창고 ID를 우선 사용, null인 경우에만 기본값 설정
    // (이제 위에서 selectedWarehouseId = equipment.warehousesId 로 설정하므로 이 조건은 거의 실행되지 않음)
    if (isEditMode && selectedWarehouseId == null && warehouses.isNotEmpty) {
      // 기존 창고 ID가 없는 경우에만 첫 번째 창고 선택
      selectedWarehouseId = warehouses.keys.first;
    }
    
    // preloadedEquipment에 저장 (UI에서 JOIN 데이터 접근용)
    preloadedEquipment = equipment;
    
    _updateCanSave();
    notifyListeners(); // UI 즉시 업데이트
  }

  /// Equipment History에서 창고 정보를 로드 (비동기)
  Future<void> _loadWarehouseFromHistory(int equipmentId) async {
    try {
      print('DEBUG [_loadWarehouseFromHistory] 시작 - 장비 ID: $equipmentId');
      
      final histories = await _equipmentHistoryRepository.getEquipmentHistoriesByEquipmentId(equipmentId);
      print('DEBUG [_loadWarehouseFromHistory] API 응답: ${histories.length}개 기록');
      
      if (histories.isNotEmpty) {
        // 가장 최근 이력의 창고 ID 사용
        final latestHistory = histories.first;
        selectedWarehouseId = latestHistory.warehousesId;
        
        final warehouseName = warehouses[selectedWarehouseId] ?? '알 수 없는 창고';
        print('DEBUG [_loadWarehouseFromHistory] 창고 정보 찾음: $warehouseName (ID: $selectedWarehouseId)');
        print('DEBUG [_loadWarehouseFromHistory] 최근 거래: ${latestHistory.transactionType} (${latestHistory.transactedAt})');
        
        notifyListeners(); // UI 업데이트
      } else {
        print('DEBUG [_loadWarehouseFromHistory] 이력 없음 - 기본 창고 사용');
        if (warehouses.isNotEmpty) {
          selectedWarehouseId = warehouses.keys.first;
          print('DEBUG [_loadWarehouseFromHistory] 기본 창고로 설정: $selectedWarehouseId');
          notifyListeners();
        }
      }
    } catch (e) {
      print('DEBUG [_loadWarehouseFromHistory] 오류: $e');
      // 오류 발생시 기본 창고 사용
      if (warehouses.isNotEmpty) {
        selectedWarehouseId = warehouses.keys.first;
        print('DEBUG [_loadWarehouseFromHistory] 오류로 인한 기본 창고 설정: $selectedWarehouseId');
        notifyListeners();
      }
    }
  }
  
  // 기존 데이터 로드(수정 모드)
  Future<void> _loadEquipmentIn() async {
    print('DEBUG [_loadEquipmentIn] 호출됨 - equipmentInId: $equipmentInId');
    if (equipmentInId == null) {
      print('DEBUG [_loadEquipmentIn] equipmentInId가 null이어서 return');
      return;
    }
    
    _isLoading = true;
    _error = null;
    notifyListeners();
    
    try {
      // equipmentInId는 실제로 장빔 ID임 (입고 ID가 아님)
      actualEquipmentId = equipmentInId;
      
      try {
        // API에서 장비 정보 가져오기
          print('DEBUG [_loadEquipmentIn] Start loading equipment ID: $actualEquipmentId');
          DebugLogger.log('장비 정보 로드 시작', tag: 'EQUIPMENT_IN', data: {
            'equipmentId': actualEquipmentId,
          });
          
          final equipment = await _equipmentService.getEquipmentDetail(actualEquipmentId!);
          print('DEBUG [_loadEquipmentIn] Equipment loaded from service');
          
          print('DEBUG [_loadEquipmentIn] Equipment loaded successfully');
          DebugLogger.log('장비 정보 로드 성공', tag: 'EQUIPMENT_IN', data: {
            'equipmentId': equipment.id,
            'companiesId': equipment.companiesId, // 백엔드 실제 필드
            'serialNumber': equipment.serialNumber,
          });
          
          // 장비 정보 설정 (백엔드 실제 필드 구조)
          print('DEBUG [_loadEquipmentIn] Setting equipment data...');
          print('DEBUG [_loadEquipmentIn] equipment.companiesId="${equipment.companiesId}"');
          print('DEBUG [_loadEquipmentIn] equipment.serialNumber="${equipment.serialNumber}"');
          
          // 백엔드 실제 필드로 매핑
          _serialNumber = equipment.serialNumber;
          _modelsId = equipment.modelsId; // 백엔드 실제 필드
          selectedCompanyId = equipment.companiesId; // companyId → companiesId
          selectedWarehouseId = equipment.warehousesId; // ✅ 기존 창고 ID 복원 (백엔드에서 null)
          print('DEBUG [_loadEquipmentIn] equipment.warehousesId: ${equipment.warehousesId}');
          print('DEBUG [_loadEquipmentIn] selectedWarehouseId after assignment: $selectedWarehouseId');
          
          // 🔧 창고 정보 우회 처리: Equipment History에서 가장 최근 창고 정보 조회
          // 백엔드 Equipment API가 창고 정보를 제공하지 않으므로 항상 Equipment History에서 조회
          try {
            print('DEBUG [_loadEquipmentIn] Equipment History API 호출 시작');
            final equipmentHistories = await _equipmentHistoryRepository.getEquipmentHistoriesByEquipmentId(equipment.id);
            print('DEBUG [_loadEquipmentIn] Equipment History API 응답: ${equipmentHistories.length}개 기록');
            
            if (equipmentHistories.isNotEmpty) {
              // 가장 최근 이력의 창고 ID 사용 (이미 날짜 순으로 정렬됨)
              final latestHistory = equipmentHistories.first;
              selectedWarehouseId = latestHistory.warehousesId;
              
              // 창고 이름 찾기
              final warehouseName = warehouses[selectedWarehouseId] ?? '알 수 없는 창고';
              
              print('DEBUG [_loadEquipmentIn] Equipment History에서 창고 정보 찾음: $warehouseName (ID: $selectedWarehouseId)');
              print('DEBUG [_loadEquipmentIn] 최근 거래: ${latestHistory.transactionType} (${latestHistory.transactedAt})');
              DebugLogger.log('창고 정보 우회 조회 성공', tag: 'EQUIPMENT_IN', data: {
                'equipmentId': equipment.id,
                'warehouseId': selectedWarehouseId,
                'warehouseName': warehouseName,
                'lastTransaction': latestHistory.transactionType,
                'transactedAt': latestHistory.transactedAt.toIso8601String(),
              });
            } else {
              print('DEBUG [_loadEquipmentIn] Equipment History가 비어있음 - 기본 창고 사용');
              // 창고 정보를 찾을 수 없으면 기본값으로 첫 번째 창고 사용
              if (warehouses.isNotEmpty) {
                selectedWarehouseId = warehouses.keys.first;
                print('DEBUG [_loadEquipmentIn] 기본 창고로 설정: $selectedWarehouseId');
              }
            }
          } catch (e) {
            print('DEBUG [_loadEquipmentIn] Equipment History에서 창고 정보 찾기 실패: $e');
            // 창고 정보를 찾을 수 없으면 기본값으로 첫 번째 창고 사용
            if (warehouses.isNotEmpty) {
              selectedWarehouseId = warehouses.keys.first;
              print('DEBUG [_loadEquipmentIn] 기본 창고로 설정: $selectedWarehouseId');
            }
          }
          
          purchasePrice = equipment.purchasePrice > 0 ? equipment.purchasePrice.toDouble() : null; // int → double 변환, 0이면 null
          remarkController.text = equipment.remark ?? '';
          
          // Legacy 필드들 - 백엔드에서 제공하는 정보 사용
          manufacturer = equipment.vendorName ?? ''; // vendor_name 사용
          name = equipment.modelName ?? ''; // model_name 사용
          
          // 날짜 필드 설정
          if (equipment.purchasedAt != null) {
            purchaseDate = equipment.purchasedAt;
          }
          
          // 보증 정보 설정
          if (equipment.warrantyStartedAt != null) {
            warrantyStartDate = equipment.warrantyStartedAt;
          }
          if (equipment.warrantyEndedAt != null) {
            warrantyEndDate = equipment.warrantyEndedAt;
          }
          warrantyNumberController.text = equipment.warrantyNumber;
          
          print('DEBUG [_loadEquipmentIn] After setting - serialNumber="$_serialNumber", manufacturer="$_manufacturer", name="$_name"');
          // 🔧 [DEBUG] UI 업데이트를 위한 중요 필드들 로깅
          print('DEBUG [_loadEquipmentIn] purchaseDate: $purchaseDate, purchasePrice: $purchasePrice');
          print('DEBUG [_loadEquipmentIn] selectedCompanyId: $selectedCompanyId, selectedWarehouseId: $selectedWarehouseId');
          
          DebugLogger.log('장비 데이터 설정 완료', tag: 'EQUIPMENT_IN', data: {
            'serialNumber': _serialNumber,
            'companiesId': selectedCompanyId,
            'modelsId': _modelsId,
            'purchasePrice': purchasePrice,
          });
          
          print('DEBUG [EQUIPMENT_IN]: Equipment loaded - serialNumber: "$_serialNumber", companiesId: "$selectedCompanyId", modelsId: "$_modelsId"');
          
          // 추가 필드들은 입고 시에는 필요하지 않으므로 생략
          
        } catch (e, stackTrace) {
          print('DEBUG [_loadEquipmentIn] Error loading equipment: $e');
          print('DEBUG [_loadEquipmentIn] Stack trace: $stackTrace');
          DebugLogger.logError('장비 정보 로드 실패', error: e);
          throw ServerFailure(message: '장비 정보를 찾을 수 없습니다.');
        }
    } catch (e) {
      _error = '장비 정보를 불러오는데 실패했습니다: $e';
      DebugLogger.logError('장비 로드 실패', error: e);
    } finally {
      _isLoading = false;
      _updateCanSave(); // 데이터 로드 완료 시 canSave 상태 업데이트
      if (!_disposed) notifyListeners();
    }
  }
  

  // 워런티 기간 계산
  String getWarrantyPeriodSummary() {
    final difference = warrantyEndDate.difference(warrantyStartDate);
    final days = difference.inDays;

    if (days <= 0) {
      return '유효하지 않은 기간';
    }

    final years = days ~/ 365;
    final remainingDays = days % 365;

    String summary = '';
    if (years > 0) {
      summary += '$years년 ';
    }
    if (remainingDays > 0) {
      summary += '$remainingDays일';
    }

    return summary.trim();
  }

  // 저장 처리
  Future<bool> save() async {
    if (!formKey.currentState!.validate()) {
      return false;
    }
    formKey.currentState!.save();
    
    // 입고지 필수 선택 검증 (신규 생성 모드에서만)
    if (!isEditMode && selectedWarehouseId == null) {
      _error = '입고지는 필수 선택 항목입니다. 입고지를 선택해주세요.';
      if (!_disposed) notifyListeners();
      return false;
    }
    
    _isSaving = true;
    _error = null;
    _updateCanSave(); // 저장 시작 시 canSave 상태 업데이트
    if (!_disposed) notifyListeners();
    
    try {

      // 새로운 입력값을 로컬 리스트에 추가 (사용자 경험 향상용)
      if (_manufacturer.isNotEmpty && !manufacturers.contains(_manufacturer)) {
        manufacturers.add(_manufacturer);
      }
      if (_name.isNotEmpty && !equipmentNames.contains(_name)) {
        equipmentNames.add(_name);
      }

    // 백엔드 API 구조에 맞는 Equipment 객체 생성
    final equipment = Equipment(
      // Required 필드들
      modelsId: _modelsId, // 필수: Model ID (Vendor→Model cascade에서 선택)
      equipmentNumber: _serialNumber.trim(), // required: 장비번호
      serialNumber: _serialNumber.trim(), // required: 시리얼번호
      quantity: 1, // required
      // Optional 필드들
      purchaseDate: purchaseDate,
      purchasePrice: purchasePrice,
      inDate: purchaseDate ?? DateTime.now(),
      remark: remarkController.text.trim().isEmpty ? null : remarkController.text.trim(),
      companyId: selectedCompanyId,      // 구매처 ID
      warehouseLocationId: selectedWarehouseId, // 입고지 ID
      barcode: '', // 사용하지 않음
    );
    
    // API 호출
    if (isEditMode) {
        // 수정 모드 - API로 장비 정보 업데이트
        if (actualEquipmentId == null) {
          throw ServerFailure(message: '장비 ID가 없습니다.');
        }
        
        DebugLogger.log('장비 정보 업데이트 시작', tag: 'EQUIPMENT_IN', data: {
          'equipmentId': actualEquipmentId,
          'serialNumber': equipment.serialNumber,
          'modelsId': equipment.modelsId,
          'companyId': equipment.companyId,
        });
        
        // Equipment 객체를 EquipmentUpdateRequestDto로 변환
        // 수정 시에는 실제로 값이 있는 필드만 전송
        // companies가 로드되었고 selectedCompanyId가 유효한 경우에만 포함
        final validCompanyId = companies.isNotEmpty && companies.containsKey(selectedCompanyId) 
            ? selectedCompanyId 
            : null;
        
        // 보증 번호가 비어있으면 원본 값 사용 또는 기본값
        final validWarrantyNumber = warrantyNumberController.text.trim().isNotEmpty 
            ? warrantyNumberController.text.trim() 
            : 'WR-${DateTime.now().millisecondsSinceEpoch}'; // 기본값 생성
        
        final updateRequest = EquipmentUpdateRequestDto(
          companiesId: validCompanyId,
          modelsId: _modelsId,
          serialNumber: _serialNumber.trim(),
          barcode: _barcode.trim().isEmpty ? null : _barcode.trim(),
          purchasedAt: purchaseDate,
          purchasePrice: purchasePrice?.toInt(),
          warrantyNumber: validWarrantyNumber,
          warrantyStartedAt: warrantyStartDate,
          warrantyEndedAt: warrantyEndDate,
          remark: remarkController.text.trim().isNotEmpty ? remarkController.text.trim() : null,
        );
        
        // 디버그: 전송할 데이터 로깅
        DebugLogger.log('장비 업데이트 요청 데이터', tag: 'EQUIPMENT_UPDATE', data: {
          'equipmentId': actualEquipmentId,
          'companiesId': updateRequest.companiesId,
          'modelsId': updateRequest.modelsId,
          'serialNumber': updateRequest.serialNumber,
          'purchasedAt': updateRequest.purchasedAt?.toIso8601String(),
          'purchasePrice': updateRequest.purchasePrice,
          'warrantyNumber': updateRequest.warrantyNumber,
          'warrantyStartedAt': updateRequest.warrantyStartedAt?.toIso8601String(),
          'warrantyEndedAt': updateRequest.warrantyEndedAt?.toIso8601String(),
          'remark': updateRequest.remark,
        });
        
        await _equipmentService.updateEquipment(actualEquipmentId!, updateRequest);
        
        DebugLogger.log('장비 정보 업데이트 성공', tag: 'EQUIPMENT_IN');
      } else {
        // 생성 모드
        try {
          // 1. 먼저 장비 생성
          DebugLogger.log('장비 입고 시작', tag: 'EQUIPMENT_IN', data: {
            'serialNumber': _serialNumber,
            'manufacturer': _manufacturer,
            'name': _name,
            'companiesId': selectedCompanyId,
          });
          
          // Equipment 객체를 EquipmentRequestDto로 변환 (백엔드 스펙에 맞게)
          final createRequest = EquipmentRequestDto(
            companiesId: selectedCompanyId,              // 백엔드: Option<i32> - null 허용
            modelsId: _modelsId,                        // 백엔드: Option<i32> - null 허용
            serialNumber: _serialNumber,
            barcode: _barcode.trim().isEmpty ? null : _barcode.trim(),
            purchasedAt: (purchaseDate ?? DateTime.now()).toUtc(),     // 단순 UTC 변환
            purchasePrice: purchasePrice?.toInt() ?? 0,
            warrantyNumber: warrantyNumberController.text.isNotEmpty 
                ? warrantyNumberController.text 
                : 'WR-${DateTime.now().millisecondsSinceEpoch}',
            warrantyStartedAt: warrantyStartDate.toUtc(),              // 단순 UTC 변환
            warrantyEndedAt: warrantyEndDate.toUtc(),                  // 단순 UTC 변환
            remark: remarkController.text.isNotEmpty ? remarkController.text : null,
          );
          
          final createdEquipment = await _equipmentService.createEquipment(createRequest);
          
          DebugLogger.log('장비 생성 성공', tag: 'EQUIPMENT_IN', data: {
            'equipmentId': createdEquipment.id,
          });
          
          // 2. Equipment History (입고 기록) 생성 - 출고 시스템과 동일한 패턴 적용
          print('🔍 [입고 처리] selectedWarehouseId: $selectedWarehouseId, createdEquipment.id: ${createdEquipment.id}');
          
          if (selectedWarehouseId != null && createdEquipment.id != null) {
            // 입고지 정보 상세 로깅
            final warehouseName = warehouses[selectedWarehouseId] ?? '알 수 없는 창고';
            print('🏪 [입고 처리] 입고지 정보:');
            print('   - 창고 ID: $selectedWarehouseId');
            print('   - 창고 이름: $warehouseName');
            print('   - 장비 ID: ${createdEquipment.id}');
            print('   - 입고 수량: $_initialStock');
            
            try {
              // ✅ Repository 직접 호출 (출고 시스템과 동일한 패턴)
              await _equipmentHistoryRepository.createStockIn(
                equipmentsId: createdEquipment.id,
                warehousesId: selectedWarehouseId!,
                quantity: _initialStock,
                transactedAt: DateTime.now().toUtc().copyWith(microsecond: 0),
                remark: '장비 등록 시 자동 입고',
              );
              
              print('✅ [입고 처리] Equipment History 생성 성공');
              DebugLogger.log('Equipment History 생성 성공', tag: 'EQUIPMENT_IN', data: {
                'equipmentId': createdEquipment.id,
                'warehouseId': selectedWarehouseId,
                'warehouseName': warehouseName,
                'quantity': _initialStock,
              });
            } catch (e) {
              // ✅ 입고 이력 생성 실패시 전체 프로세스 실패 처리 (출고 시스템과 동일)
              print('❌ [입고 처리] Equipment History 생성 실패: $e');
              DebugLogger.logError('Equipment History 생성 실패', error: e);
              throw Exception('입고 이력 생성에 실패했습니다. 다시 시도해주세요: $e');
            }
          } else {
            // 필수 정보 누락 시 에러
            final missingInfo = <String>[];
            if (selectedWarehouseId == null) missingInfo.add('입고지');
            if (createdEquipment.id == null) missingInfo.add('장비 ID');
            
            final errorMsg = '입고 처리 실패: ${missingInfo.join(', ')} 정보가 누락되었습니다';
            print('❌ [입고 처리] $errorMsg');
            _error = errorMsg;
          }
          
          DebugLogger.log('입고 처리 완료', tag: 'EQUIPMENT_IN');
          
        } catch (e) {
          DebugLogger.logError('장비 입고 처리 실패', error: e);
          rethrow;  // 에러를 상위로 전파하여 적절한 에러 메시지 표시
        }
      }

    // 저장 후 드롭다운 데이터 새로고침 (백엔드 데이터 업데이트를 위해)
    _loadDropdownData();

    return true;
    } on Failure catch (e) {
      _error = e.message;
      if (!_disposed) notifyListeners();
      return false;
    } catch (e) {
      _error = 'An unexpected error occurred: $e';
      if (!_disposed) notifyListeners();
      return false;
    } finally {
      _isSaving = false;
      _updateCanSave(); // 저장 완료 시 canSave 상태 업데이트
      if (!_disposed) notifyListeners();
    }
  }

  // 에러 처리
  void clearError() {
    if (_disposed) return;
    _error = null;
    notifyListeners();
  }
  
  // API만 사용하므로 토글 기능 제거
  
  @override
  void dispose() {
    _disposed = true; // dispose 상태 설정
    remarkController.dispose();
    warrantyNumberController.dispose();
    super.dispose();
  }
}
