import 'dart:math' as math;

import 'package:flame/components.dart';
import 'package:flutter/material.dart';

import '../../../../../core/network/card_images.dart';
import '../../../../../core/theme/app_theme.dart';

// رنگ‌های مشترکِ میز (منبعِ واحد در AppColors).
const _gold = AppColors.gold;
const _goldDark = AppColors.goldDark;

/// میز: زمینِ لاجوردیِ نمدی در کلِ صفحه + یک «میزِ» مرکزی با قابِ طلاییِ دولایه.
/// اگر فرشی انتخاب شده باشد، سطحِ میز تصویرِ فرش است (بریده‌شده در شکلِ میز)؛
/// وگرنه سطحِ سرمه‌ایِ ترسیمی. کارت‌ها داخلِ همین ناحیه انداخته می‌شوند.
class Felt extends PositionComponent with HasGameReference {
  /// شناسه‌ی فرشِ انتخابی؛ 'classic' یعنی سطحِ ترسیمی (بدون تصویر).
  final String carpet;
  Felt({this.carpet = 'classic'});

  Sprite? _carpetSprite;

  bool get _hasCarpet => carpet != 'classic';

  @override
  Future<void> onLoad() async {
    if (_hasCarpet) {
      _carpetSprite = await CardImages.carpet(carpet);
    }
  }

  @override
  void render(Canvas canvas) {
    final w = game.size.x, h = game.size.y;
    final center = Offset(w / 2, h / 2);

    // ۱) زمینِ لاجوردیِ نمدی (کلِ صفحه) با وینیتِ شعاعی برای عمق. همیشه کشیده
    // می‌شود تا زیرِ میز/فرش یکدست باشد و لبه‌های فرش با پس‌زمینه جور شود.
    canvas.drawRect(
      Rect.fromLTWH(0, 0, w, h),
      Paint()
        ..shader = RadialGradient(
          center: Alignment.center,
          radius: 1.0,
          colors: const [AppColors.lapisHi, AppColors.lapisNight],
          stops: const [0.5, 1.0],
        ).createShader(Rect.fromLTWH(0, 0, w, h)),
    );

    // ۲) میزِ مرکزی با قابِ طلایی.
    final rect = Rect.fromCenter(
        center: center, width: w * 0.72, height: h * 0.46);
    final radius = Radius.circular(h * 0.05);
    final table = RRect.fromRectAndRadius(rect, radius);

    // سایه‌ی نرمِ زیرِ میز (یک‌بار، نه هر-فریمی سنگین).
    canvas.drawRRect(
      table.shift(const Offset(0, 6)),
      Paint()
        ..color = const Color(0x66000000)
        ..maskFilter = const MaskFilter.blur(BlurStyle.normal, 12),
    );

    // قابِ طلاییِ بیرونی.
    canvas.drawRRect(
      RRect.fromRectAndRadius(rect.inflate(w * 0.012), radius),
      Paint()
        ..shader = const LinearGradient(
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
          colors: [_gold, _goldDark],
        ).createShader(rect),
    );

    // سطحِ میز: تصویرِ فرش (بریده در شکلِ میز) یا سطحِ سرمه‌ایِ ترسیمی.
    final sprite = _carpetSprite;
    if (_hasCarpet && sprite != null) {
      canvas.save();
      canvas.clipRRect(table);
      // فرش را به‌صورتِ cover داخلِ مستطیلِ میز می‌کشیم.
      sprite.render(
        canvas,
        position: Vector2(rect.left, rect.top),
        size: Vector2(rect.width, rect.height),
      );
      // تیره‌ترِ ملایم برای خوانایی کارت‌ها روی فرش.
      canvas.drawRRect(table, Paint()..color = const Color(0x1A000000));
      canvas.restore();
    } else {
      canvas.drawRRect(
        table,
        Paint()
          ..shader = RadialGradient(
            center: Alignment.center,
            radius: 0.9,
            colors: const [AppColors.lapisLo, AppColors.lapisInk],
            stops: const [0.4, 1.0],
          ).createShader(rect),
      );
    }

    // خطِ طلاییِ نازکِ داخلی (قابِ دولایه).
    canvas.drawRRect(
      RRect.fromRectAndRadius(rect.deflate(w * 0.018), Radius.circular(h * 0.04)),
      Paint()
        ..style = PaintingStyle.stroke
        ..strokeWidth = w * 0.004
        ..color = _gold.withValues(alpha: 0.65),
    );
  }
}

