import 'package:flutter/cupertino.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:webrtc_controller_flutter/l10n/app_localizations.dart';

import '../../../../app/constants/app_constants.dart';
import '../../../auth/presentation/auth_controller.dart';
import '../../../auth/presentation/widgets/login_dialog.dart';
import '../../domain/binding_device.dart';
import '../../domain/connection_session_state.dart';
import '../connection_controller.dart';
import '../widgets/auth_dialog.dart';

/// 连接设置页：服务器地址 / 绑定设备选择 / 登录 / 连接。
class SetupPage extends ConsumerStatefulWidget {
  const SetupPage({super.key});

  @override
  ConsumerState<SetupPage> createState() => _SetupPageState();
}

class _SetupPageState extends ConsumerState<SetupPage> {
  final _deviceIdController = TextEditingController();

  @override
  void initState() {
    super.initState();
    // build() 期间不能改动 provider 状态，推迟到首帧之后。
    WidgetsBinding.instance.addPostFrameCallback((_) => _autoConnectSignaling());
  }

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

  /// 进入页面后自动建立信令（WebSocket）连接，并拉取绑定设备列表。
  ///
  /// 仅连接信令并完成注册，**不会**向任何设备发起远程控制；
  /// 能进入本页即已登录，携带 Bearer token 即可建连。
  Future<void> _autoConnectSignaling() async {
    if (!mounted) return;
    final loggedIn =
        ref.read(authControllerProvider).valueOrNull?.loggedIn ?? false;
    if (!loggedIn) return;

    await ref
        .read(connectionControllerProvider.notifier)
        .connectSignaling(serverUrl: kDefaultSignalServer);
    if (!mounted) return;
    await ref.read(connectionControllerProvider.notifier).loadDevices();
  }

