import 'dart:io';
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:mobile_scanner/mobile_scanner.dart';

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

  @override
  State<ScanQRPage> createState() => _ScanQRPageState();
}

class _ScanQRPageState extends State<ScanQRPage> {
  MobileScannerController? cameraController;
  bool _isScanComplete = false;
  String? _scannedData;
  bool _hasError = false;
  String? _errorMessage;
  bool get isMobile => !kIsWeb && (Platform.isAndroid || Platform.isIOS);
  @override
  void initState() {
    super.initState();
    _initializeController();
  }

  void _initializeController() {
    if (!isMobile) {
      setState(() {
        _hasError = true;
        _errorMessage =
            "Le scanner QR n'est pas disponible sur cette plateforme.";
      });
      return;
    }
    try {
      cameraController = MobileScannerController(
        detectionSpeed: DetectionSpeed.noDuplicates,
        facing: CameraFacing.back,
        torchEnabled: false,
      );
      setState(() {
        _hasError = false;
        _errorMessage = null;
      });
    } catch (e) {
      setState(() {
        _hasError = true;
        _errorMessage = 'Erreur d\'initialisation de la caméra: $e';
      });
    }
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Scanner QR Code'),
        actions: _hasError
            ? []
            : [
                if (cameraController != null) ...[
                  IconButton(
                    color: Colors.white,
                    icon: const Icon(Icons.flash_on, color: Colors.white),
                    iconSize: 32.0,
                    onPressed: () => cameraController!.toggleTorch(),
                  ),
                  IconButton(
                    color: Colors.white,
                    icon:
                        const Icon(Icons.flip_camera_ios, color: Colors.white),
                    iconSize: 32.0,
                    onPressed: () => cameraController!.switchCamera(),
                  ),
                ],
              ],
      ),
      body: _hasError ? _buildErrorWidget() : _buildScannerWidget(),
    );
  }

  Widget _buildErrorWidget() {
    return Center(
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Icon(
              Icons.error_outline,
              size: 64,
              color: Colors.red,
            ),
            const SizedBox(height: 16),
            const Text(
              'Erreur de caméra',
              style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 8),
            Text(
              _errorMessage ?? 'Une erreur s\'est produite',
              textAlign: TextAlign.center,
              style: const TextStyle(fontSize: 16),
            ),
            const SizedBox(height: 24),
            ElevatedButton(
              onPressed: () {
                _initializeController();
              },
              child: const Text('Réessayer'),
            ),
            const SizedBox(height: 16),
            const Text(
              'Vérifiez que:\n• Le plugin mobile_scanner est installé\n• Les permissions de caméra sont accordées\n• Votre appareil a une caméra fonctionnelle',
              textAlign: TextAlign.center,
              style: TextStyle(fontSize: 14, color: Colors.grey),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildScannerWidget() {
    if (cameraController == null) {
      return const Center(child: CircularProgressIndicator());
    }

    return Stack(
      children: [
        MobileScanner(
          controller: cameraController!,
          onDetect: (capture) {
            final List<Barcode> barcodes = capture.barcodes;
            for (final barcode in barcodes) {
              if (!_isScanComplete && barcode.rawValue != null) {
                _isScanComplete = true;
                _scannedData = barcode.rawValue;
                _showScanResult(context, _scannedData!);
              }
            }
          },
          errorBuilder: (context, error) {
            return Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  const Icon(Icons.error, size: 64, color: Colors.red),
                  const SizedBox(height: 16),
                  Text(
                    'Erreur: ${error.errorDetails?.message ?? 'Erreur inconnue'}',
                  ),
                  const SizedBox(height: 16),
                  ElevatedButton(
                    onPressed: () => _initializeController(),
                    child: const Text('Réessayer'),
                  ),
                ],
              ),
            );
          },
        ),
        CustomPaint(
          painter: QrScannerOverlay(
            borderColor: Colors.blue.shade800,
          ),
        ),
      ],
    );
  }

  void _showScanResult(BuildContext context, String data) {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('Résultat du scan'),
        content: SelectableText(data), // Permet de sélectionner le texte
        actions: [
          TextButton(
            onPressed: () {
              Navigator.pop(context);
              setState(() {
                _isScanComplete = false;
              });
            },
            child: const Text('Fermer'),
          ),
          TextButton(
            onPressed: () {
              Navigator.pop(context);
              Navigator.pop(context, data); // Retourner la donnée scannée
            },
            child: const Text('Utiliser'),
          ),
        ],
      ),
    ).then((_) {
      setState(() {
        _isScanComplete = false;
      });
    });
  }
}

class QrScannerOverlay extends CustomPainter {
  final Color borderColor;

  QrScannerOverlay({required this.borderColor});

  @override
  void paint(Canvas canvas, Size size) {
    final double width = size.width;
    final double height = size.height;
    final double borderWidth = 2.0;
    final double borderLength = 30.0;
    final double areaSize = width * 0.7;

    final Paint backgroundPaint = Paint()
      ..color = Colors.black.withOpacity(0.4);
    canvas.drawRect(Rect.fromLTRB(0, 0, width, height), backgroundPaint);

    final Paint transparentPaint = Paint()
      ..color = Colors.transparent
      ..blendMode = BlendMode.clear;
    final double areaLeft = (width - areaSize) / 2;
    final double areaTop = (height - areaSize) / 2;
    canvas.drawRect(
      Rect.fromLTRB(areaLeft, areaTop, areaLeft + areaSize, areaTop + areaSize),
      transparentPaint,
    );

    final Paint borderPaint = Paint()
      ..color = borderColor
      ..strokeWidth = borderWidth
      ..style = PaintingStyle.stroke;

    // Coins du scanner
    _drawCorner(
        canvas, borderPaint, areaLeft, areaTop, borderLength, true, true);
    _drawCorner(canvas, borderPaint, areaLeft + areaSize, areaTop, borderLength,
        false, true);
    _drawCorner(canvas, borderPaint, areaLeft, areaTop + areaSize, borderLength,
        true, false);
    _drawCorner(canvas, borderPaint, areaLeft + areaSize, areaTop + areaSize,
        borderLength, false, false);
  }

  void _drawCorner(Canvas canvas, Paint paint, double x, double y,
      double length, bool isLeft, bool isTop) {
    final double horizontalStart = isLeft ? x : x - length;
    final double horizontalEnd = isLeft ? x + length : x;
    final double verticalStart = isTop ? y : y - length;
    final double verticalEnd = isTop ? y + length : y;

    canvas.drawLine(
        Offset(horizontalStart, y), Offset(horizontalEnd, y), paint);
    canvas.drawLine(Offset(x, verticalStart), Offset(x, verticalEnd), paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}
