import 'dart:convert';
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart' as desktop;
import 'package:webview_flutter/webview_flutter.dart' as mobile;

bool get _useDesktopWebView =>
    !kIsWeb && (Platform.isWindows || Platform.isLinux);

class AnnouncementDialog extends StatefulWidget {
  final String title;
  final String html;
  final String baseUrl;

  const AnnouncementDialog({
    super.key,
    required this.title,
    required this.html,
    required this.baseUrl,
  });

  static Future<void> show(
    BuildContext context, {
    required String title,
    required String html,
    required String baseUrl,
  }) async {
    if (html.trim().isEmpty) return;

    await showDialog<void>(
      context: context,
      barrierDismissible: true,
      builder: (_) =>
          AnnouncementDialog(title: title, html: html, baseUrl: baseUrl),
    );
  }

  @override
  State<AnnouncementDialog> createState() => _AnnouncementDialogState();
}

class _AnnouncementDialogState extends State<AnnouncementDialog> {
  mobile.WebViewController? _mobileController;
  desktop.InAppWebViewController? _desktopController;
  late final String _html;
  late final String _baseUrl;
  bool _loading = true;

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

    final origin = Uri.parse(widget.baseUrl).origin;
    _html = _wrapHtml(widget.html);
    _baseUrl = '$origin/';

    if (!_useDesktopWebView) {
      _mobileController = mobile.WebViewController()
        ..setJavaScriptMode(mobile.JavaScriptMode.unrestricted)
        ..setBackgroundColor(Colors.transparent)
        ..setNavigationDelegate(
          mobile.NavigationDelegate(
            onPageFinished: (_) {
              if (mounted) setState(() => _loading = false);
            },
          ),
        )
        ..loadHtmlString(_html, baseUrl: _baseUrl);
    }
  }

  @override
  void dispose() {
    _desktopController?.dispose();
    super.dispose();
  }

  String _wrapHtml(String body) {
    final encodedTitle = const HtmlEscape().convert(widget.title);

    return '''
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>$encodedTitle</title>
<style>
  html, body {
    margin: 0;
    padding: 0;
    background: transparent;
    color: #1f2937;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans SC", sans-serif;
    font-size: 14px;
    line-height: 1.65;
    overflow-wrap: anywhere;
  }
  body {
    padding: 12px 14px 18px;
    box-sizing: border-box;
  }
  img, video {
    max-width: 100% !important;
    height: auto !important;
    border-radius: 12px;
  }
  a {
    color: #2563eb;
    text-decoration: none;
  }
  fieldset, section, div {
    max-width: 100% !important;
    box-sizing: border-box !important;
  }
</style>
</head>
<body>
$body
</body>
</html>
''';
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);

    return Dialog(
      insetPadding: const EdgeInsets.symmetric(horizontal: 18, vertical: 28),
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(22)),
      child: ClipRRect(
        borderRadius: BorderRadius.circular(22),
        child: SizedBox(
          width: double.infinity,
          height: MediaQuery.of(context).size.height * 0.72,
          child: Column(
            children: [
              Container(
                padding: const EdgeInsets.fromLTRB(18, 14, 8, 10),
                decoration: BoxDecoration(
                  color: theme.colorScheme.surface,
                  border: Border(
                    bottom: BorderSide(
                      color: theme.dividerColor.withValues(alpha: 0.45),
                    ),
                  ),
                ),
                child: Row(
                  children: [
                    Expanded(
                      child: Text(
                        widget.title,
                        style: theme.textTheme.titleMedium?.copyWith(
                          fontWeight: FontWeight.w800,
                        ),
                      ),
                    ),
                    IconButton(
                      tooltip: '关闭',
                      onPressed: () => Navigator.of(context).pop(),
                      icon: const Icon(Icons.close),
                    ),
                  ],
                ),
              ),
              Expanded(
                child: Stack(
                  children: [
                    _buildWebView(),
                    if (_loading)
                      const Center(child: CircularProgressIndicator()),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildWebView() {
    if (_useDesktopWebView) {
      return desktop.InAppWebView(
        initialData: desktop.InAppWebViewInitialData(
          data: _html,
          baseUrl: desktop.WebUri(_baseUrl),
        ),
        initialSettings: desktop.InAppWebViewSettings(
          javaScriptEnabled: true,
          domStorageEnabled: true,
          transparentBackground: true,
          supportZoom: false,
        ),
        onWebViewCreated: (controller) {
          _desktopController = controller;
        },
        onLoadStop: (_, url) {
          if (mounted) setState(() => _loading = false);
        },
      );
    }

    return mobile.WebViewWidget(controller: _mobileController!);
  }
}
