import 'package:flutter/material.dart';
import 'package:injectable/injectable.dart';
import 'package:superport/data/models/model/model_dto.dart';
import 'package:superport/data/models/vendor_dto.dart';
import 'package:superport/domain/usecases/models/get_models_usecase.dart';
import 'package:superport/domain/usecases/models/create_model_usecase.dart';
import 'package:superport/domain/usecases/models/update_model_usecase.dart';
import 'package:superport/domain/usecases/models/delete_model_usecase.dart';
import 'package:superport/domain/usecases/vendor_usecase.dart';

/// Model 관리 화면의 상태 관리 Controller
@lazySingleton
class ModelController extends ChangeNotifier {
  final GetModelsUseCase _getModelsUseCase;
  final CreateModelUseCase _createModelUseCase;
  final UpdateModelUseCase _updateModelUseCase;
  final DeleteModelUseCase _deleteModelUseCase;
  final VendorUseCase _vendorUseCase;

  ModelController(
    this._getModelsUseCase,
    this._createModelUseCase,
    this._updateModelUseCase,
    this._deleteModelUseCase,
    this._vendorUseCase,
  );

  // 상태 변수들
  List<ModelDto> _models = [];
  List<ModelDto> _filteredModels = [];
  List<VendorDto> _vendors = [];
  final Map<int, List<ModelDto>> _modelsByVendor = {};
  
  bool _isLoading = false;
  bool _isLoadingVendors = false;
  bool _isSubmitting = false;
  String? _errorMessage;
  String? _vendorsError;
  String _searchQuery = '';
  int? _selectedVendorId;
  
  // Getters
  List<ModelDto> get models => _filteredModels;
  List<ModelDto> get allModels => _models;
  List<VendorDto> get vendors => _vendors;
  Map<int, List<ModelDto>> get modelsByVendor => _modelsByVendor;
  bool get isLoading => _isLoading;
  bool get isLoadingVendors => _isLoadingVendors;
  bool get isSubmitting => _isSubmitting;
  String? get errorMessage => _errorMessage;
  String? get vendorsError => _vendorsError;
  String get searchQuery => _searchQuery;
  int? get selectedVendorId => _selectedVendorId;
  int get totalCount => _filteredModels.length;

