import 'package:dio/dio.dart';

import '../../../shared/utils/app_logger.dart';
import '../../contracts/trakt/trakt_token.dart';
import '../../contracts/trakt/trakt_user.dart';
import '../../domain/ports/trakt_gateway.dart';
import 'trakt_credentials.dart';
import 'trakt_rest_api.dart';


class TraktApiClient implements TraktGateway {
  static const _tag = 'Trakt';

  TraktApiClient({Dio? dio})
    : _api = TraktRestApi(
        (dio ??
              Dio(
                BaseOptions(
                  connectTimeout: const Duration(seconds: 10),
                  receiveTimeout: const Duration(seconds: 15),
                  headers: {'Accept': 'application/json'},
                ),
              ))
          ..interceptors.add(TraktHeaderInterceptor()),
      );

  final TraktRestApi _api;

  @override
  Future<TraktToken> exchangeCode(String code) async {
    try {
      return await _api.exchangeToken(<String, dynamic>{
        'client_id': TraktCredentials.clientId,
        'client_secret': TraktCredentials.clientSecret,
        'redirect_uri': TraktCredentials.redirectUri,
        'code': code,
        'grant_type': 'authorization_code',
      });
    } catch (e) {
      AppLogger.warn(_tag, 'exchangeCode failed', e);
      rethrow;
    }
  }

  @override
  Future<TraktToken> refreshToken(String refreshToken) async {
    try {
      return await _api.exchangeToken(<String, dynamic>{
        'client_id': TraktCredentials.clientId,
        'client_secret': TraktCredentials.clientSecret,
        'redirect_uri': TraktCredentials.redirectUri,
        'refresh_token': refreshToken,
        'grant_type': 'refresh_token',
      });
    } catch (e) {
      AppLogger.warn(_tag, 'refreshToken failed', e);
      rethrow;
    }
  }

  @override
  Future<TraktUser> getMe(String accessToken) async {
    try {
      final res = await _api.getUserSettings('Bearer $accessToken');
      return res.user ?? const TraktUser();
    } catch (e) {
      AppLogger.warn(_tag, 'getMe failed', e);
      rethrow;
    }
  }
}
