import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http;
import 'package:pdfx/pdfx.dart';
import 'package:universal_platform/universal_platform.dart';

import '../services/api/api_config.dart';
import '../services/user_service.dart';

/// Tons **turquoise / menthe** (charte : `#8AD0C8`) — plus doux que le vert
/// Material « gazon ».
abstract final class _ModaleCouleur {
  static const Color turquoise = Color(0xFF8AD0C8);
  static const Color turquoiseFonce = Color(0xFF5A9D94);
  static const Color mentheTresClair = Color(0xFFF3FAF8);
  static const Color mentheClair = Color(0xFFE2F3EF);
  static const Color ivoire = Color(0xFFFFFEF9);
  static const Color encre = Color(0xFF2F2F2F);
}

enum LegalDocType {
  cgu,
  privacy,
}

class CguPrivacyValidationDialog extends StatefulWidget {
  const CguPrivacyValidationDialog({super.key});

  @override
  State<CguPrivacyValidationDialog> createState() =>
      _CguPrivacyValidationDialogState();
}

class _CguPrivacyValidationDialogState extends State<CguPrivacyValidationDialog> {
  bool _loadingLegalDocs = false;
  DocumentActifInfo? _cguDoc;
  DocumentActifInfo? _privacyDoc;
  LegalDocType _selectedDocType = LegalDocType.cgu;

  static const double _cornerRadius = 16;

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

  Future<void> _loadActiveLegalDocs() async {
    setState(() => _loadingLegalDocs = true);
    try {
      final docs = await UserService.getDocumentsLegauxActifs();
      if (!mounted) return;
      setState(() {
        _cguDoc = docs.cgu;
        _privacyDoc = docs.privacy;
      });
    } catch (_) {
      // Silencieux : message dans la zone PDF si besoin.
    } finally {
      if (mounted) setState(() => _loadingLegalDocs = false);
    }
  }

  /// Sur le web, [PdfDocument.openFile] n’est pas implémenté : on charge les
  /// octets puis [PdfDocument.openData].
  Future<Uint8List> _fetchPdfBytes(String pathOrUrl) async {
    final absolute = ApiConfig.absoluteMediaUrl(pathOrUrl);
    final response = await http.get(Uri.parse(absolute));
    if (response.statusCode != 200) {
      throw StateError('PDF indisponible (HTTP ${response.statusCode})');
    }
    return response.bodyBytes;
  }

  Future<PdfDocument>? get _currentPdfDocumentFuture {
    switch (_selectedDocType) {
      case LegalDocType.cgu:
        if (_cguDoc == null) return null;
        return PdfDocument.openData(_fetchPdfBytes(_cguDoc!.url));
      case LegalDocType.privacy:
        if (_privacyDoc == null) return null;
        return PdfDocument.openData(_fetchPdfBytes(_privacyDoc!.url));
    }
  }

  String get _dialogTitle {
    switch (_selectedDocType) {
      case LegalDocType.cgu:
        return 'Conditions Générales d’Utilisation';
      case LegalDocType.privacy:
        return 'Politique de Confidentialité';
    }
  }

  bool get _canValidate {
    return (_cguDoc != null && _privacyDoc != null) ||
        (_cguDoc != null &&
            _privacyDoc == null &&
            _selectedDocType == LegalDocType.cgu) ||
        (_privacyDoc != null &&
            _cguDoc == null &&
            _selectedDocType == LegalDocType.privacy);
  }

  /// [PdfViewPinch] n’est pas supporté sur Windows (pdfx) : repli [PdfView].
  Widget _buildPdfBody() {
    final doc = _currentPdfDocumentFuture!;
    final key = ValueKey(_selectedDocType);
    if (UniversalPlatform.isWindows) {
      return PdfView(
        key: key,
        scrollDirection: Axis.vertical,
        controller: PdfController(document: doc),
        backgroundDecoration: const BoxDecoration(color: Colors.white),
      );
    }
    return _PdfPaneWithScrollbar(
      key: key,
      documentFuture: doc,
    );
  }

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.sizeOf(context);
    final dialogW = size.width * 0.92;
    final dialogH = size.height * 0.88;

