import 'package:flutter/material.dart';
import 'package:syncrow_web/utils/color_manager.dart';

class OccupancyPaintItem {
  final int index;
  final int value;
  final DateTime date;

  const OccupancyPaintItem({
    required this.index,
    required this.value,
    required this.date,
  });
}

class OccupancyPainter extends CustomPainter {
  OccupancyPainter({
    required this.items,
    required this.maxValue,
    this.hoveredItem,
  });

  final List<OccupancyPaintItem> items;
  final int maxValue;
  final OccupancyPaintItem? hoveredItem;

  static const double cellSize = 16.0;

  @override
  void paint(Canvas canvas, Size size) {
    final fillPaint = Paint();
    final borderPaint = Paint()
      ..color = ColorsManager.grayBorder.withValues(alpha: 0.4)
      ..style = PaintingStyle.stroke;
    final hoveredBorderPaint = Paint()
      ..color = Colors.black
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1.5;

    for (final item in items) {
      final column = item.index ~/ 7;
      final row = item.index % 7;

      final x = column * cellSize;
      final y = row * cellSize;

      fillPaint.color = _getColor(item.value);
      final rect = Rect.fromLTWH(x, y, cellSize, cellSize);
      canvas.drawRect(rect, fillPaint);

      if (hoveredItem != null && hoveredItem!.index == item.index) {
        canvas.drawRect(rect, hoveredBorderPaint);
      } else {
        _drawDashedLine(
          canvas,
          Offset(x, y),
          Offset(x + cellSize, y),
          borderPaint,
        );
        _drawDashedLine(
          canvas,
          Offset(x, y + cellSize),
          Offset(x + cellSize, y + cellSize),
          borderPaint,
        );

        canvas.drawLine(Offset(x, y), Offset(x, y + cellSize), borderPaint);
        canvas.drawLine(Offset(x + cellSize, y), Offset(x + cellSize, y + cellSize),
            borderPaint);
      }
    }
  }

  void _drawDashedLine(Canvas canvas, Offset start, Offset end, Paint paint) {
    const dashWidth = 2.0;
    const dashSpace = 4.0;
    final totalLength = (end - start).distance;
    final direction = (end - start) / (end - start).distance;

    var currentLength = 0.0;
    while (currentLength < totalLength) {
      final dashStart = start + direction * currentLength;
      final nextLength = currentLength + dashWidth;
      final dashEnd =
          start + direction * (nextLength < totalLength ? nextLength : totalLength);
      canvas.drawLine(dashStart, dashEnd, paint);
      currentLength = nextLength + dashSpace;
    }
  }

  Color _getColor(int value) {
    if (maxValue == 0) return ColorsManager.vividBlue.withValues(alpha: 0);
    final clampedValue = 0.075 + (1 * value.clamp(0, maxValue) / maxValue);
    final opacity = value == 0 ? 0 : clampedValue;
    return ColorsManager.vividBlue.withValues(alpha: opacity.toDouble());
  }

  @override
  bool shouldRepaint(covariant OccupancyPainter oldDelegate) =>
      oldDelegate.hoveredItem != hoveredItem;
}