  /// 초기 데이터 로드
  Future<void> loadInitialData() async {
    _isLoading = true;
    _errorMessage = null;
    notifyListeners();

    try {
      // Vendor 데이터 로드 (완전 안전한 오류 처리)
      try {
        final vendorResponse = await _vendorUseCase.getVendors();
        if (vendorResponse != null && vendorResponse.items.isNotEmpty) {
          _vendors = List<VendorDto>.from(vendorResponse.items);
        } else {
          _vendors = <VendorDto>[];
        }
      } catch (vendorError) {
        _vendors = <VendorDto>[];
        _vendorsError = "제조사 목록 로드 실패: $vendorError";
      }
      
      // Model 데이터 로드 (안전한 처리)
      const params = GetModelsParams(page: 1, perPage: 100);
      final modelResult = await _getModelsUseCase(params);
      modelResult.fold(
        (failure) => throw Exception(failure.message),
        (modelResponse) {
          if (modelResponse != null && modelResponse.items.isNotEmpty) {
            _models = List<ModelDto>.from(modelResponse.items);
            _filteredModels = List.from(_models);
          } else {
            _models = <ModelDto>[];
            _filteredModels = <ModelDto>[];
          }
        },
      );
      
      // Vendor별로 모델 그룹핑
      await _groupModelsByVendor();
      
    } catch (e) {
      _errorMessage = "모델 목록 조회 실패: ${e.toString()}";
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  /// 모델 목록 새로고침
  Future<void> refreshModels() async {
    _errorMessage = null;
    
    try {
      final params = GetModelsParams(
        page: 1, 
        perPage: 100,
        vendorId: _selectedVendorId,
      );
      final result = await _getModelsUseCase(params);
      result.fold(
        (failure) => throw Exception(failure.message),
        (modelResponse) {
          if (modelResponse != null && modelResponse.items.isNotEmpty) {
            _models = List<ModelDto>.from(modelResponse.items);
          } else {
            _models = <ModelDto>[];
          }
          _applyFilters();
        },
      );
      await _groupModelsByVendor();
    } catch (e) {
      _errorMessage = e.toString();
    } finally {
      notifyListeners();
    }
  }

  /// 모델 생성
  Future<bool> createModel({
    required int vendorsId,
    required String name,
  }) async {
    _isSubmitting = true;
    _errorMessage = null;
    notifyListeners();

    try {
      final request = CreateModelRequest(vendorsId: vendorsId, name: name);
      final result = await _createModelUseCase(request);
      
      return result.fold(
        (failure) {
          _errorMessage = failure.message;
          return false;
        },
        (newModel) {
          // 목록에 추가
          _models = [..._models, newModel];
          _applyFilters();
          _groupModelsByVendor();
          return true;
        },
      );
    } catch (e) {
      _errorMessage = e.toString();
      return false;
    } finally {
      _isSubmitting = false;
      notifyListeners();
    }
  }

  /// 모델 수정
  Future<bool> updateModel({
    required int id,
    required int vendorsId,
    required String name,
  }) async {
    _isSubmitting = true;
    _errorMessage = null;
    notifyListeners();

    try {
      final request = UpdateModelRequest(vendorsId: vendorsId, name: name);
      final params = UpdateModelParams(id: id, request: request);
      final result = await _updateModelUseCase(params);
      
      return result.fold(
        (failure) {
          _errorMessage = failure.message;
          return false;
        },
        (updatedModel) {
          // 목록에서 업데이트
          final index = _models.indexWhere((m) => m.id == id);
          if (index != -1) {
            _models = _models.map((model) => 
              model.id == id ? updatedModel : model
            ).toList();
            _applyFilters();
            _groupModelsByVendor();
          }
          return true;
        },
      );
    } catch (e) {
      _errorMessage = e.toString();
      return false;
    } finally {
      _isSubmitting = false;
      notifyListeners();
    }
  }

  /// 모델 삭제 (Soft Delete)
  Future<bool> deleteModel(int id) async {
    _isSubmitting = true;
    _errorMessage = null;
    notifyListeners();

    try {
      final result = await _deleteModelUseCase(id);
      
      return result.fold(
        (failure) {
          _errorMessage = failure.message;
          return false;
        },
        (_) {
          // 목록에서 제거 또는 비활성화 표시
          _models = _models.where((m) => m.id != id).toList();
          _applyFilters();
          _groupModelsByVendor();
          return true;
        },
      );
    } catch (e) {
      _errorMessage = e.toString();
      return false;
    } finally {
      _isSubmitting = false;
      notifyListeners();
    }
  }

  /// 검색어 설정
  void setSearchQuery(String query) {
    _searchQuery = query;
    _applyFilters();
    notifyListeners();
  }

  /// Vendor 필터 설정
  void setVendorFilter(int? vendorId) {
    _selectedVendorId = vendorId;
    _applyFilters();
    notifyListeners();
  }

  /// 필터 적용
  void _applyFilters() {
    _filteredModels = _models.where((model) {
      // Vendor 필터
      if (_selectedVendorId != null && model.vendorsId != _selectedVendorId) {
        return false;
      }
      
      // 검색어 필터
      if (_searchQuery.isNotEmpty) {
        final query = _searchQuery.toLowerCase();
        return model.name.toLowerCase().contains(query);
      }
      
      return true;
    }).toList();
  }

  /// Vendor별 모델 그룹핑
  Future<void> _groupModelsByVendor() async {
    _modelsByVendor.clear();
    
    for (final model in _models) {
      _modelsByVendor.putIfAbsent(model.vendorsId, () => []).add(model);
    }
  }

  /// Vendor ID로 Vendor 정보 가져오기
  VendorDto? getVendorById(int vendorId) {
    try {
      return _vendors.firstWhere((v) => v.id == vendorId);
    } catch (_) {
      return null;
    }
  }

  /// 특정 Vendor의 모델 목록 가져오기
  List<ModelDto> getModelsByVendor(int vendorId) {
    return _modelsByVendor[vendorId] ?? [];
  }

  /// 모델명 중복 확인
  Future<bool> checkDuplicateName(String name, {int? excludeId}) async {
    try {
      // 현재 로드된 모델 목록에서 중복 검사
      final duplicates = _models.where((model) {
        // 수정 모드일 때 자기 자신은 제외
        if (excludeId != null && model.id == excludeId) {
          return false;
        }
        // 대소문자 구분 없이 이름 비교
        return model.name.toLowerCase() == name.toLowerCase();
      }).toList();
      
      return duplicates.isNotEmpty;
    } catch (e) {
      // 에러 발생 시 false 반환 (중복 없음으로 처리)
      return false;
    }
  }

  /// 에러 메시지 클리어
  void clearError() {
    _errorMessage = null;
    notifyListeners();
  }

  /// 컨트롤러 리셋
  void reset() {
    _models.clear();
    _filteredModels.clear();
    _vendors.clear();
    _modelsByVendor.clear();
    _isLoading = false;
    _isSubmitting = false;
    _errorMessage = null;
    _searchQuery = '';
    _selectedVendorId = null;
    notifyListeners();
  }

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