/// Outil de calibration de la cible.
///
/// Permet l'ajustement interactif du centre et du rayon global.
/// Les anneaux sont répartis proportionnellement.
library;

import 'dart:math' as math;
import 'package:flutter/material.dart';
import '../../../core/theme/app_theme.dart';
import '../../../data/models/target_type.dart';

class TargetCalibration extends StatefulWidget {
  final double initialCenterX;
  final double initialCenterY;
  final double initialRadius;
  final double initialInnerRadius;
  final int initialRingCount;
  final TargetType targetType;
  final List<double>? initialRingRadii;
  final Function(
      double centerX,
      double centerY,
      double innerRadius,
      double radius,
      int ringCount, {
      List<double>? ringRadii,
      })
  onCalibrationChanged;

  const TargetCalibration({
    super.key,
    required this.initialCenterX,
    required this.initialCenterY,
    required this.initialRadius,
    required this.initialInnerRadius,
    this.initialRingCount = 10,
    required this.targetType,
    this.initialRingRadii,
    required this.onCalibrationChanged,
  });

  @override
  State<TargetCalibration> createState() => TargetCalibrationState();
}

class TargetCalibrationState extends State<TargetCalibration> {
  late double _centerX;
  late double _centerY;
  late double _radius;
  late double _innerRadius;
  late int _ringCount;
  late List<double> _ringRadii;

  // Variable dédiée pour piloter la jauge orange sans conflit
  late double _currentEspacementRatio;

  bool _isDraggingCenter = false;
  bool _isDraggingRadius = false;
  bool _isDraggingInnerRadius = false;

  bool _showEspacement = false;
  double _baseRadiusBeforeScale = 1.0;

  // SAUVEGARDE CRITIQUE : Pour mémoriser la structure d'origine de l'IA
  List<double>? _originalRingRadii;

  @override
  void initState() {
    super.initState();
    _centerX = widget.initialCenterX;
    _centerY = widget.initialCenterY;
    _radius = widget.initialRadius;
    _innerRadius = widget.initialInnerRadius;
    _ringCount = widget.initialRingCount;

    // On mémorise la configuration d'usine de l'image
    if (widget.initialRingRadii != null) {
      _originalRingRadii = List.from(widget.initialRingRadii!);
    }

    // Initialisation du ratio par défaut
    _currentEspacementRatio = (_radius > 0) ? (_innerRadius / _radius).clamp(0.01, 0.70) : 0.1;
    _initRingRadii();
  }

  /// Fige et propage la calibration courante vers le provider.
  ///
  /// Appelée par l'écran d'analyse (via GlobalKey) juste avant de basculer
  /// dans l'instance de Plotting, pour garantir que l'état affiché en Plotting
  /// correspond exactement au dernier réglage validé, sans dépendre d'un
  /// éventuel rebuild intermédiaire.
  void commitCalibration() {
    _notifyChange();
  }

  void _initRingRadii({bool forceRecalculate = false}) {
    // CORRECTION : Si on ne recalcule pas activement l'espacement linéaire, on préserve en priorité la structure d'origine
    if (!forceRecalculate && _originalRingRadii != null && _originalRingRadii!.length == _ringCount) {
      _ringRadii = List.from(_originalRingRadii!);
    } else if (!forceRecalculate && widget.initialRingRadii != null && widget.initialRingRadii!.length == _ringCount) {
      _ringRadii = List.from(widget.initialRingRadii!);
    } else {
      _ringRadii = List.generate(_ringCount, (i) {
        if (_ringCount <= 1) return 1.0;
        return _currentEspacementRatio + (1.0 - _currentEspacementRatio) * i / (_ringCount - 1);
      });
    }
  }

