import 'package:agora_rtc_engine/agora_rtc_engine.dart';
import 'package:flutter/foundation.dart';

import '../constants/app_constants.dart';
import '../network/api_client.dart';

class CallService {
  final ApiClient _apiClient;
  RtcEngine? _engine;

  CallService(this._apiClient);

  Future<Map<String, dynamic>?> requestToken({required int receiverId}) async {
    final res = await _apiClient.dio.post(
      '/shared/call/token',
      data: {'receiverId': receiverId},
    );
    final data = res.data['data'];
    return data is Map<String, dynamic> ? data : null;
  }

  Future<int?> getPairedReceiverId() async {
    final res = await _apiClient.dio.get('/pairing/status');
    final data = res.data['data'];
    if (data is! Map<String, dynamic>) return null;
    final id = data['pairedWithId'];
    return id is num ? id.toInt() : int.tryParse(id?.toString() ?? '');
  }

  Future<void> notifyIncomingCall({
    required int receiverId,
    required String channelName,
    String? agoraToken,
    int receiverUid = 0,
  }) async {
    await _apiClient.dio.post('/shared/call/notify', data: {
      'receiverId': receiverId,
      'channelName': channelName,
      'agoraToken': agoraToken,
      'receiverUid': receiverUid,
    });
  }

  Future<bool> callPairedUser({int uid = 0}) async {
    final receiverId = await getPairedReceiverId();
    if (receiverId == null) return false;

    final tokenData = await requestToken(receiverId: receiverId);
    final channelName = tokenData?['channelName']?.toString();
    final token = tokenData?['token']?.toString();
    if (channelName == null || channelName.isEmpty) return false;

    final joined = await joinChannel(
      channelName: channelName,
      token: token,
      uid: uid,
    );
    if (joined) {
      await notifyIncomingCall(
        receiverId: receiverId,
        channelName: channelName,
        agoraToken: token,
        receiverUid: uid,
      );
    }
    return joined;
  }

  Future<bool> joinChannel({
    required String channelName,
    String? token,
    int uid = 0,
  }) async {
    try {
      _engine ??= createAgoraRtcEngine();
      await _engine!.initialize(const RtcEngineContext(appId: AppConstants.agoraAppId));
      await _engine!.enableAudio();
      await _engine!.joinChannel(
        token: token ?? '',
        channelId: channelName,
        uid: uid,
        options: const ChannelMediaOptions(),
      );
      return true;
    } catch (e) {
      debugPrint('Agora join skipped: $e');
      return false;
    }
  }

  Future<void> leave() async {
    await _engine?.leaveChannel();
  }

  Future<void> dispose() async {
    await _engine?.release();
    _engine = null;
  }
}
