import 'package:flutter/material.dart';
import 'package:forui/forui.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:url_launcher/url_launcher.dart';

import '../../providers/update_provider.dart';
import '../../shared/app_info.dart';
import '../../shared/utils/format_utils.dart';

class UpdateDialog extends ConsumerStatefulWidget {
  const UpdateDialog({super.key});

  @override
  ConsumerState<UpdateDialog> createState() => _UpdateDialogState();
}

class _UpdateDialogState extends ConsumerState<UpdateDialog> {
  bool _installTriggered = false;

  @override
  Widget build(BuildContext context) {
    final state = ref.watch(updateProvider);
    final info = state.info;
    final appVersion =
        ref.watch(appVersionProvider).value ?? kSmPlayerVersionFallback;

    if (state.status == UpdateStatus.readyToInstall && !_installTriggered) {
      _installTriggered = true;
      WidgetsBinding.instance.addPostFrameCallback((_) async {
        final navigator = Navigator.of(context);
        await ref.read(updateProvider.notifier).install();
        if (mounted && navigator.canPop()) {
          navigator.pop();
        }
      });
    }

    if (info == null) {
      return FDialog.adaptive(
        title: const Text('检查更新'),
        body: _ErrorContent(message: state.error ?? '没有可用的更新信息'),
        actions: [
          FButton(
            onPress: () => ref.read(updateProvider.notifier).manualCheck(),
            child: const Text('重试'),
          ),
          FButton(
            onPress: () => Navigator.of(context).pop(),
            variant: FButtonVariant.outline,
            child: const Text('关闭'),
          ),
        ],
      );
    }

    final isDownloading = state.status == UpdateStatus.downloading;
    final isReady = state.status == UpdateStatus.readyToInstall;
    final hasError = state.status == UpdateStatus.error;
    final noAsset = info.noAssetForPlatform;

    return FDialog.adaptive(
      title: Text('发现新版本 ${info.version}'),
      body: SizedBox(
        width: 460,
        child: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('当前版本 $appVersion → 最新版本 ${info.version}'),
            const SizedBox(height: 12),
            ConstrainedBox(
              constraints: const BoxConstraints(maxHeight: 220),
              child: SingleChildScrollView(
                child: Text(
                  info.releaseNotes.trim().isEmpty
                      ? '暂无更新说明'
                      : info.releaseNotes.trim(),
                  style: Theme.of(context).textTheme.bodySmall,
                ),
              ),
            ),
            if (isDownloading) ...[
              const SizedBox(height: 16),
              FDeterminateProgress(
                value: downloadProgressValue(
                  received: state.received,
                  total: state.total,
                ) ?? 0,
              ),
              const SizedBox(height: 8),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Text(
                    '${formatDownloadBytes(state.received)} / ${formatDownloadBytes(state.total)}',
                    style: Theme.of(context).textTheme.bodySmall,
                  ),
                  Text(
                    formatDownloadSpeed(state.speedBytesPerSec),
                    style: Theme.of(context).textTheme.bodySmall,
                  ),
                ],
              ),
            ],
            if (isReady) ...[
              const SizedBox(height: 16),
              const Text('安装程序已下载，正在打开。'),
            ],
            if (hasError) ...[
              const SizedBox(height: 16),
              _ErrorContent(message: state.error ?? '更新失败'),
            ],
          ],
        ),
      ),
      actions: [
        if (isDownloading)
          FButton(
            onPress: () => ref.read(updateProvider.notifier).cancel(),
            variant: FButtonVariant.outline,
            child: const Text('取消'),
          )
        else ...[
          FButton(
            onPress: () => Navigator.of(context).pop(),
            variant: FButtonVariant.outline,
            child: const Text('稍后'),
          ),
          if (hasError)
            FButton(
              onPress: () => ref.read(updateProvider.notifier).startDownload(),
              child: const Text('重试'),
            )
          else if (noAsset)
            FButton(
              onPress: () => _openDownloadPage(info.htmlUrl),
              child: const Text('前往下载页'),
            )
          else
            FButton(
              onPress: isReady
                  ? null
                  : () => ref.read(updateProvider.notifier).startDownload(),
              child: const Text('下载并安装'),
            ),
        ],
      ],
    );
  }

  Future<void> _openDownloadPage(Uri uri) async {
    if (!uri.hasScheme) return;
    await launchUrl(uri, mode: LaunchMode.externalApplication);
  }
}

class _ErrorContent extends StatelessWidget {
  final String message;

  const _ErrorContent({required this.message});

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Icon(
          Icons.error_outline,
          size: 18,
          color: Theme.of(context).colorScheme.error,
        ),
        const SizedBox(width: 8),
        Flexible(
          child: Text(
            message,
            style: TextStyle(color: Theme.of(context).colorScheme.error),
          ),
        ),
      ],
    );
  }
}
