import 'package:dio/dio.dart';
import 'package:get_it/get_it.dart';
import 'package:superport/core/constants/api_endpoints.dart';
import 'package:superport/core/errors/exceptions.dart';
import 'package:superport/data/datasources/remote/api_client.dart';
import 'package:superport/data/models/model/model_dto.dart';

abstract class ModelRemoteDataSource {
  Future<ModelListDto> getModels({
    int page = 1,
    int perPage = 10,
    String? search,
    int? vendorId,
    bool? includeDeleted,
  });
  
  Future<ModelDto> createModel(CreateModelRequest request);
  
  Future<ModelDto> getModelDetail(int id);
  
  Future<ModelDto> updateModel(int id, UpdateModelRequest request);
  
  Future<void> deleteModel(int id);

  Future<ModelDto> restoreModel(int id);

  Future<List<ModelDto>> getModelsByVendor(int vendorId);
}

class ModelRemoteDataSourceImpl implements ModelRemoteDataSource {
  final ApiClient _apiClient = GetIt.instance<ApiClient>();

  @override
  Future<ModelListDto> getModels({
    int page = 1,
    int perPage = 10,
    String? search,
    int? vendorId,
    bool? includeDeleted,
  }) async {
    try {
      final queryParams = <String, dynamic>{
        'page': page,
        'per_page': perPage,
      };

      if (search != null && search.isNotEmpty) {
        queryParams['search'] = search;
      }
      if (vendorId != null) {
        queryParams['vendor_id'] = vendorId;
      }
      if (includeDeleted != null) {
        queryParams['include_deleted'] = includeDeleted;
      }

      final response = await _apiClient.dio.get(
        ApiEndpoints.models,
        queryParameters: queryParams,
      );

      if (response.statusCode == 200) {
        return ModelListDto.fromJson(response.data);
      } else {
        throw ServerException(message: '모델 목록 조회 실패: ${response.statusCode}');
      }
    } on DioException catch (e) {
      throw ServerException(message: '네트워크 오류: ${e.message}');
    } catch (e) {
      throw ServerException(message: '모델 목록 조회 실패: $e');
    }
  }

  @override
  Future<ModelDto> getModelDetail(int id) async {
    try {
      final response = await _apiClient.dio.get('${ApiEndpoints.models}/$id');

      if (response.statusCode == 200) {
        return ModelDto.fromJson(response.data);
      } else {
        throw ServerException(message: '모델 상세 조회 실패: ${response.statusCode}');
      }
    } on DioException catch (e) {
      throw ServerException(message: '네트워크 오류: ${e.message}');
    } catch (e) {
      throw ServerException(message: '모델 상세 조회 실패: $e');
    }
  }

  @override
  Future<ModelDto> createModel(CreateModelRequest request) async {
    try {
      final response = await _apiClient.dio.post(
        ApiEndpoints.models,
        data: request.toJson(),
      );

      if (response.statusCode == 201) {
        return ModelDto.fromJson(response.data);
      } else {
        throw ServerException(message: '모델 생성 실패: ${response.statusCode}');
      }
    } on DioException catch (e) {
      throw ServerException(message: '네트워크 오류: ${e.message}');
    } catch (e) {
      throw ServerException(message: '모델 생성 실패: $e');
    }
  }

  @override
  Future<ModelDto> updateModel(int id, UpdateModelRequest request) async {
    try {
      final response = await _apiClient.dio.put(
        '${ApiEndpoints.models}/$id',
        data: request.toJson(),
      );

      if (response.statusCode == 200) {
        return ModelDto.fromJson(response.data);
      } else {
        throw ServerException(message: '모델 수정 실패: ${response.statusCode}');
      }
    } on DioException catch (e) {
      throw ServerException(message: '네트워크 오류: ${e.message}');
    } catch (e) {
      throw ServerException(message: '모델 수정 실패: $e');
    }
  }

  @override
  Future<void> deleteModel(int id) async {
    try {
      final response = await _apiClient.dio.delete('${ApiEndpoints.models}/$id');

      if (response.statusCode != 200) {
        throw ServerException(message: '모델 삭제 실패: ${response.statusCode}');
      }
    } on DioException catch (e) {
      throw ServerException(message: '네트워크 오류: ${e.message}');
    } catch (e) {
      throw ServerException(message: '모델 삭제 실패: $e');
    }
  }

  @override
  Future<ModelDto> restoreModel(int id) async {
    try {
      final response = await _apiClient.dio.put('${ApiEndpoints.models}/$id/restore');

      if (response.statusCode == 200) {
        return ModelDto.fromJson(response.data);
      } else {
        throw ServerException(message: '모델 복구 실패: ${response.statusCode}');
      }
    } on DioException catch (e) {
      throw ServerException(message: '네트워크 오류: ${e.message}');
    } catch (e) {
      throw ServerException(message: '모델 복구 실패: $e');
    }
  }

  @override
  Future<List<ModelDto>> getModelsByVendor(int vendorId) async {
    try {
      final response = await _apiClient.dio.get('${ApiEndpoints.modelsByVendor}/$vendorId');

      if (response.statusCode == 200) {
        final List<dynamic> data = response.data;
        return data.map((json) => ModelDto.fromJson(json)).toList();
      } else {
        throw ServerException(message: '제조사별 모델 조회 실패: ${response.statusCode}');
      }
    } on DioException catch (e) {
      throw ServerException(message: '네트워크 오류: ${e.message}');
    } catch (e) {
      throw ServerException(message: '제조사별 모델 조회 실패: $e');
    }
  }
}