  @override
  void didUpdateWidget(TargetCalibration oldWidget) {
    super.didUpdateWidget(oldWidget);
    bool shouldReinit = false;

    if (widget.initialCenterX != oldWidget.initialCenterX && !_isDraggingCenter) {
      _centerX = widget.initialCenterX;
    }
    if (widget.initialCenterY != oldWidget.initialCenterY && !_isDraggingCenter) {
      _centerY = widget.initialCenterY;
    }
    if (widget.initialRingCount != oldWidget.initialRingCount) {
      _ringCount = widget.initialRingCount;
      shouldReinit = true;
    }
    if (widget.initialRadius != oldWidget.initialRadius && !_isDraggingRadius) {
      _radius = widget.initialRadius;
      shouldReinit = true;
    }
    if (widget.initialInnerRadius != oldWidget.initialInnerRadius && !_isDraggingInnerRadius) {
      _innerRadius = widget.initialInnerRadius;
      _currentEspacementRatio = (_radius > 0) ? (_innerRadius / _radius).clamp(0.01, 0.70) : 0.1;
      shouldReinit = true;
    }
    if (widget.initialRingRadii != oldWidget.initialRingRadii && widget.initialRingRadii != null) {
      _originalRingRadii = List.from(widget.initialRingRadii!);
      shouldReinit = true;
    }

    if (shouldReinit) {
      _initRingRadii();
    }
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        final size = constraints.biggest;

        return Stack(
          children: [
            GestureDetector(
              onScaleStart: (details) {
                _baseRadiusBeforeScale = _radius;
                final tapX = details.localFocalPoint.dx / size.width;
                final tapY = details.localFocalPoint.dy / size.height;
                final distToCenter = _distance(tapX, tapY, _centerX, _centerY);

                if (distToCenter < 0.05 || distToCenter < _radius + 0.02) {
                  setState(() {
                    _isDraggingCenter = true;
                  });
                }
              },
              onScaleUpdate: (details) => _onScaleUpdate(details, size),
              onScaleEnd: (_) => _onScaleEnd(),
              child: CustomPaint(
                size: size,
                painter: _CalibrationPainter(
                  centerX: _centerX,
                  centerY: _centerY,
                  radius: _radius,
                  innerRadius: _innerRadius,
                  ringCount: _ringCount,
                  ringRadii: _ringRadii,
                  targetType: widget.targetType,
                  isDraggingCenter: _isDraggingCenter,
                  isDraggingRadius: false,
                  isDraggingInnerRadius: false,
                ),
              ),
            ),

            Positioned(
              top: 10,
              left: 40,
              right: 40,
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  Container(
                    margin: const EdgeInsets.only(bottom: 8),
                    padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 2),
                    decoration: BoxDecoration(
                      color: Colors.black54,
                      borderRadius: BorderRadius.circular(20),
                    ),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        const Text(
                          'Options d\'espacement avancées',
                          style: TextStyle(color: Colors.white70, fontSize: 11, fontWeight: FontWeight.w500),
                        ),
                        SizedBox(
                          height: 28,
                          child: Switch(
                            value: _showEspacement,
                            activeThumbColor: const Color(0xFF00FF00),
                            onChanged: (bool value) {
                              setState(() {
                                _showEspacement = value;
                                // Quand on désactive l'espacement manuel, on restaure la configuration d'usine !
                                if (!value) {
                                  _initRingRadii(forceRecalculate: false);
                                }
                              });
                              _notifyChange();
                            },
                          ),
                        ),
                      ],
                    ),
                  ),

                  // Slider pour la taille (toujours visible)
                  Container(
                    padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
                    decoration: BoxDecoration(
                      color: Colors.black54,
                      borderRadius: BorderRadius.circular(20),
                    ),
                    child: Row(
                      children: [
                        const Text('Taille ', style: TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.bold)),
                        const Icon(Icons.zoom_out, color: Colors.white, size: 16),
                        Expanded(
                          child: Slider(
                            // SÉCURITÉ : Ouverture mesurée des bornes pour plus de liberté sans débordement incontrôlé
                            value: _radius.clamp(0.3, 0.95),
                            min: 0.3,
                            max: 0.95,
                            activeColor: AppTheme.primaryColor,
                            onChanged: (value) {
                              setState(() {
                                _radius = value;
                                _innerRadius = _radius * _currentEspacementRatio;
                                // CORRECTION : Si le mode avancé n'est pas coché, on applique la taille pure sans détruire le ratio d'origine
                                _initRingRadii(forceRecalculate: _showEspacement);
                              });
                              _notifyChange();
                            },
                          ),
                        ),
                        const Icon(Icons.zoom_in, color: Colors.white, size: 16),
                      ],
                    ),
                  ),

