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

import '../l10n/generated/app_localizations.dart';
import '../src/rust/api.dart' as rust;

/// Translate a [LogicalKeyboardKey] into the platform-neutral label
/// stored by the PTT binding flow.
String? pttDisplayLabelForKey(LogicalKeyboardKey k) {
  if (k == LogicalKeyboardKey.space) return 'Space';
  if (k == LogicalKeyboardKey.enter || k == LogicalKeyboardKey.numpadEnter) {
    return 'Enter';
  }
  if (k == LogicalKeyboardKey.tab) return 'Tab';
  if (k == LogicalKeyboardKey.escape) return 'Escape';
  if (k == LogicalKeyboardKey.backspace) return 'Backspace';
  if (k == LogicalKeyboardKey.delete) return 'Delete';
  if (k == LogicalKeyboardKey.insert) return 'Insert';
  if (k == LogicalKeyboardKey.home) return 'Home';
  if (k == LogicalKeyboardKey.end) return 'End';
  if (k == LogicalKeyboardKey.pageUp) return 'Page Up';
  if (k == LogicalKeyboardKey.pageDown) return 'Page Down';
  if (k == LogicalKeyboardKey.arrowUp) return 'Arrow Up';
  if (k == LogicalKeyboardKey.arrowDown) return 'Arrow Down';
  if (k == LogicalKeyboardKey.arrowLeft) return 'Arrow Left';
  if (k == LogicalKeyboardKey.arrowRight) return 'Arrow Right';
  if (k == LogicalKeyboardKey.shift ||
      k == LogicalKeyboardKey.shiftLeft ||
      k == LogicalKeyboardKey.shiftRight ||
      k == LogicalKeyboardKey.control ||
      k == LogicalKeyboardKey.controlLeft ||
      k == LogicalKeyboardKey.controlRight ||
      k == LogicalKeyboardKey.alt ||
      k == LogicalKeyboardKey.altLeft ||
      k == LogicalKeyboardKey.altRight ||
      k == LogicalKeyboardKey.meta ||
      k == LogicalKeyboardKey.metaLeft ||
      k == LogicalKeyboardKey.metaRight ||
      k == LogicalKeyboardKey.capsLock ||
      k == LogicalKeyboardKey.numLock ||
      k == LogicalKeyboardKey.scrollLock) {
    return null;
  }
  final fallback = k.keyLabel.trim();
  if (fallback.isEmpty) return null;
  return fallback;
}

/// Result of a successful PTT binding capture.
class CapturedBinding {
  const CapturedBinding({required this.inputClass, required this.platformKey});

  /// Coarse input class, safe to persist and display.
  final rust.BridgePttInputClass inputClass;

  /// Opaque platform-neutral key label.
  final String platformKey;
}

/// 'Save bookmark' name-entry dialog.
class BookmarkNameDialog extends StatefulWidget {
  /// Construct a bookmark-name dialog.
  const BookmarkNameDialog({super.key, required this.initialName});

  /// Initial display name.
  final String initialName;

  @override
  State<BookmarkNameDialog> createState() => _BookmarkNameDialogState();
}

class _BookmarkNameDialogState extends State<BookmarkNameDialog> {
  late final TextEditingController _ctl = TextEditingController(
    text: widget.initialName,
  );

  @override
  void dispose() {
    _ctl.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final l10n = AppL10n.of(context);
    return AlertDialog(
      title: Text(l10n.bookmarkAddTitle),
      content: TextField(
        controller: _ctl,
        autofocus: true,
        decoration: InputDecoration(labelText: l10n.fieldDisplayName),
        onSubmitted: (_) => Navigator.of(context).pop(_ctl.text),
      ),
      actions: [
        TextButton(
          onPressed: () => Navigator.of(context).pop(),
          child: Text(l10n.closeAction),
        ),
        FilledButton(
          onPressed: () => Navigator.of(context).pop(_ctl.text),
          child: Text(l10n.bookmarkAddAction),
        ),
      ],
    );
  }
}

/// Channel-password dialog.
class ChannelPasswordDialog extends StatefulWidget {
  /// Construct a channel-password dialog.
  const ChannelPasswordDialog({super.key});

  @override
  State<ChannelPasswordDialog> createState() => _ChannelPasswordDialogState();
}

class _ChannelPasswordDialogState extends State<ChannelPasswordDialog> {
  final TextEditingController _ctl = TextEditingController();