    return Dialog(
      insetPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 20),
      backgroundColor: Colors.transparent,
      elevation: 0,
      child: ClipRRect(
        borderRadius: BorderRadius.circular(_cornerRadius),
        child: Material(
          color: _ModaleCouleur.ivoire,
          elevation: 6,
          shadowColor: _ModaleCouleur.encre.withOpacity(0.12),
          child: SizedBox(
            width: dialogW,
            height: dialogH,
            child: Column(
              children: [
                _buildHeader(context),
                Padding(
                  padding: const EdgeInsets.fromLTRB(12, 8, 12, 4),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      _tabButton(
                        context,
                        label: 'CGU',
                        selected: _selectedDocType == LegalDocType.cgu,
                        enabled: !_loadingLegalDocs && _cguDoc != null,
                        onTap: () => setState(
                          () => _selectedDocType = LegalDocType.cgu,
                        ),
                      ),
                      const SizedBox(width: 10),
                      _tabButton(
                        context,
                        label: 'Confidentialité',
                        selected: _selectedDocType == LegalDocType.privacy,
                        enabled: !_loadingLegalDocs && _privacyDoc != null,
                        onTap: () => setState(
                          () => _selectedDocType = LegalDocType.privacy,
                        ),
                      ),
                    ],
                  ),
                ),
                Expanded(
                  child: Padding(
                    padding: const EdgeInsets.fromLTRB(12, 4, 12, 8),
                    child: DecoratedBox(
                      decoration: BoxDecoration(
                        color: Colors.white,
                        borderRadius: BorderRadius.circular(12),
                        border: Border.all(
                          color: _ModaleCouleur.turquoiseFonce.withOpacity(0.35),
                        ),
                      ),
                      child: ClipRRect(
                        borderRadius: BorderRadius.circular(12),
                        child: _loadingLegalDocs
                            ? const Center(
                                child: CircularProgressIndicator(
                                  color: _ModaleCouleur.turquoiseFonce,
                                  strokeWidth: 3,
                                ),
                              )
                            : _currentPdfDocumentFuture != null
                                ? _buildPdfBody()
                                : Center(
                                    child: Text(
                                      'Document non disponible.',
                                      style: GoogleFonts.merienda(
                                        color: _ModaleCouleur.encre
                                            .withOpacity(0.75),
                                      ),
                                    ),
                                  ),
                      ),
                    ),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
                  child: Center(
                    child: ConstrainedBox(
                      constraints: const BoxConstraints(maxWidth: 520),
                      child: FilledButton(
                        onPressed: _canValidate
                            ? () => Navigator.of(context).pop(true)
                            : null,
                        style: FilledButton.styleFrom(
                          backgroundColor: _ModaleCouleur.turquoiseFonce,
                          foregroundColor: Colors.white,
                          disabledBackgroundColor:
                              _ModaleCouleur.mentheClair.withOpacity(0.7),
                          disabledForegroundColor:
                              _ModaleCouleur.encre.withOpacity(0.45),
                          padding: const EdgeInsets.symmetric(
                            horizontal: 20,
                            vertical: 14,
                          ),
                        ),
                        child: Text(
                          'Valider les CGU et la Politique '
                          'de Confidentialité',
                          textAlign: TextAlign.center,
                          style: GoogleFonts.merienda(
                            fontSize: 14,
                            fontWeight: FontWeight.w600,
                          ),
                        ),
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildHeader(BuildContext context) {
    return DecoratedBox(
      decoration: const BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
          colors: [
            _ModaleCouleur.mentheTresClair,
            _ModaleCouleur.mentheClair,
          ],
        ),
      ),
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2),
        child: Row(
          children: [
            Expanded(
              child: Padding(
                padding: const EdgeInsets.only(left: 8),
                child: Text(
                  _dialogTitle,
                  style: GoogleFonts.merienda(
                    fontSize: 17,
                    fontWeight: FontWeight.w600,
                    color: _ModaleCouleur.encre,
                    height: 1.25,
                  ),
                  maxLines: 2,
                  overflow: TextOverflow.ellipsis,
                ),
              ),
            ),
            IconButton(
              tooltip: 'Fermer',
              icon: Icon(
                Icons.close,
                color: _ModaleCouleur.encre.withOpacity(0.55),
              ),
              onPressed: () => Navigator.of(context).pop(false),
            ),
          ],
        ),
      ),
    );
  }

  Widget _tabButton(
    BuildContext context, {
    required String label,
    required bool selected,
    required bool enabled,
    required VoidCallback onTap,
  }) {
    return OutlinedButton(
      onPressed: enabled ? onTap : null,
      style: OutlinedButton.styleFrom(
        foregroundColor: _ModaleCouleur.encre,
        backgroundColor: selected
            ? _ModaleCouleur.turquoise
            : _ModaleCouleur.mentheTresClair,
        side: BorderSide(
          color: _ModaleCouleur.turquoiseFonce.withOpacity(0.55),
          width: 1.5,
        ),
        padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 10),
      ),
      child: Text(
        label,
        style: GoogleFonts.merienda(
          fontSize: 13,
          fontWeight: selected ? FontWeight.w600 : FontWeight.w500,
        ),
      ),
    );
  }
}

/// [PdfViewPinch] pour le web / mobile avec `pdfx` 2.6 (pas de
/// `documentProgress` / `minScale` dans cette API).
class _PdfPaneWithScrollbar extends StatefulWidget {
  const _PdfPaneWithScrollbar({
    super.key,
    required this.documentFuture,
  });

  final Future<PdfDocument> documentFuture;

  @override
  State<_PdfPaneWithScrollbar> createState() => _PdfPaneWithScrollbarState();
}

class _PdfPaneWithScrollbarState extends State<_PdfPaneWithScrollbar> {
  late final PdfControllerPinch _ctrl;

  @override
  void initState() {
    super.initState();
    _ctrl = PdfControllerPinch(document: widget.documentFuture);
  }

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

  @override
  Widget build(BuildContext context) {
    return PdfViewPinch(
      padding: 10,
      scrollDirection: Axis.vertical,
      controller: _ctrl,
      backgroundDecoration: const BoxDecoration(color: Colors.white),
    );
  }
}
