/// iOS microphone permission integration for AVAudioSession.
///
/// Trace:
/// - SRS-164 (iOS system permission presentation and settings path).
/// - SRS-114 / SRS-138 (iOS platform-service behaviour for audio).
library;

import 'dart:async';
import 'dart:developer' as developer;
import 'dart:io' show Platform;

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

import 'android_permissions_service.dart';

@visibleForTesting
const String iosPlatformChannelName = 'chanora/ios_platform';

@visibleForTesting
const String methodGetMicrophonePermissionState =
    'getMicrophonePermissionState';

@visibleForTesting
const String methodRequestMicrophonePermission = 'requestMicrophonePermission';

@visibleForTesting
const String methodIosOpenAppSettings = 'openAppSettings';

/// Dart-side integration for iOS microphone permission state.
class IosPermissionsService {
  IosPermissionsService({MethodChannel? channel})
    : _channel =
          channel ??
          (_isIOS ? const MethodChannel(iosPlatformChannelName) : null);

  static bool get _isIOS {
    if (kIsWeb) return false;
    return Platform.isIOS;
  }

  final MethodChannel? _channel;

  final ValueNotifier<AndroidRecordAudioPermissionState> _state =
      ValueNotifier<AndroidRecordAudioPermissionState>(
        _isIOS
            ? AndroidRecordAudioPermissionState.unknown
            : AndroidRecordAudioPermissionState.granted,
      );

  ValueListenable<AndroidRecordAudioPermissionState> get recordAudioState =>
      _state;

  Future<void> start() async {
    final ch = _channel;
    if (ch == null) return;
    try {
      _state.value = _parseState(
        await ch.invokeMethod<String>(methodGetMicrophonePermissionState),
      );
    } catch (_) {
      _state.value = AndroidRecordAudioPermissionState.unknown;
    }
  }

  void stop() {}

  Future<AndroidRecordAudioPermissionState> ensureRecordAudio() async {
    final ch = _channel;
    if (ch == null) return AndroidRecordAudioPermissionState.granted;
    if (_state.value == AndroidRecordAudioPermissionState.granted) {
      return AndroidRecordAudioPermissionState.granted;
    }
    try {
      final state = _parseState(
        await ch.invokeMethod<String>(methodRequestMicrophonePermission),
      );
      _state.value = state;
      return state;
    } catch (_) {
      return _state.value;
    }
  }

  Future<void> openAppSettings() async {
    final ch = _channel;
    if (ch == null) return;
    try {
      await ch.invokeMethod<bool>(methodIosOpenAppSettings);
    } catch (e, st) {
      developer.log(
        'openAppSettings failed',
        name: 'IosPermissionsService',
        error: e,
        stackTrace: st,
      );
    }
  }

  @visibleForTesting
  void dispose() {
    _state.dispose();
  }
}

AndroidRecordAudioPermissionState _parseState(String? raw) {
  switch (raw) {
    case 'Granted':
      return AndroidRecordAudioPermissionState.granted;
    case 'Denied':
      return AndroidRecordAudioPermissionState.permanentlyDenied;
    case 'NotDetermined':
      return AndroidRecordAudioPermissionState.denied;
    default:
      return AndroidRecordAudioPermissionState.unknown;
  }
}