  @override
  void dispose() {
    _ctl.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final l10n = AppL10n.of(context);
    return AlertDialog(
      title: Text(l10n.channelPasswordTitle),
      content: TextField(
        controller: _ctl,
        obscureText: true,
        autofocus: true,
        decoration: InputDecoration(labelText: l10n.fieldPassword),
        onSubmitted: (_) => Navigator.of(context).pop(_ctl.text),
      ),
      actions: [
        TextButton(
          onPressed: () => Navigator.of(context).pop(),
          child: Text(l10n.closeAction),
        ),
        FilledButton(
          onPressed: () => Navigator.of(context).pop(_ctl.text),
          child: Text(l10n.connectAction),
        ),
      ],
    );
  }
}

/// Focus-scoped dialog that captures the next key press or mouse
/// side-button click.
class PttBindingCaptureDialog extends StatefulWidget {
  /// Construct a PTT binding capture dialog.
  const PttBindingCaptureDialog({super.key});

  @override
  State<PttBindingCaptureDialog> createState() =>
      _PttBindingCaptureDialogState();
}

class _PttBindingCaptureDialogState extends State<PttBindingCaptureDialog> {
  final FocusNode _focusNode = FocusNode();
  String? _captured;
  rust.BridgePttInputClass _capturedClass = rust.BridgePttInputClass.none;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _focusNode.requestFocus();
    });
  }

  @override
  void dispose() {
    _focusNode.dispose();
    super.dispose();
  }

  KeyEventResult _onKeyEvent(FocusNode node, KeyEvent event) {
    if (event is! KeyDownEvent) return KeyEventResult.ignored;
    final label = pttDisplayLabelForKey(event.logicalKey);
    if (label == null) return KeyEventResult.ignored;
    setState(() {
      _captured = label;
      _capturedClass = rust.BridgePttInputClass.keyboard;
    });
    return KeyEventResult.handled;
  }

  void _captureMouseSideButton(int button) {
    setState(() {
      _captured = 'mouse-side-button:$button';
      _capturedClass = rust.BridgePttInputClass.mouseSideButton;
    });
  }

  @override
  Widget build(BuildContext context) {
    final l10n = AppL10n.of(context);
    final theme = Theme.of(context);
    return AlertDialog(
      title: Text(l10n.pttConfigureTitle),
      content: ConstrainedBox(
        constraints: const BoxConstraints(maxWidth: 360),
        child: SingleChildScrollView(
          child: Focus(
            focusNode: _focusNode,
            onKeyEvent: _onKeyEvent,
            autofocus: true,
            child: Listener(
              behavior: HitTestBehavior.opaque,
              onPointerDown: (e) {
                const int back = 0x08;
                const int forward = 0x10;
                if (e.buttons == back || e.buttons == forward) {
                  _captureMouseSideButton(e.buttons);
                }
              },
              child: Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    l10n.pttConfigurePrompt,
                    style: theme.textTheme.bodyMedium,
                  ),
                  const SizedBox(height: 12),
                  Container(
                    width: double.infinity,
                    padding: const EdgeInsets.symmetric(
                      vertical: 12,
                      horizontal: 16,
                    ),
                    decoration: BoxDecoration(
                      color: theme.colorScheme.surfaceContainerHighest,
                      borderRadius: BorderRadius.circular(6),
                    ),
                    child: Text(
                      _captured == null
                          ? l10n.pttConfigureWaiting
                          : '${l10n.pttConfigureCaptured}: $_captured',
                      style: theme.textTheme.bodyMedium?.copyWith(
                        fontFamily: 'monospace',
                      ),
                    ),
                  ),
                  const SizedBox(height: 12),
                  Text(
                    l10n.pttConfigurePrivacyNote,
                    style: theme.textTheme.bodySmall?.copyWith(
                      color: theme.colorScheme.onSurfaceVariant,
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
      actions: [
        TextButton(
          onPressed: () => Navigator.of(context).pop(),
          child: Text(l10n.closeAction),
        ),
        FilledButton(
          onPressed: _captured == null
              ? null
              : () => Navigator.of(context).pop(
                  CapturedBinding(
                    inputClass: _capturedClass,
                    platformKey: _captured!,
                  ),
                ),
          child: Text(l10n.pttConfigureSaveAction),
        ),
      ],
    );
  }
}
