import 'dart:io' show Platform;

import 'package:flutter/services.dart';

import '../src/rust/api.dart' as rust;

const iosAudioLifecycleChannelName = 'chanora/ios_audio_lifecycle';
const androidAudioLifecycleChannelName = 'chanora/android_audio_lifecycle';

rust.BridgeAudioRoute parseBridgeAudioRoute(String value) {
  switch (value) {
    case 'Earpiece':
      return rust.BridgeAudioRoute.earpiece;
    case 'Speaker':
      return rust.BridgeAudioRoute.speaker;
    case 'WiredHeadset':
      return rust.BridgeAudioRoute.wiredHeadset;
    case 'BluetoothHfp':
      return rust.BridgeAudioRoute.bluetoothHfp;
    case 'BluetoothA2dp':
      return rust.BridgeAudioRoute.bluetoothA2Dp;
    default:
      return rust.BridgeAudioRoute.unknown;
  }
}

void wireAudioLifecycle() {
  wireIosAudioLifecycle();
  wireAndroidAudioLifecycle();
}

/// Wire the iOS AVAudioSession lifecycle MethodChannel.
///
/// Swift side (AppDelegate) posts route-change and interruption events through
/// this channel. The handler dispatches them to the FRB bridge functions on
/// the Rust side.
void wireIosAudioLifecycle({
  MethodChannel channel = const MethodChannel(iosAudioLifecycleChannelName),
}) {
  channel.setMethodCallHandler((call) async {
    try {
      switch (call.method) {
        case 'handleRouteChange':
          final routeStr = call.arguments as String? ?? 'Unknown';
          final route = parseBridgeAudioRoute(routeStr);
          rust.handleRouteChange(route: route);
          break;
        case 'handleMediaServicesReset':
          final routeClass = call.arguments as String? ?? 'Unknown';
          rust.handleMediaServicesResetWithRoute(routeClass: routeClass);
          break;
        case 'handleInterruptionBegan':
          rust.handleInterruptionBegan();
          break;
        case 'handleInterruptionEnded':
          final shouldResume = call.arguments as bool? ?? false;
          rust.handleInterruptionEnded(shouldResume: shouldResume);
          break;
        case 'handleWillResignActive':
        case 'handleDidEnterBackground':
          rust.handleInterruptionBegan();
          break;
        case 'handleWillEnterForeground':
          rust.handleInterruptionEnded(shouldResume: true);
          break;
        case 'handleWillTerminate':
          rust.handleInterruptionBegan();
          break;
        default:
          break;
      }
    } catch (_) {
      // Errors from the Rust side are already logged there; do not propagate
      // exceptions to the platform framework.
    }
  });
}

/// Wire the Android audio lifecycle MethodChannel.
///
/// Kotlin side (`AndroidAudioLifecycleController`) posts route-change events
/// through this channel. This mirrors the iOS dispatch path.
void wireAndroidAudioLifecycle({
  bool isAndroid = false,
  MethodChannel channel = const MethodChannel(androidAudioLifecycleChannelName),
}) {
  if (!isAndroid && !Platform.isAndroid) return;
  channel.setMethodCallHandler((call) async {
    try {
      switch (call.method) {
        case 'handleRouteChange':
          final args = call.arguments;
          final routeStr = args is Map
              ? (args['routeType'] as String? ?? 'Unknown')
              : (args as String? ?? 'Unknown');
          final route = parseBridgeAudioRoute(routeStr);
          rust.handleRouteChange(route: route);
          break;
        default:
          break;
      }
    } catch (_) {
      // Errors from the Rust side are already logged there; do not propagate
      // exceptions to the platform framework.
    }
  });
}
