import 'dart:io';
import 'package:flutter/material.dart';
import '../../../../app/i18n/app_localizations.dart';
import '../../../../app/theme/app_colors.dart';
import '../version_checker.dart';
import '../download_manager.dart';
import '../apk_installer.dart';
import '../app_market_detector.dart';
import '../models/version_info.dart';

/// 自建服务器更新器
class SelfHostedUpdater {
  final VersionChecker versionChecker;
  final DownloadManager downloadManager;

  SelfHostedUpdater({required String apiBaseUrl})
      : versionChecker = VersionChecker(apiBaseUrl: apiBaseUrl),
        downloadManager = DownloadManager();

  Future<void> checkAndPromptUpdate(BuildContext context) async {
    final versionInfo = await versionChecker.checkForUpdate();
    if (versionInfo == null) return;
    if (!context.mounted) return;

    final isFromMarket = await AppMarketDetector.isFromAppMarket();
    if (isFromMarket) {
      _showMarketUpdateDialog(context, versionInfo);
    } else {
      _showSelfHostedUpdateDialog(context, versionInfo);
    }
  }

  Future<VersionInfo?> silentCheckUpdate() async {
    return await versionChecker.checkForUpdate();
  }

  void _showMarketUpdateDialog(BuildContext context, VersionInfo versionInfo) {
    showDialog(
      context: context,
      barrierDismissible: !versionInfo.forceUpdate,
      builder: (context) => PopScope(
        canPop: !versionInfo.forceUpdate,
        child: AlertDialog(
          title: Text(
            versionInfo.forceUpdate
                ? context.t('update.importantUpdate')
                : context.t('update.newVersion'),
            style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
          ),
          content: SingleChildScrollView(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  '${context.t('update.latestVersion')}: ${versionInfo.version}',
                  style: TextStyle(fontSize: 14, color: Colors.grey[700]),
                ),
                if (versionInfo.updateLog != null) ...[
                  const SizedBox(height: 16),
                  Text(
                    '${context.t('update.changelog')}:',
                    style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w600),
                  ),
                  const SizedBox(height: 8),
                  Text(
                    versionInfo.updateLog!,
                    style: TextStyle(fontSize: 14, color: Colors.grey[700]),
                  ),
                ],
                const SizedBox(height: 16),
                Text(
                  context.t('update.marketHint'),
                  style: TextStyle(fontSize: 12, color: Colors.grey[400]),
                ),
              ],
            ),
          ),
          actions: [
            if (!versionInfo.forceUpdate)
              TextButton(
                onPressed: () => Navigator.pop(context),
                child: Text(
                  context.t('update.later'),
                  style: TextStyle(fontSize: 14, color: Colors.grey[600]),
                ),
              ),
            ElevatedButton(
              onPressed: () async {
                Navigator.pop(context);
                final packageInfo = await versionChecker.getCurrentVersion();
                await AppMarketDetector.openAppMarketDetail(packageInfo.packageName);
              },
              style: ElevatedButton.styleFrom(
                backgroundColor: AppColors.primary,
                foregroundColor: Colors.white,
              ),
              child: Text(context.t('update.goMarket'), style: const TextStyle(fontSize: 14)),
            ),
          ],
        ),
      ),
    );
  }

  void _showSelfHostedUpdateDialog(BuildContext context, VersionInfo versionInfo) {
    showDialog(
      context: context,
      barrierDismissible: !versionInfo.forceUpdate,
      builder: (context) => PopScope(
        canPop: !versionInfo.forceUpdate,
        child: AlertDialog(
          title: Text(
            versionInfo.forceUpdate
                ? context.t('update.importantUpdate')
                : context.t('update.newVersion'),
            style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
          ),
          content: SingleChildScrollView(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  '${context.t('update.latestVersion')}: ${versionInfo.version}',
                  style: TextStyle(fontSize: 14, color: Colors.grey[700]),
                ),
                const SizedBox(height: 8),
                Text(
                  '${context.t('update.fileSize')}: ${versionInfo.fileSizeFriendly}',
                  style: TextStyle(fontSize: 14, color: Colors.grey[700]),
                ),
                if (versionInfo.updateLog != null) ...[
                  const SizedBox(height: 16),
                  Text(
                    '${context.t('update.changelog')}:',
                    style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w600),
                  ),
                  const SizedBox(height: 8),
                  Text(
                    versionInfo.updateLog!,
                    style: TextStyle(fontSize: 14, color: Colors.grey[700]),
                  ),
                ],
              ],
            ),
          ),
          actions: [
            if (!versionInfo.forceUpdate)
              TextButton(
                onPressed: () => Navigator.pop(context),
                child: Text(
                  context.t('update.skipUpdate'),
                  style: TextStyle(fontSize: 14, color: Colors.grey[600]),
                ),
              ),
            ElevatedButton(
              onPressed: () {
                Navigator.pop(context);
                _startUpdate(context, versionInfo);
              },
              style: ElevatedButton.styleFrom(
                backgroundColor: AppColors.primary,
                foregroundColor: Colors.white,
              ),
              child: Text(context.t('update.updateNow'), style: const TextStyle(fontSize: 14)),
            ),
          ],
        ),
      ),
    );
  }

  Future<void> _startUpdate(BuildContext context, VersionInfo versionInfo) async {
    if (!context.mounted) return;
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) => _DownloadProgressDialog(
        versionInfo: versionInfo,
        downloadManager: downloadManager,
        forceUpdate: versionInfo.forceUpdate,
      ),
    );
  }

  Future<void> cleanup() async {
    await downloadManager.cleanupDownloadedApk();
  }
}