/// دیسکِ فلزیِ شمارش (امتیاز تیم) با عددِ وسط؛ از ۰ تا ۷.
class ScorePuck extends PositionComponent {
  final int count;
  ScorePuck(this.count, {required double radius, super.position})
      : super(size: Vector2.all(radius * 2), anchor: Anchor.center);

  @override
  void render(Canvas canvas) {
    final r = size.x / 2;
    final c = Offset(r, r);
    canvas.drawCircle(c, r, Paint()..color = const Color(0xFF14110F));
    canvas.drawCircle(
      c,
      r * 0.92,
      Paint()
        ..style = PaintingStyle.stroke
        ..strokeWidth = r * 0.22
        ..color = _goldDark,
    );
    final tp = TextPainter(
      text: TextSpan(
        text: '$count',
        style: TextStyle(
          fontFamily: 'Dana',
          color: _gold,
          fontSize: r * 1.05,
          fontWeight: FontWeight.bold,
        ),
      ),
      textDirection: TextDirection.ltr,
    )..layout();
    tp.paint(canvas, c - Offset(tp.width / 2, tp.height / 2));
  }
}

/// افکت رعد روی زمین هنگام «بریدن با حکم»؛ پس از مدت کوتاهی خودش حذف می‌شود.
class Lightning extends PositionComponent with HasGameReference {
  static const _max = 0.55;
  double _life = _max;
  final _rng = math.Random();
  final List<List<Offset>> _bolts = [];

  @override
  Future<void> onLoad() async {
    size = game.size;
    final center = Offset(size.x / 2, size.y / 2);
    for (var i = 0; i < 3; i++) {
      // هر رعد یک خط شکسته از یک نقطه‌ی تصادفیِ بالا به سمت مرکز.
      final start =
          Offset(_rng.nextDouble() * size.x, _rng.nextDouble() * size.y * 0.4);
      final pts = <Offset>[start];
      const segs = 6;
      for (var s = 1; s <= segs; s++) {
        final t = s / segs;
        final base = Offset.lerp(start, center, t)!;
        final jitter = (1 - t) * size.x * 0.06;
        pts.add(base +
            Offset((_rng.nextDouble() - 0.5) * jitter,
                (_rng.nextDouble() - 0.5) * jitter));
      }
      _bolts.add(pts);
    }
  }

  @override
  void update(double dt) {
    _life -= dt;
    if (_life <= 0) removeFromParent();
  }

  @override
  void render(Canvas canvas) {
    final op = (_life / _max).clamp(0.0, 1.0);
    final glow = Paint()
      ..color = const Color(0xFFFFE082).withValues(alpha: op * 0.5)
      ..style = PaintingStyle.stroke
      ..strokeWidth = size.x * 0.02
      ..maskFilter = const MaskFilter.blur(BlurStyle.normal, 6);
    final core = Paint()
      ..color = const Color(0xFFFFFDE7).withValues(alpha: op)
      ..style = PaintingStyle.stroke
      ..strokeWidth = size.x * 0.006
      ..strokeCap = StrokeCap.round;
    for (final bolt in _bolts) {
      final path = Path()..moveTo(bolt.first.dx, bolt.first.dy);
      for (final p in bolt.skip(1)) {
        path.lineTo(p.dx, p.dy);
      }
      canvas.drawPath(path, glow);
      canvas.drawPath(path, core);
    }
  }
}
