import 'package:injectable/injectable.dart';
import 'package:superport/data/models/model_dto.dart';
import 'package:superport/data/repositories/model_repository.dart';

/// Model 비즈니스 로직을 처리하는 UseCase
@lazySingleton
class ModelUseCase {
  final ModelRepository _repository;

  ModelUseCase(this._repository);

  /// 모든 모델 조회 (선택적으로 vendor로 필터링)
  Future<List<ModelDto>> getModels({int? vendorId}) async {
    try {
      final models = await _repository.getModels(vendorId: vendorId);
      
      // 활성 모델만 필터링 (비즈니스 규칙)
      return models.where((model) => model.isActive).toList()
        ..sort((a, b) => a.name.compareTo(b.name));
    } catch (e) {
      throw Exception('모델 목록을 불러오는데 실패했습니다: $e');
    }
  }

  /// 특정 모델 상세 조회
  Future<ModelDto> getModelById(int id) async {
    try {
      return await _repository.getModelById(id);
    } catch (e) {
      throw Exception('모델 정보를 불러오는데 실패했습니다: $e');
    }
  }

  /// 새 모델 생성
  Future<ModelDto> createModel({
    required int vendorsId,
    required String name,
  }) async {
    try {
      // 입력값 검증
      if (name.trim().isEmpty) {
        throw Exception('모델명을 입력해주세요');
      }

      // 중복 검사 (같은 vendor 내에서)
      final existingModels = await _repository.getModels(vendorId: vendorsId);
      final isDuplicate = existingModels.any(
        (model) => model.name.toLowerCase() == name.toLowerCase(),
      );

      if (isDuplicate) {
        throw Exception('동일한 제조사에 이미 존재하는 모델명입니다');
      }

      // 모델 생성
      final request = ModelRequestDto(
        vendorsId: vendorsId,
        name: name.trim(),
      );

      return await _repository.createModel(request);
    } catch (e) {
      if (e.toString().contains('이미 존재하는')) {
        rethrow;
      }
      throw Exception('모델 생성에 실패했습니다: $e');
    }
  }

  /// 모델 정보 수정
  Future<ModelDto> updateModel({
    required int id,
    required int vendorsId,
    required String name,
  }) async {
    try {
      // 입력값 검증
      if (name.trim().isEmpty) {
        throw Exception('모델명을 입력해주세요');
      }

      // 중복 검사 (자기 자신 제외)
      final existingModels = await _repository.getModels(vendorId: vendorsId);
      final isDuplicate = existingModels.any(
        (model) => model.id != id && 
                   model.name.toLowerCase() == name.toLowerCase(),
      );

      if (isDuplicate) {
        throw Exception('동일한 제조사에 이미 존재하는 모델명입니다');
      }

      // 모델 수정 
      final request = ModelUpdateRequestDto(
        vendorsId: vendorsId,
        name: name.trim(),
      );

      return await _repository.updateModel(id, request);
    } catch (e) {
      if (e.toString().contains('이미 존재하는')) {
        rethrow;
      }
      throw Exception('모델 수정에 실패했습니다: $e');
    }
  }

  /// 모델 삭제 (Hard Delete - 백엔드 API 사용)
  Future<void> deleteModel(int id) async {
    try {
      await _repository.deleteModel(id);
    } catch (e) {
      throw Exception('모델 삭제에 실패했습니다: $e');
    }
  }

  /// 모델 검색
  Future<List<ModelDto>> searchModels(String query) async {
    try {
      if (query.trim().isEmpty) {
        return await getModels();
      }

      final models = await _repository.searchModels(query);
      
      // 활성 모델만 필터링
      return models.where((model) => model.isActive).toList()
        ..sort((a, b) => a.name.compareTo(b.name));
    } catch (e) {
      throw Exception('모델 검색에 실패했습니다: $e');
    }
  }

  /// Vendor별 모델 그룹핑
  Future<Map<int, List<ModelDto>>> getModelsByVendorGrouped() async {
    try {
      final models = await getModels();
      final grouped = <int, List<ModelDto>>{};

      for (final model in models) {
        grouped.putIfAbsent(model.vendorsId, () => []).add(model);
      }

      return grouped;
    } catch (e) {
      throw Exception('모델 그룹핑에 실패했습니다: $e');
    }
  }

  /// Vendor 삭제 시 관련 모델 처리
  Future<void> handleVendorDeletion(int vendorId) async {
    try {
      final models = await _repository.getModels(vendorId: vendorId);
      
      // 모든 관련 모델 삭제
      for (final model in models) {
        if (model.id != null) {
          await _repository.deleteModel(model.id!);
        }
      }
    } catch (e) {
      throw Exception('Vendor 삭제 처리에 실패했습니다: $e');
    }
  }
}