                  // Affichage conditionnel du slider d'espacement orange
                  if (_showEspacement) ...[
                    const SizedBox(height: 8),
                    Container(
                      padding: const EdgeInsets.fromLTRB(16, 4, 4, 4),
                      decoration: BoxDecoration(
                        color: Colors.black54,
                        borderRadius: BorderRadius.circular(20),
                      ),
                      child: Row(
                        children: [
                          const Text('Espacement ', style: TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.bold)),
                          const Icon(Icons.compress, color: Colors.white, size: 16),
                          Expanded(
                            child: Row(
                              children: [
                                Expanded(
                                  child: Slider(
                                    value: _currentEspacementRatio,
                                    min: 0.01,
                                    // SÉCURITÉ : Écartement max bridé à 0.70 pour confiner le dernier cercle
                                    max: 0.70,
                                    activeColor: Colors.orange,
                                    onChanged: (value) {
                                      setState(() {
                                        _currentEspacementRatio = value;
                                        _innerRadius = _radius * _currentEspacementRatio;
                                        _initRingRadii(forceRecalculate: true);
                                      });
                                      _notifyChange();
                                    },
                                  ),
                                ),
                                const Icon(Icons.expand, color: Colors.white, size: 16),
                              ],
                            ),
                          ),
                          // CORRECTION DU BOUTON RESET : Restaure désormais le vrai profil d'usine de l'IA
                          IconButton(
                            icon: const Icon(Icons.refresh, color: Colors.white70, size: 20),
                            onPressed: () {
                              setState(() {
                                if (_originalRingRadii != null) {
                                  _initRingRadii(forceRecalculate: false);
                                  if (_ringRadii.isNotEmpty) {
                                    _currentEspacementRatio = _ringRadii.first;
                                    _innerRadius = _radius * _currentEspacementRatio;
                                  }
                                } else {
                                  _currentEspacementRatio = 0.1;
                                  _innerRadius = _radius * _currentEspacementRatio;
                                  _initRingRadii(forceRecalculate: true);
                                }
                              });
                              _notifyChange();
                            },
                            tooltip: 'Réinitialiser l\'espacement',
                            constraints: const BoxConstraints(),
                            padding: const EdgeInsets.symmetric(horizontal: 8),
                          ),
                        ],
                      ),
                    ),
                  ],
                ],
              ),
            ),
          ],
        );
      },
    );
  }

  Widget buildDirectionalControls(BuildContext context, Size size) {
    return Container(
      padding: const EdgeInsets.all(8),
      decoration: BoxDecoration(
        color: Colors.black.withValues(alpha: 0.05),
        borderRadius: BorderRadius.circular(12),
        border: Border.all(color: Colors.white10),
      ),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          _buildDirectionButton(Icons.keyboard_arrow_up, () => _moveCenterByPixels(0, -1, size)),
          Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              _buildDirectionButton(Icons.keyboard_arrow_left, () => _moveCenterByPixels(-1, 0, size)),
              const SizedBox(width: 40),
              _buildDirectionButton(Icons.keyboard_arrow_right, () => _moveCenterByPixels(1, 0, size)),
            ],
          ),
          _buildDirectionButton(Icons.keyboard_arrow_down, () => _moveCenterByPixels(0, 1, size)),
        ],
      ),
    );
  }

  Widget _buildDirectionButton(IconData icon, VoidCallback onPressed) {
    return Container(
      decoration: BoxDecoration(color: Colors.black87, borderRadius: BorderRadius.circular(8)),
      margin: const EdgeInsets.all(2),
      child: IconButton(
        icon: Icon(icon, color: Colors.white, size: 28),
        onPressed: onPressed,
        padding: EdgeInsets.zero,
        constraints: const BoxConstraints(minWidth: 40, minHeight: 40),
      ),
    );
  }

  void _notifyChange() {
    widget.onCalibrationChanged(
      _centerX,
      _centerY,
      _innerRadius,
      _radius,
      _ringCount,
      ringRadii: _ringRadii,
    );
  }

  void _moveCenterByPixels(double dx, double dy, Size size) {
    setState(() {
      _centerX = _centerX + (dx / size.width);
      _centerY = _centerY + (dy / size.height);
    });
    _notifyChange();
  }

  void _onScaleUpdate(ScaleUpdateDetails details, Size size) {
    setState(() {
      if (details.pointerCount == 2) {
        _radius = (_baseRadiusBeforeScale * details.scale).clamp(0.3, 0.95);
        _innerRadius = _radius * _currentEspacementRatio;
        _initRingRadii(forceRecalculate: _showEspacement);
      } else if (_isDraggingCenter) {
        final deltaX = details.focalPointDelta.dx / size.width;
        final deltaY = details.focalPointDelta.dy / size.height;
        _centerX = _centerX + deltaX;
        _centerY = _centerY + deltaY;
      }
    });
    _notifyChange();
  }

  void _onScaleEnd() {
    setState(() {
      _isDraggingCenter = false;
      _isDraggingRadius = false;
      _isDraggingInnerRadius = false;
    });
  }

  double _distance(double x1, double y1, double x2, double y2) {
    final dx = x1 - x2;
    final dy = y1 - y2;
    return (dx * dx + dy * dy);
  }
}

