/// SRS-209 listen-only banner for mobile microphone permission.
///
/// Trace:
/// - SDD-106 §2 (denial UX — non-blocking affordance "Enable
///   microphone"), §3 (permanent denial — "Open settings" deep-link).
/// - SRS-209 (path to grant; listen-only fallback).
///
/// Behaviour:
///  * Watches the injected microphone permission state listenable.
///  * On `denied`: renders a non-modal banner with a "Grant" action.
///  * On `permanentlyDenied`: action text becomes "Open Settings" and
///    invokes [AndroidPermissionsService.openAppSettings].
///  * On `granted` / `unknown`: builds an empty [SizedBox.shrink].
///  * On platforms whose service stays at `granted`, this widget is
///    effectively invisible without any extra branching.
library;

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

import '../l10n/generated/app_localizations.dart';
import '../services/android_permissions_service.dart';

/// Listen-only banner widget. Drop this above the `VoiceBar` in the
/// app shell; it self-hides when no action is required.
///
/// Trace: SDD-106 §2, §3; SRS-209.
class PermissionStateBanner extends StatelessWidget {
  PermissionStateBanner({super.key, required AndroidPermissionsService service})
    : recordAudioState = service.recordAudioState,
      ensureRecordAudio = service.ensureRecordAudio,
      openAppSettings = service.openAppSettings;

  const PermissionStateBanner.fromCallbacks({
    super.key,
    required this.recordAudioState,
    required this.ensureRecordAudio,
    required this.openAppSettings,
  });

  final ValueListenable<AndroidRecordAudioPermissionState> recordAudioState;
  final Future<AndroidRecordAudioPermissionState> Function() ensureRecordAudio;
  final Future<void> Function() openAppSettings;

  @override
  Widget build(BuildContext context) {
    return ValueListenableBuilder<AndroidRecordAudioPermissionState>(
      valueListenable: recordAudioState,
      builder: (ctx, state, _) {
        final l10n = AppL10n.of(ctx);
        final action = _actionFor(state, l10n);
        if (action == null) {
          return const SizedBox.shrink();
        }

        return _BannerBody(
          message: l10n.microphonePermissionRequiredForVoice,
          actionLabel: action.label,
          onPressed: action.onPressed,
        );
      },
    );
  }

  _BannerAction? _actionFor(
    AndroidRecordAudioPermissionState state,
    AppL10n l10n,
  ) {
    switch (state) {
      case AndroidRecordAudioPermissionState.granted:
      case AndroidRecordAudioPermissionState.unknown:
        return null;
      case AndroidRecordAudioPermissionState.denied:
        return _BannerAction(
          label: l10n.permissionGrantAction,
          onPressed: () => ensureRecordAudio(),
        );
      case AndroidRecordAudioPermissionState.permanentlyDenied:
        return _BannerAction(
          label: l10n.networkPermissionOpenSettings,
          onPressed: () => openAppSettings(),
        );
    }
  }
}

class _BannerAction {
  const _BannerAction({required this.label, required this.onPressed});

  final String label;
  final VoidCallback onPressed;
}

class _BannerBody extends StatelessWidget {
  const _BannerBody({
    required this.message,
    required this.actionLabel,
    required this.onPressed,
  });

  final String message;
  final String actionLabel;
  final VoidCallback onPressed;

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    return Material(
      color: theme.colorScheme.errorContainer,
      borderRadius: BorderRadius.circular(8),
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
        child: Row(
          children: [
            Icon(Icons.mic_off, color: theme.colorScheme.onErrorContainer),
            const SizedBox(width: 12),
            Expanded(
              child: Text(
                message,
                style: TextStyle(color: theme.colorScheme.onErrorContainer),
              ),
            ),
            const SizedBox(width: 8),
            TextButton(
              onPressed: onPressed,
              style: TextButton.styleFrom(
                foregroundColor: theme.colorScheme.onErrorContainer,
              ),
              child: Text(actionLabel),
            ),
          ],
        ),
      ),
    );
  }
}