/// 下载进度对话框
class _DownloadProgressDialog extends StatefulWidget {
  final VersionInfo versionInfo;
  final DownloadManager downloadManager;
  final bool forceUpdate;

  const _DownloadProgressDialog({
    required this.versionInfo,
    required this.downloadManager,
    required this.forceUpdate,
  });

  @override
  State<_DownloadProgressDialog> createState() => _DownloadProgressDialogState();
}

class _DownloadProgressDialogState extends State<_DownloadProgressDialog> {
  double _progress = 0.0;
  String _statusText = '';
  bool _isDownloading = true;
  bool _hasError = false;
  bool _downloadCompleted = false;
  File? _downloadedApkFile;

  @override
  void initState() {
    super.initState();
    _startDownload();
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    if (_statusText.isEmpty) {
      _statusText = context.t('update.preparing');
    }
  }

  Future<void> _startDownload() async {
    if (mounted) {
      setState(() {
        _statusText = context.t('update.downloading');
        _isDownloading = true;
        _hasError = false;
        _downloadCompleted = false;
      });
    }

    final apkFile = await widget.downloadManager.downloadApk(
      url: widget.versionInfo.downloadUrl,
      sha256Expected: widget.versionInfo.sha256,
      onProgress: (received, total) {
        if (mounted) {
          setState(() {
            _progress = received / total;
            final receivedMB = (received / 1024 / 1024).toStringAsFixed(1);
            final totalMB = (total / 1024 / 1024).toStringAsFixed(1);
            _statusText = '${context.t('update.downloading')} $receivedMB MB / $totalMB MB';
          });
        }
      },
    );

    if (!mounted) return;

    if (apkFile == null) {
      setState(() {
        _statusText = widget.downloadManager.status == DownloadStatus.cancelled
            ? context.t('update.cancelled')
            : context.t('update.failed');
        _isDownloading = false;
        _hasError = true;
      });
      return;
    }

    _downloadedApkFile = apkFile;

    if (widget.forceUpdate) {
      setState(() => _statusText = context.t('update.installing'));
      await Future.delayed(const Duration(milliseconds: 500));
      await _installApk();
    } else {
      setState(() {
        _statusText = context.t('update.downloadComplete');
        _isDownloading = false;
        _downloadCompleted = true;
      });
    }
  }

  Future<void> _installApk() async {
    if (_downloadedApkFile == null) return;

    setState(() {
      _statusText = context.t('update.installing');
      _isDownloading = true;
    });

    final installed = await ApkInstaller.installApk(_downloadedApkFile!);

    if (!mounted) return;

    if (installed) {
      Navigator.pop(context);
    } else {
      setState(() {
        _statusText = context.t('update.installFailed');
        _isDownloading = false;
        _hasError = true;
      });
    }
  }

  void _cancelDownload() {
    widget.downloadManager.cancelDownload();
  }

  void _retryDownload() {
    widget.downloadManager.reset();
    _startDownload();
  }

  @override
  Widget build(BuildContext context) {
    String title;
    if (_downloadCompleted && !_hasError) {
      title = context.t('update.downloadComplete');
    } else if (_hasError) {
      title = context.t('update.updateFailed');
    } else {
      title = context.t('update.updating');
    }

    return PopScope(
      canPop: !_isDownloading && !widget.forceUpdate,
      child: AlertDialog(
        title: Text(
          title,
          style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
        ),
        content: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            LinearProgressIndicator(
              value: _progress,
              backgroundColor: Colors.grey[200],
              valueColor: AlwaysStoppedAnimation<Color>(
                _hasError ? Colors.red : AppColors.primary,
              ),
            ),
            const SizedBox(height: 16),
            Text(
              _statusText,
              style: TextStyle(
                fontSize: 14,
                color: _hasError ? Colors.red : Colors.grey[700],
              ),
            ),
            if (_isDownloading) ...[
              const SizedBox(height: 8),
              Text(
                '${(_progress * 100).toStringAsFixed(0)}%',
                style: const TextStyle(
                  fontSize: 24,
                  fontWeight: FontWeight.w700,
                  color: AppColors.primary,
                ),
              ),
            ],
          ],
        ),
        actions: [
          if (_isDownloading)
            TextButton(
              onPressed: _cancelDownload,
              child: Text(
                context.t('update.cancel'),
                style: TextStyle(fontSize: 14, color: Colors.grey[600]),
              ),
            ),
          if (!_isDownloading && _hasError) ...[
            TextButton(
              onPressed: () => Navigator.pop(context),
              child: Text(
                context.t('update.close'),
                style: TextStyle(fontSize: 14, color: Colors.grey[600]),
              ),
            ),
            ElevatedButton(
              onPressed: _retryDownload,
              style: ElevatedButton.styleFrom(
                backgroundColor: AppColors.primary,
                foregroundColor: Colors.white,
              ),
              child: Text(context.t('update.retry'), style: const TextStyle(fontSize: 14)),
            ),
          ],
          if (_downloadCompleted && !_hasError) ...[
            TextButton(
              onPressed: () => Navigator.pop(context),
              child: Text(
                context.t('update.installLater'),
                style: TextStyle(fontSize: 14, color: Colors.grey[600]),
              ),
            ),
            ElevatedButton(
              onPressed: _installApk,
              style: ElevatedButton.styleFrom(
                backgroundColor: AppColors.primary,
                foregroundColor: Colors.white,
              ),
              child: Text(context.t('update.installNow'), style: const TextStyle(fontSize: 14)),
            ),
          ],
        ],
      ),
    );
  }
}
