import 'package:dartz/dartz.dart';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:injectable/injectable.dart';
import 'package:superport/core/errors/failures.dart';
import 'package:superport/data/datasources/remote/api_client.dart';
import 'package:superport/core/constants/api_endpoints.dart';
import 'package:superport/data/models/lookups/lookup_data.dart';

abstract class LookupRemoteDataSource {
  Future<Either<Failure, LookupData>> getAllLookups();
  Future<Either<Failure, LookupData>> getLookupsByType(String type);
}

@LazySingleton(as: LookupRemoteDataSource)
class LookupRemoteDataSourceImpl implements LookupRemoteDataSource {
  final ApiClient _apiClient;

  LookupRemoteDataSourceImpl(this._apiClient);

  @override
  Future<Either<Failure, LookupData>> getAllLookups() async {
    try {
      debugPrint('📞 === LOOKUP 개별 API 요청 시작 ===');
      
      // 개별 API들을 병렬로 호출
      final List<Future> futures = [
        _apiClient.get(ApiEndpoints.lookupsVendors),
        _apiClient.get(ApiEndpoints.lookupsCompanies), 
        _apiClient.get(ApiEndpoints.lookupsWarehouses),
      ];
      
      final responses = await Future.wait(futures, eagerError: false);
      
      debugPrint('📊 === LOOKUP 개별 API 응답 ===');
      
      // Vendors 데이터 처리
      List<LookupItem> manufacturers = [];
      try {
        final vendorsResponse = responses[0] as Response;
        if (vendorsResponse.data is List) {
          manufacturers = (vendorsResponse.data as List)
            .map((v) => LookupItem(
              id: v['id'] as int?, 
              name: v['name'] as String
            ))
            .toList();
          debugPrint('✅ 제조사 데이터: ${manufacturers.length}개');
        }
      } catch (e) {
        debugPrint('⚠️ 제조사 데이터 처리 실패: $e');
      }
      
      // Companies 데이터 처리
      List<LookupItem> companies = [];
      try {
        final companiesResponse = responses[1] as Response;
        if (companiesResponse.data is List) {
          companies = (companiesResponse.data as List)
            .map((c) => LookupItem(
              id: c['id'] as int?, 
              name: c['name'] as String
            ))
            .toList();
          debugPrint('✅ 회사 데이터: ${companies.length}개');
        }
      } catch (e) {
        debugPrint('⚠️ 회사 데이터 처리 실패: $e');
      }
      
      // Warehouses 데이터 처리
      List<LookupItem> warehouses = [];
      try {
        final warehousesResponse = responses[2] as Response;
        if (warehousesResponse.data is List) {
          warehouses = (warehousesResponse.data as List)
            .map((w) => LookupItem(
              id: w['id'] as int?, 
              name: w['name'] as String
            ))
            .toList();
          debugPrint('✅ 창고 데이터: ${warehouses.length}개');
        }
      } catch (e) {
        debugPrint('⚠️ 창고 데이터 처리 실패: $e');
      }
      
      // 통합된 LookupData 생성
      final lookupData = LookupData(
        manufacturers: manufacturers,
        companies: companies,
        warehouses: warehouses,
        equipmentNames: [], // 현재 백엔드에서 제공하지 않음
        equipmentCategories: [], // 현재 백엔드에서 제공하지 않음
        equipmentStatuses: [], // 현재 백엔드에서 제공하지 않음
      );
      
      debugPrint('📊 통합 Lookup 데이터 생성 완료');
      return Right(lookupData);
      
    } on DioException catch (e) {
      debugPrint('❌ === LOOKUP API DIO 에러 ===');
      debugPrint('❌ 에러 타입: ${e.type}');
      debugPrint('❌ 상태 코드: ${e.response?.statusCode}');
      debugPrint('❌ 에러 메시지: ${e.message}');
      
      // 개별 API 오류의 경우 빈 데이터로 fallback
      return Right(LookupData.empty());
    } catch (e) {
      debugPrint('❌ === LOOKUP API 일반 에러 ===');
      debugPrint('❌ 에러: $e');
      return Left(ServerFailure(message: '조회 데이터를 가져오는 중 오류가 발생했습니다: $e'));
    }
  }

  @override
  Future<Either<Failure, LookupData>> getLookupsByType(String type) async {
    try {
      final response = await _apiClient.get(
        '${ApiEndpoints.lookups}/type',
        queryParameters: {'lookup_type': type},
      );
      
      if (response.data != null && response.data['success'] == true && response.data['data'] != null) {
        // 타입별 조회도 전체 LookupData 형식으로 반환 - IdentityMap 타입 오류 수정
        try {
          final lookupData = LookupData.fromJson(response.data['data'] as Map<String, dynamic>);
          return Right(lookupData);
        } catch (jsonError) {
          debugPrint('❌ LookupData JSON 파싱 오류: $jsonError');
          debugPrint('❌ 응답 데이터: ${response.data['data']}');
          // JSON 파싱 실패 시 빈 데이터 반환
          return Right(LookupData.empty());
        }
      } else {
        final errorMessage = response.data?['error']?['message'] ?? '응답 데이터가 올바르지 않습니다';
        return Left(ServerFailure(message: errorMessage));
      }
    } on DioException catch (e) {
      return Left(_handleDioError(e));
    } catch (e) {
      debugPrint('❌ getLookupsByType 일반 오류: $e');
      return Left(ServerFailure(message: '타입별 조회 데이터를 가져오는 중 오류가 발생했습니다: $e'));
    }
  }

  Failure _handleDioError(DioException error) {
    switch (error.type) {
      case DioExceptionType.connectionTimeout:
      case DioExceptionType.sendTimeout:
      case DioExceptionType.receiveTimeout:
        return NetworkFailure(message: '네트워크 연결 시간이 초과되었습니다');
      case DioExceptionType.connectionError:
        return NetworkFailure(message: '서버에 연결할 수 없습니다');
      case DioExceptionType.badResponse:
        final statusCode = error.response?.statusCode ?? 0;
        final errorData = error.response?.data;
        
        String message;
        if (errorData is Map) {
          message = errorData['error']?['message'] ?? 
                   errorData['message'] ?? 
                   '서버 오류가 발생했습니다';
        } else {
          message = '서버 오류가 발생했습니다';
        }
        
        if (statusCode == 401) {
          return AuthenticationFailure(message: '인증이 만료되었습니다');
        } else if (statusCode == 403) {
          return AuthenticationFailure(message: '접근 권한이 없습니다');
        } else {
          return ServerFailure(message: message);
        }
      case DioExceptionType.cancel:
        return ServerFailure(message: '요청이 취소되었습니다');
      default:
        return ServerFailure(message: '알 수 없는 오류가 발생했습니다');
    }
  }
}