class _CalibrationPainter extends CustomPainter {
  final double centerX;
  final double centerY;
  final double radius;
  final double innerRadius;
  final int ringCount;
  final List<double> ringRadii;
  final TargetType targetType;
  final bool isDraggingCenter;
  final bool isDraggingRadius;
  final bool isDraggingInnerRadius;

  _CalibrationPainter({
    required this.centerX,
    required this.centerY,
    required this.radius,
    required this.innerRadius,
    required this.ringCount,
    required this.ringRadii,
    required this.targetType,
    required this.isDraggingCenter,
    required this.isDraggingRadius,
    required this.isDraggingInnerRadius,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final centerPx = Offset(centerX * size.width, centerY * size.height);
    final minDim = size.width < size.height ? size.width : size.height;
    final baseRadiusPx = radius * minDim;

    if (targetType == TargetType.concentric) {
      _drawConcentricZones(canvas, size, centerPx, baseRadiusPx);
    } else {
      _drawSilhouetteZones(canvas, size, centerPx, baseRadiusPx);
    }

    if (isDraggingCenter) {
      final crosshairLinePaint = Paint()..color = Colors.red.withValues(alpha: 0.5)..strokeWidth = 1;
      canvas.drawLine(Offset(0, centerPx.dy), Offset(size.width, centerPx.dy), crosshairLinePaint);
      canvas.drawLine(Offset(centerPx.dx, 0), Offset(centerPx.dx, size.height), crosshairLinePaint);
    }

    _drawCenterHandle(canvas, centerPx);
    _drawInstructions(canvas, size);
  }

  void _drawConcentricZones(Canvas canvas, Size size, Offset center, double baseRadius) {
    List<Color> zoneColors = [];
    for (int i = 0; i < ringCount; i++) {
      final ratio = i / ringCount;
      if (ratio < 0.2) {
        zoneColors.add(Colors.yellow.withValues(alpha: 0.3 - ratio * 0.5));
      } else if (ratio < 0.4) {
        zoneColors.add(Colors.orange.withValues(alpha: 0.25 - ratio * 0.3));
      } else if (ratio < 0.6) {
        zoneColors.add(Colors.blue.withValues(alpha: 0.2 - ratio * 0.2));
      } else if (ratio < 0.8) {
        zoneColors.add(Colors.green.withValues(alpha: 0.15 - ratio * 0.1));
      } else {
        zoneColors.add(Colors.white.withValues(alpha: 0.1));
      }
    }

    final zonePaint = Paint()..style = PaintingStyle.fill;
    final strokePaint = Paint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1
      ..color = Colors.red.withValues(alpha: 0.8);

    for (int i = ringCount - 1; i >= 0; i--) {
      final ringRadius = ringRadii.length > i ? ringRadii[i] : (i + 1) / ringCount;
      final zoneRadius = baseRadius * ringRadius;

      zonePaint.color = zoneColors[i];
      canvas.drawCircle(center, zoneRadius, zonePaint);
      canvas.drawCircle(center, zoneRadius, strokePaint);
    }

    final textPainter = TextPainter(textDirection: TextDirection.ltr);

    for (int i = 0; i < ringCount; i++) {
      final ringRadius = ringRadii.length > i ? ringRadii[i] : (i + 1) / ringCount;
      final textSpanRatio = i > 0 ? (ringRadii.length > i - 1 ? ringRadii[i - 1] : i / ringCount) : 0.0;
      final zoneRadius = baseRadius * (ringRadius + textSpanRatio) / 2;

      final score = 10 - i;
      final labelX = center.dx + zoneRadius;
      if (labelX < 0 || labelX > size.width) continue;

      textPainter.text = TextSpan(
        text: '$score',
        style: TextStyle(
          color: Colors.white.withValues(alpha: 0.9),
          fontSize: 12,
          fontWeight: FontWeight.bold,
          shadows: const [Shadow(color: Colors.black, blurRadius: 2)],
        ),
      );
      textPainter.layout();

      final labelY = center.dy - textPainter.height / 2;
      if (labelY >= 0 && labelY <= size.height) {
        textPainter.paint(canvas, Offset(labelX - textPainter.width / 2, labelY));
      }
    }
  }

  void _drawSilhouetteZones(Canvas canvas, Size size, Offset center, double radius) {
    final paint = Paint()..style = PaintingStyle.stroke..strokeWidth = 2;
    final silhouetteWidth = radius * 0.8;
    final silhouetteHeight = radius * 2;

    paint.color = Colors.green.withValues(alpha: 0.5);
    canvas.drawRect(Rect.fromCenter(center: center, width: silhouetteWidth, height: silhouetteHeight), paint);
  }

  void _drawCenterHandle(Canvas canvas, Offset center) {
    final outerPaint = Paint()..color = isDraggingCenter ? Colors.redAccent : Colors.red..style = PaintingStyle.stroke..strokeWidth = 3;
    canvas.drawCircle(center, 15, outerPaint);

    final innerPaint = Paint()..color = isDraggingCenter ? Colors.redAccent : Colors.red..style = PaintingStyle.fill;
    canvas.drawCircle(center, 5, innerPaint);

    final crossPaint = Paint()..color = isDraggingCenter ? Colors.redAccent : Colors.red..strokeWidth = 2;
    canvas.drawLine(Offset(center.dx - 20, center.dy), Offset(center.dx - 8, center.dy), crossPaint);
    canvas.drawLine(Offset(center.dx + 8, center.dy), Offset(center.dx + 20, center.dy), crossPaint);
    canvas.drawLine(Offset(center.dx, center.dy - 20), Offset(center.dx, center.dy - 8), crossPaint);
    canvas.drawLine(Offset(center.dx, center.dy + 4), Offset(center.dx, center.dy + 20), crossPaint);
  }

  void _drawInstructions(Canvas canvas, Size size) {
    const instruction = 'Deplacez le centre ou ajustez le rayon';
    final textPainter = TextPainter(
      text: TextSpan(text: instruction, style: TextStyle(color: Colors.white.withValues(alpha: 0.9), fontSize: 12, backgroundColor: Colors.black54)),
      textDirection: TextDirection.ltr,
    );
    textPainter.layout();
    textPainter.paint(canvas, Offset((size.width - textPainter.width) / 2, size.height - 30));
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    if (oldDelegate is! _CalibrationPainter) return true;
    return centerX != oldDelegate.centerX ||
        centerY != oldDelegate.centerY ||
        radius != oldDelegate.radius ||
        innerRadius != oldDelegate.innerRadius ||
        ringCount != oldDelegate.ringCount ||
        isDraggingCenter != oldDelegate.isDraggingCenter ||
        isDraggingRadius != oldDelegate.isDraggingRadius ||
        isDraggingInnerRadius != oldDelegate.isDraggingInnerRadius ||
        ringRadii != oldDelegate.ringRadii;
  }
}