import 'dart:math' as math;

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import '../../theme/autopilot_theme.dart';
import '../../theme/theme_provider.dart';

/// Full compass rose widget — the dominant visual element of the cockpit.
///
/// Displays:
/// - Rotating compass ring with degree markings
/// - Heading arc in [AutopilotTheme.accentLight]
/// - Set-point tick in [AutopilotTheme.setLight]
/// - North mark in [AutopilotTheme.northColor]
/// - Centre heading readout in [AutopilotTheme.textMain] with accent glow
///
/// [headingDeg] is the current vessel heading (0–359.9°, magnetic).
/// [setPointDeg] is the desired heading (the autopilot target).
class CompassRose extends StatelessWidget {
  const CompassRose({
    super.key,
    required this.headingDeg,
    this.setPointDeg,
    this.size = 280,
  });

  final double headingDeg;
  final double? setPointDeg;
  final double size;

  @override
  Widget build(BuildContext context) {
    final theme = context.watch<AutopilotThemeProvider>().current;
    return SizedBox(
      width: size,
      height: size,
      child: CustomPaint(
        painter: _CompassPainter(
          theme: theme,
          headingDeg: headingDeg,
          setPointDeg: setPointDeg,
        ),
        child: Center(
          child: _HeadingReadout(theme: theme, headingDeg: headingDeg),
        ),
      ),
    );
  }
}

class _HeadingReadout extends StatelessWidget {
  const _HeadingReadout({required this.theme, required this.headingDeg});
  final AutopilotTheme theme;
  final double headingDeg;

  @override
  Widget build(BuildContext context) {
    final text = headingDeg.toStringAsFixed(1).padLeft(5, ' ');
    return Text(
      '$text°',
      style: TextStyle(
        color: theme.textMain,
        fontSize: 36,
        fontWeight: FontWeight.w200,
        letterSpacing: 2,
        fontFeatures: const [FontFeature.tabularFigures()],
        shadows: theme.accentGlowRadius > 0
            ? [Shadow(color: theme.accentGlowColor, blurRadius: theme.accentGlowRadius)]
            : null,
      ),
    );
  }
}

class _CompassPainter extends CustomPainter {
  const _CompassPainter({
    required this.theme,
    required this.headingDeg,
    this.setPointDeg,
  });

  final AutopilotTheme theme;
  final double headingDeg;
  final double? setPointDeg;

  double _toRad(double deg) => deg * math.pi / 180;

  @override
  void paint(Canvas canvas, Size size) {
    final center = Offset(size.width / 2, size.height / 2);
    final radius = size.width / 2 - 8;

    // Outer ring
    canvas.drawCircle(
      center,
      radius,
      Paint()
        ..color = theme.panelBorder
        ..style = PaintingStyle.stroke
        ..strokeWidth = 1,
    );

    // Heading arc (±45° around top = current heading)
    canvas.drawArc(
      Rect.fromCircle(center: center, radius: radius - 8),
      _toRad(-90 - 45),
      _toRad(90),
      false,
      Paint()
        ..color = theme.accentLight
        ..style = PaintingStyle.stroke
        ..strokeWidth = 4
        ..strokeCap = StrokeCap.round,
    );

    // North mark (always at top of the ring, rotated opposite to heading)
    final northAngle = _toRad(-headingDeg - 90);
    final nx = center.dx + radius * math.cos(northAngle);
    final ny = center.dy + radius * math.sin(northAngle);
    canvas.drawCircle(
      Offset(nx, ny),
      5,
      Paint()..color = theme.northColor,
    );

    // Set-point tick
    if (setPointDeg != null) {
      final spAngle = _toRad(setPointDeg! - headingDeg - 90);
      canvas.drawLine(
        Offset(
          center.dx + (radius - 12) * math.cos(spAngle),
          center.dy + (radius - 12) * math.sin(spAngle),
        ),
        Offset(
          center.dx + radius * math.cos(spAngle),
          center.dy + radius * math.sin(spAngle),
        ),
        Paint()
          ..color = theme.setLight
          ..strokeWidth = 3
          ..strokeCap = StrokeCap.round,
      );
    }

    // Glow ring (dark themes only)
    if (theme.accentGlowRadius > 0) {
      canvas.drawCircle(
        center,
        radius - 8,
        Paint()
          ..color = theme.accentGlowColor
          ..style = PaintingStyle.stroke
          ..strokeWidth = theme.accentGlowRadius / 2
          ..maskFilter = MaskFilter.blur(BlurStyle.normal, theme.accentGlowRadius / 2),
      );
    }
  }

  @override
  bool shouldRepaint(_CompassPainter old) =>
      old.headingDeg != headingDeg ||
      old.setPointDeg != setPointDeg ||
      old.theme != theme;
}
