import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_fonts/google_fonts.dart';

import 'package:aitrainer_app/bloc/timer/timer_bloc.dart';

final temperatureColors = [
  const Color(0xFFB50DE2), // -20 Celsius , friggin cold
  const Color(0xFFAE0DE2),
  const Color(0xFF980DE2),
  const Color(0xFF8E0DE2),
  const Color(0xFF810DE2),
  const Color(0xFF7B0DE2),
  const Color(0xFF670DE2),
  const Color(0xFF570DE2),
  const Color(0xFF4A0DE2),
  const Color(0xFF410DE2),
  const Color(0xFF1D0DE2),
  const Color(0xFF0D4AE2),
  const Color(0xFF0D57E2),
  const Color(0xFF012e7d),
  const Color(0xFF01417d),
  const Color(0xFF01737d),
  const Color(0xFF017d71),
  const Color(0xFF017d49),
  const Color(0xFF017d1c),
  const Color(0xFF317d01),
  const Color(0xFF477d01),
  const Color(0xFF607d01),
  const Color(0xFF7d7d01),
  const Color(0xFF7d6001),
  const Color(0xFF7d4701),
  const Color(0xFFE2740D),
  const Color(0xFFE2510D),
  const Color(0xFFE22D0D),
  const Color(0xFFE2100D),
  const Color(0xFFE20D17), // 40 Celsius, rather be dead
];

// ignore: must_be_immutable
class Clock extends StatelessWidget {
  final TimerBloc bloc;
  final List<Color> colors = temperatureColors;

  Clock({required this.bloc});

  // ignore: close_sinks

  final Paint paintSeconds = Paint()
    ..strokeCap = StrokeCap.butt
    ..style = PaintingStyle.stroke
    ..strokeWidth = 4
    ..isAntiAlias = true;

  final Paint paintMinutes = Paint()
    ..strokeCap = StrokeCap.butt
    ..style = PaintingStyle.stroke
    ..strokeWidth = 4
    ..isAntiAlias = true;

  final Paint paintHours = Paint()
    ..strokeCap = StrokeCap.butt
    ..style = PaintingStyle.stroke
    ..strokeWidth = 4
    ..isAntiAlias = true;

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<TimerBloc, TimerState>(builder: (context, state) {
      if (state is TimerRunning) {
        return getLayout(bloc.state);
      } else {
        return Offstage();
      }
    });
  }

  Widget getLayout(TimerState state) {
    int duration = 300 - state.duration;
    int seconds = (duration % 60).floor();
    int minutes = ((duration / 60) % 60).floor();
    String secondStr = seconds.toString().padLeft(2, '0');
    String time = minutes == 0 ? "$secondStr" : "$minutes:$secondStr";
    return LayoutBuilder(builder: (context, constraints) {
      return Stack(
        alignment: Alignment.center,
        fit: StackFit.expand,
        children: <Widget>[
          Positioned(
              top: 37,
              left: (45 - time.length / 2 * 9).toDouble(), //seconds < 10 ? 37 : 30,
              child: Text(
                "$time",
                style: GoogleFonts.kosugi(color: colors[(seconds ~/ 2)], fontSize: 16),
              )),
          CustomPaint(painter: ArcPainter(minutes, paintMinutes, 5, constraints.maxHeight * 0.40, 0.15, colors)),
          CustomPaint(painter: ArcPainter(seconds, paintSeconds, 60, constraints.maxHeight * 0.34, 0.2, colors)),
        ],
      );
    });
  }
}

class ArcPainter extends CustomPainter {
  int _progress;
  Paint _paint;
  int _units;
  double _gap;

  List<Color> _gradient;

  Offset? center;
  double _radius;

  late Paint paintMarkerEmpty;

  ArcPainter(
    this._progress,
    this._paint,
    this._units,
    this._radius,
    this._gap,
    this._gradient,
  ) {
    this.paintMarkerEmpty = Paint()
      ..strokeCap = StrokeCap.butt
      ..style = PaintingStyle.stroke
      ..strokeWidth = this._paint.strokeWidth
      ..isAntiAlias = true;
  }

  @override
  void paint(Canvas canvas, Size size) {
    center = Offset(size.width / 2, size.height / 2);
    var rect = Rect.fromCircle(center: center!, radius: this._radius);

    final gradient2 = new SweepGradient(
      startAngle: -pi / 2,
      endAngle: (-pi / 2) + (pi * 2),
      tileMode: TileMode.repeated,
      colors: this._gradient,
    );

    this._paint.shader = gradient2.createShader(rect);

    this.paintMarkerEmpty.color = this._gradient[0].withOpacity(0.2);

    for (var i = 0; i < this._units; i++) {
      final double unit = 2 * pi / this._units;
      double start = unit * i;
      double to = (((2 * pi) / this._units) + unit);

      canvas.drawArc(rect, (-pi / 2 + start), to * 2 * this._gap, false, i < this._progress ? this._paint : this.paintMarkerEmpty);
    }
  }

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