import 'package:flutter/material.dart';
import 'package:injectable/injectable.dart';
import '../../../data/models/equipment/equipment_dto.dart';
import '../../../data/models/company/company_dto.dart';
import '../../../data/models/model/model_dto.dart';
import '../../../data/models/vendor_dto.dart';
import '../../../domain/usecases/equipment/create_equipment_usecase.dart';
import '../../../domain/usecases/equipment/update_equipment_usecase.dart';
import '../../../domain/usecases/equipment/get_equipment_detail_usecase.dart';
import '../../../domain/usecases/company/get_companies_usecase.dart';
import '../../../domain/usecases/models/get_models_usecase.dart';
import '../../../domain/usecases/vendor_usecase.dart';
import '../../../core/errors/failures.dart';

/// 장비 폼 컨트롤러 (생성/수정)
/// Phase 8 - Clean Architecture 패턴, 복합 FK 지원
@injectable
class EquipmentFormController extends ChangeNotifier {
  final CreateEquipmentUseCase _createEquipmentUseCase;
  final UpdateEquipmentUseCase _updateEquipmentUseCase;
  final GetEquipmentDetailUseCase _getEquipmentDetailUseCase;
  final GetCompaniesUseCase _getCompaniesUseCase;
  final GetModelsUseCase _getModelsUseCase;
  final VendorUseCase _vendorUseCase;

  EquipmentFormController(
    this._createEquipmentUseCase,
    this._updateEquipmentUseCase,
    this._getEquipmentDetailUseCase,
    this._getCompaniesUseCase,
    this._getModelsUseCase,
    this._vendorUseCase,
  );

  // 상태 관리
  bool _isLoading = false;
  bool _isLoadingCompanies = false;
  bool _isLoadingVendors = false;
  bool _isLoadingModels = false;
  bool _isSaving = false;
  String? _error;
  
  // 폼 데이터
  EquipmentDto? _currentEquipment;
  int? _equipmentId; // 수정 모드일 때 사용
  
  // 드롭다운 데이터
  List<CompanyDto> _companies = [];
  List<VendorDto> _vendors = [];
  List<ModelDto> _models = [];
  List<ModelDto> _filteredModels = [];
  
  // 선택된 값
  int? _selectedCompanyId;
  int? _selectedVendorId;
  int? _selectedModelId;
  
  // 폼 컨트롤러들
  final TextEditingController serialNumberController = TextEditingController();
  final TextEditingController barcodeController = TextEditingController();
  final TextEditingController purchasePriceController = TextEditingController();
  final TextEditingController warrantyNumberController = TextEditingController();
  final TextEditingController remarkController = TextEditingController();
  
  // 날짜 필드들
  DateTime? _purchasedAt;
  DateTime _warrantyStartedAt = DateTime.now().toUtc();
  DateTime _warrantyEndedAt = DateTime.now().toUtc().add(const Duration(days: 365));

  // Getters
  bool get isLoading => _isLoading;
  bool get isLoadingCompanies => _isLoadingCompanies;
  bool get isLoadingVendors => _isLoadingVendors;
  bool get isLoadingModels => _isLoadingModels;
  bool get isSaving => _isSaving;
  String? get error => _error;
  EquipmentDto? get currentEquipment => _currentEquipment;
  bool get isEditMode => _equipmentId != null;
  
  List<CompanyDto> get companies => _companies;
  List<VendorDto> get vendors => _vendors;
  List<ModelDto> get filteredModels => _filteredModels;
  
  int? get selectedCompanyId => _selectedCompanyId;
  int? get selectedVendorId => _selectedVendorId;
  int? get selectedModelId => _selectedModelId;
  
  DateTime? get purchasedAt => _purchasedAt;
  DateTime get warrantyStartedAt => _warrantyStartedAt;
  DateTime get warrantyEndedAt => _warrantyEndedAt;