  @override
  Widget build(BuildContext context) {
    final l10n = AppLocalizations.of(context);
    final authState = ref.watch(authControllerProvider).valueOrNull;
    final connection = ref.watch(connectionControllerProvider);

    // 登录完成后补发信令连接；退出登录则断开信令。
    ref.listen(authControllerProvider, (prev, next) {
      final was = prev?.valueOrNull?.loggedIn ?? false;
      final now = next.valueOrNull?.loggedIn ?? false;
      if (!was && now) {
        _autoConnectSignaling();
      } else if (was && !now) {
        ref.read(connectionControllerProvider.notifier).disconnect();
      }
    });

    // 信令注册成功后回显服务端下发的本机设备ID。
    final myDeviceId = connection.myDeviceId ?? '';
    if (_deviceIdController.text != myDeviceId) {
      _deviceIdController.text = myDeviceId;
    }

    // 连接建立后跳转控制页；连接失败等一次性提示展示后立即消费。
    ref.listen<ConnectionSessionState>(
      connectionControllerProvider,
      (prev, next) {
        if ((prev?.connected ?? false) == false && next.connected) {
          context.go('/control');
          return;
        }
        final alert = next.alert;
        if (alert != null && alert.isNotEmpty) {
          ref.read(connectionControllerProvider.notifier).consumeAlert();
          _showAlert(alert);
        }
      },
    );

    return CupertinoPageScaffold(
      navigationBar: CupertinoNavigationBar(
        middle: Text(l10n.appTitle),
      ),
      child: SafeArea(
        child: SingleChildScrollView(
          padding: const EdgeInsets.all(24),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(l10n.deviceId, style: const TextStyle(fontSize: 14)),
              const SizedBox(height: 8),
              CupertinoTextField(
                controller: _deviceIdController,
                placeholder: l10n.deviceIdPlaceholder,
                enabled: false,
                padding: const EdgeInsets.symmetric(
                  vertical: 12,
                  horizontal: 12,
                ),
              ),
              const SizedBox(height: 24),
              _buildDeviceSection(context, l10n, connection),
              const SizedBox(height: 16),
              Text(
                connection.status,
                style: const TextStyle(
                  fontSize: 16,
                  fontWeight: FontWeight.bold,
                ),
              ),
              if (connection.deviceError != null) ...[
                const SizedBox(height: 8),
                Text(
                  connection.deviceError!,
                  style: const TextStyle(fontSize: 13, color: CupertinoColors.systemRed),
                ),
              ],
              const SizedBox(height: 16),
              SizedBox(
                width: double.infinity,
                child: CupertinoButton.filled(
                  onPressed: (authState?.loggedIn ?? false)
                      ? () async {
                          await ref
                              .read(authControllerProvider.notifier)
                              .logout();
                        }
                      : () async {
                          final ok = await showCupertinoDialog<bool>(
                            context: context,
                            builder: (_) => const LoginDialog(),
                          );
                          if (ok != true && mounted) {
                            ref.read(connectionControllerProvider.notifier)
                                .consumeAlert();
                          }
                        },
                  child: Text(
                    (authState?.loggedIn ?? false)
                        ? l10n.logout
                        : l10n.loginAccount,
                  ),
                ),
              ),
              const SizedBox(height: 24),
              SizedBox(
                width: double.infinity,
                child: CupertinoButton.filled(
                  onPressed: connection.connecting ? null : _onConnectPressed,
                  child: Text(
                    connection.connecting ? l10n.connecting : l10n.connectDevice,
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  /// 绑定设备列表：展示已绑定设备、在线状态、选择，并提供刷新与配对码绑定。
  Widget _buildDeviceSection(
    BuildContext context,
    AppLocalizations l10n,
    ConnectionSessionState connection,
  ) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Text(l10n.boundDevices, style: const TextStyle(fontSize: 16)),
            CupertinoButton(
              padding: EdgeInsets.zero,
              onPressed: connection.deviceRefreshing
                  ? null
                  : () => ref
                      .read(connectionControllerProvider.notifier)
                      .loadDevices(),
              child: connection.deviceRefreshing
                  ? const CupertinoActivityIndicator(radius: 9)
                  : Text(l10n.refreshDevices),
            ),
          ],
        ),
        const SizedBox(height: 8),
        if (connection.bindings.isEmpty)
          _buildEmptyHint(context, l10n, connection)
        else
          _DeviceList(
            devices: connection.bindings,
            selectedUid: connection.selectedDeviceUid,
            onSelect: (uid) => ref
                .read(connectionControllerProvider.notifier)
                .selectDevice(uid),
          ),
        const SizedBox(height: 12),
        CupertinoButton(
          padding: EdgeInsets.zero,
          onPressed: connection.redeeming
              ? null
              : () => _showRedeemDialog(context, l10n),
          child: connection.redeeming
              ? const CupertinoActivityIndicator()
              : Text(l10n.redeemPairingCode),
        ),
      ],
    );
  }

  /// 无绑定设备时的引导提示（含配对失败提示）。
  Widget _buildEmptyHint(
    BuildContext context,
    AppLocalizations l10n,
    ConnectionSessionState connection,
  ) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          l10n.noBoundDevices,
          style: const TextStyle(fontSize: 14, color: CupertinoColors.systemGrey),
        ),
        if (connection.redeemError != null) ...[
          const SizedBox(height: 8),
          Text(
            connection.redeemError!,
            style: const TextStyle(fontSize: 13, color: CupertinoColors.systemRed),
          ),
        ],
      ],
    );
  }

  /// 兑换配对码对话框。
  Future<void> _showRedeemDialog(
    BuildContext context,
    AppLocalizations l10n,
  ) async {
    final controller = TextEditingController();
    final ok = await showCupertinoDialog<bool>(
      context: context,
      builder: (ctx) => CupertinoAlertDialog(
        title: Text(l10n.redeemPairingCode),
        content: Column(
          children: [
            const SizedBox(height: 12),
            CupertinoTextField(
              controller: controller,
              placeholder: l10n.pairingCodeHint,
              padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
            ),
          ],
        ),
        actions: [
          CupertinoDialogAction(
            child: Text(l10n.cancel),
            onPressed: () => Navigator.of(ctx).pop(false),
          ),
          CupertinoDialogAction(
            child: Text(l10n.confirm),
            onPressed: () => Navigator.of(ctx).pop(true),
          ),
        ],
      ),
    );
    if (ok != true || !mounted) {
      controller.dispose();
      return;
    }
    final code = controller.text.trim();
    // 延迟到下一帧再释放，避免对话框卸载时焦点回调访问已释放的 controller。
    WidgetsBinding.instance.addPostFrameCallback((_) => controller.dispose());
    if (code.isEmpty) return;
    final success = await ref
        .read(connectionControllerProvider.notifier)
        .redeemPairingCode(code);
    if (success && mounted) {
      _showAlert(l10n.bindSuccess);
    } else if (mounted) {
      final err = ref.read(connectionControllerProvider).redeemError;
      if (err != null && err.isNotEmpty) _showAlert(err);
    }
  }

  Future<void> _onConnectPressed() async {
    final l10n = AppLocalizations.of(context);
    final selected =
        ref.read(connectionControllerProvider.notifier).selectedDevice;
    if (selected == null) {
      _showAlert(l10n.pleaseSelectDevice);
      return;
    }
    if (!selected.online) {
      _showAlert(l10n.deviceOfflineCannotConnect(selected.name ?? selected.deviceUid));
      return;
    }
    // 连接前确保已登录（Bearer token）。
    final authState = ref.read(authControllerProvider).valueOrNull;
    final loggedIn = authState?.loggedIn ?? false;
    if (!loggedIn) {
      final ok = await showCupertinoDialog<bool>(
        context: context,
        builder: (_) => const LoginDialog(),
      );
      if (ok != true || !mounted) return;
    }

    // 信令若尚未就绪（如刚登录或曾断开），先补建连接。
    if (!ref.read(connectionControllerProvider).signalingConnected) {
      await _autoConnectSignaling();
      if (!mounted) return;
    }

    final selection = await showAuthDialog(context);
    if (selection == null || !mounted) return;

    await ref.read(connectionControllerProvider.notifier).connectSelectedDevice(
          authType: selection.type,
          authValue: selection.value,
        );
  }

  void _showAlert(String message) {
    showCupertinoDialog<void>(
      context: context,
      builder: (ctx) => CupertinoAlertDialog(
        content: Text(message),
        actions: [
          CupertinoDialogAction(
            child: const Text('确定'),
            onPressed: () => Navigator.of(ctx).pop(),
          ),
        ],
      ),
    );
  }
}

/// 绑定设备选择列表（Cupertino 风格）。
class _DeviceList extends StatelessWidget {
  const _DeviceList({
    required this.devices,
    required this.selectedUid,
    required this.onSelect,
  });

  final List<BindingDevice> devices;
  final String? selectedUid;
  final ValueChanged<String> onSelect;

  @override
  Widget build(BuildContext context) {
    final l10n = AppLocalizations.of(context);
    return CupertinoListSection.insetGrouped(
      margin: EdgeInsets.zero,
      children: [
        for (final d in devices)
          CupertinoListTile(
            title: Text(d.name ?? d.deviceUid),
            subtitle: Text(d.online ? l10n.online : l10n.offline),
            trailing: selectedUid == d.deviceUid
                ? const Icon(
                    CupertinoIcons.check_mark_circled_solid,
                    color: CupertinoColors.activeBlue,
                  )
                : null,
            onTap: () => onSelect(d.deviceUid),
          ),
      ],
    );
  }
}