  /// 초기화 (생성 모드)
  Future<void> initializeForCreate() async {
    _equipmentId = null;
    _currentEquipment = null;
    _clearForm();
    await _loadInitialData();
  }

  /// 초기화 (수정 모드)
  Future<void> initializeForEdit(int equipmentId) async {
    _equipmentId = equipmentId;
    _isLoading = true;
    _error = null;
    notifyListeners();

    try {
      await _loadInitialData();
      await _loadEquipmentDetail(equipmentId);
    } catch (e) {
      _error = '장비 정보를 불러오는데 실패했습니다: $e';
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  /// 초기 데이터 로드 (회사, 제조사, 모델)
  Future<void> _loadInitialData() async {
    await Future.wait([
      _loadCompanies(),
      _loadVendors(),
      _loadModels(),
    ]);
  }

  /// 회사 목록 로드
  Future<void> _loadCompanies() async {
    _isLoadingCompanies = true;
    notifyListeners();

    try {
      final params = GetCompaniesParams(page: 1, perPage: 1000); // 모든 회사 가져오기
      final result = await _getCompaniesUseCase(params);
      
      result.fold(
        (failure) {
          _error = _getErrorMessage(failure);
        },
        (paginatedResponse) {
          _companies = paginatedResponse.items
            .cast<CompanyDto>() // 타입 캐스팅 추가
            .where((company) => company.isActive)
            .toList()
            ..sort((a, b) => a.name.compareTo(b.name));
        },
      );
    } catch (e) {
      _error = '회사 목록을 불러오는데 실패했습니다: $e';
    } finally {
      _isLoadingCompanies = false;
      notifyListeners();
    }
  }

  /// 제조사 목록 로드
  Future<void> _loadVendors() async {
    _isLoadingVendors = true;
    notifyListeners();

    try {
      final vendorResponse = await _vendorUseCase.getVendors(limit: 1000); // 모든 제조사 가져오기
      _vendors = (vendorResponse.items as List)
          .whereType<VendorDto>()
          .where((vendor) => vendor.isActive)
          .toList()
          ..sort((a, b) => a.name.compareTo(b.name));
    } catch (e) {
      _error = '제조사 목록을 불러오는데 실패했습니다: $e';
    } finally {
      _isLoadingVendors = false;
      notifyListeners();
    }
  }

  /// 모델 목록 로드
  Future<void> _loadModels() async {
    _isLoadingModels = true;
    notifyListeners();

    try {
      const params = GetModelsParams(page: 1, perPage: 1000);
      final result = await _getModelsUseCase(params);
      result.fold(
        (failure) => throw Exception(failure.message),
        (modelResponse) {
          _models = modelResponse.items;
          _filteredModels = _models;
        },
      );
    } catch (e) {
      _error = '모델 목록을 불러오는데 실패했습니다: $e';
    } finally {
      _isLoadingModels = false;
      notifyListeners();
    }
  }

  /// 장비 상세 정보 로드 (수정 모드)
  Future<void> _loadEquipmentDetail(int equipmentId) async {
    final result = await _getEquipmentDetailUseCase(equipmentId);
    
    result.fold(
      (failure) {
        _error = _getErrorMessage(failure);
      },
      (equipment) {
        _currentEquipment = equipment;
        _populateForm(equipment);
      },
    );
  }

  /// 폼 필드에 데이터 채우기 (수정 모드)
  void _populateForm(EquipmentDto equipment) {
    _selectedCompanyId = equipment.companiesId;
    _selectedModelId = equipment.modelsId;
    
    serialNumberController.text = equipment.serialNumber;
    barcodeController.text = equipment.barcode ?? '';
    purchasePriceController.text = equipment.purchasePrice.toString();
    warrantyNumberController.text = equipment.warrantyNumber;
    remarkController.text = equipment.remark ?? '';
    
    _purchasedAt = equipment.purchasedAt?.toUtc(); // ✅ UTC 타임존으로 변환
    _warrantyStartedAt = equipment.warrantyStartedAt.toUtc(); // ✅ UTC 타임존으로 변환
    _warrantyEndedAt = equipment.warrantyEndedAt.toUtc(); // ✅ UTC 타임존으로 변환
    
    // 선택된 회사에 따라 모델 필터링
    _filterModelsByCompany(_selectedCompanyId);
    
    notifyListeners();
  }

  /// 회사 선택
  void selectCompany(int? companyId) {
    _selectedCompanyId = companyId;
    notifyListeners();
  }

  /// 제조사 선택 (제조사별 모델 필터링 활성화)
  void selectVendor(int? vendorId) {
    _selectedVendorId = vendorId;
    _selectedModelId = null; // 모델 선택 초기화
    _filterModelsByVendor(vendorId); // 실제 제조사별 필터링 실행
    notifyListeners();
  }

  /// 모델 선택
  void selectModel(int? modelId) {
    _selectedModelId = modelId;
    notifyListeners();
  }

  /// 제조사별 모델 필터링 (실제 구현)
  void _filterModelsByVendor(int? vendorId) {
    if (vendorId == null) {
      _filteredModels = _models;
    } else {
      // vendorsId 기준으로 실제 필터링 구현
      _filteredModels = _models.where((model) => model.vendorsId == vendorId).toList();
    }
    notifyListeners();
  }
  
  /// 레거시 호환성을 위한 Company 기반 필터링 (현재는 전체 모델 표시)
  void _filterModelsByCompany(int? companyId) {
    if (companyId == null) {
      _filteredModels = _models;
    } else {
      // 회사별 모델 필터링은 현재 구조에서는 불가능 (모든 모델 표시)
      _filteredModels = _models;
    }
    notifyListeners();
  }

  /// 구매일 선택
  void setPurchasedAt(DateTime? date) {
    _purchasedAt = date?.toUtc(); // ✅ UTC 타임존으로 변환
    notifyListeners();
  }

  /// 워런티 시작일 선택
  void setWarrantyStartedAt(DateTime date) {
    _warrantyStartedAt = date.toUtc(); // ✅ UTC 타임존으로 변환
    // 시작일이 종료일보다 늦으면 종료일을 1년 후로 설정
    if (_warrantyStartedAt.isAfter(_warrantyEndedAt)) {
      _warrantyEndedAt = _warrantyStartedAt.add(const Duration(days: 365));
    }
    notifyListeners();
  }

  /// 워런티 종료일 선택
  void setWarrantyEndedAt(DateTime date) {
    _warrantyEndedAt = date.toUtc(); // ✅ UTC 타임존으로 변환
    notifyListeners();
  }

  /// 폼 유효성 검증
  String? validateForm() {
    if (_selectedCompanyId == null) {
      return '회사를 선택해주세요.';
    }
    
    if (_selectedModelId == null) {
      return '모델을 선택해주세요.';
    }
    
    if (serialNumberController.text.trim().isEmpty) {
      return '시리얼 번호를 입력해주세요.';
    }
    
    if (warrantyNumberController.text.trim().isEmpty) {
      return '워런티 번호를 입력해주세요.';
    }
    
    if (_warrantyStartedAt.isAfter(_warrantyEndedAt)) {
      return '워런티 시작일이 종료일보다 늦을 수 없습니다.';
    }
    
    return null;
  }

  /// 장비 저장 (생성 또는 수정)
  Future<bool> saveEquipment() async {
    final validationError = validateForm();
    if (validationError != null) {
      _error = validationError;
      notifyListeners();
      return false;
    }

    _isSaving = true;
    _error = null;
    notifyListeners();

    try {
      if (isEditMode) {
        return await _updateEquipment();
      } else {
        return await _createEquipment();
      }
    } catch (e) {
      _error = '저장 중 오류가 발생했습니다: $e';
      return false;
    } finally {
      _isSaving = false;
      notifyListeners();
    }
  }

  /// 장비 생성
  Future<bool> _createEquipment() async {
    final request = EquipmentRequestDto(
      companiesId: _selectedCompanyId,              // 백엔드: Option<i32> - null 허용
      modelsId: _selectedModelId,                   // 백엔드: Option<i32> - null 허용
      serialNumber: serialNumberController.text.trim(),
      barcode: barcodeController.text.trim().isNotEmpty 
        ? barcodeController.text.trim() 
        : null,
      purchasedAt: (_purchasedAt ?? DateTime.now()).toUtc(), // 백엔드: 필수 필드 - 기본값 제공
      purchasePrice: int.tryParse(purchasePriceController.text) ?? 0,
      warrantyNumber: warrantyNumberController.text.trim(),
      warrantyStartedAt: _warrantyStartedAt.toUtc(), // ✅ UTC 타임존으로 변환
      warrantyEndedAt: _warrantyEndedAt.toUtc(), // ✅ UTC 타임존으로 변환
      remark: remarkController.text.trim().isNotEmpty 
        ? remarkController.text.trim() 
        : null,
    );

    final result = await _createEquipmentUseCase(request);
    
    return result.fold(
      (failure) {
        _error = _getErrorMessage(failure);
        return false;
      },
      (equipment) {
        _currentEquipment = equipment;
        return true;
      },
    );
  }

  /// 장비 수정
  Future<bool> _updateEquipment() async {
    final request = EquipmentUpdateRequestDto(
      companiesId: _selectedCompanyId!,
      modelsId: _selectedModelId!,
      serialNumber: serialNumberController.text.trim(),
      barcode: barcodeController.text.trim().isNotEmpty 
        ? barcodeController.text.trim() 
        : null,
      purchasedAt: _purchasedAt?.toUtc(), // ✅ UTC 타임존으로 변환
      purchasePrice: int.tryParse(purchasePriceController.text) ?? 0,
      warrantyNumber: warrantyNumberController.text.trim(),
      warrantyStartedAt: _warrantyStartedAt.toUtc(), // ✅ UTC 타임존으로 변환
      warrantyEndedAt: _warrantyEndedAt.toUtc(), // ✅ UTC 타임존으로 변환
      remark: remarkController.text.trim().isNotEmpty 
        ? remarkController.text.trim() 
        : null,
    );

    final result = await _updateEquipmentUseCase(UpdateEquipmentParams(
      id: _equipmentId!,
      request: request,
    ));
    
    return result.fold(
      (failure) {
        _error = _getErrorMessage(failure);
        return false;
      },
      (equipment) {
        _currentEquipment = equipment;
        return true;
      },
    );
  }

  /// 폼 초기화
  void _clearForm() {
    _selectedCompanyId = null;
    _selectedModelId = null;
    
    serialNumberController.clear();
    barcodeController.clear();
    purchasePriceController.text = '0';
    warrantyNumberController.clear();
    remarkController.clear();
    
    _purchasedAt = null;
    _warrantyStartedAt = DateTime.now().toUtc(); // ✅ UTC 타임존으로 변환
    _warrantyEndedAt = DateTime.now().toUtc().add(const Duration(days: 365)); // ✅ UTC 타임존으로 변환
    
    _error = null;
  }

  /// 에러 메시지 변환
  String _getErrorMessage(Failure failure) {
    switch (failure.runtimeType) {
      case ServerFailure:
        return (failure as ServerFailure).message;
      case NetworkFailure:
        return '네트워크 연결을 확인해주세요.';
      case ValidationFailure:
        return (failure as ValidationFailure).message;
      default:
        return '알 수 없는 오류가 발생했습니다.';
    }
  }

  /// 에러 초기화
  void clearError() {
    _error = null;
    notifyListeners();
  }

  @override
  void dispose() {
    serialNumberController.dispose();
    barcodeController.dispose();
    purchasePriceController.dispose();
    warrantyNumberController.dispose();
    remarkController.dispose();
    super.dispose();
  }
}