import 'dart:async';

import 'package:flutter/material.dart';
import 'package:test_sa/models/timer_model.dart';
import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.dart';

class AppTimer extends StatefulWidget {
  final TimerModel timer;
  final Future<bool> Function(TimerModel) onChange;
  final TextStyle style;
  final bool enabled;
  const AppTimer({
    Key key,
    this.timer,
    this.onChange,
    this.style,
    this.enabled = true,
  }) : super(key: key);

  @override
  State<AppTimer> createState() => _AppTimerState();
}

class _AppTimerState extends State<AppTimer> {
  Timer _timer;
  DateTime _startAt;
  DateTime _endAt;
  int _delay = 0;
  bool _running = false;
  bool _loading = false;
  final ValueNotifier<String> _period = ValueNotifier("0:00:00");

  _startTimer() async {
    if (!_running) {
      final time = DateTime.now();
      bool result = await widget.onChange(TimerModel(startAt: time, endAt: null, durationInSecond: _delay, stopped: false));
      if (!result) return;
      _running = true;

      if (_endAt != null) {
        _delay += _endAt.difference(_startAt).inSeconds;
      }
      _startAt = time.subtract(Duration(seconds: _delay));
      _endAt = null;
    }

    _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
      if (_loading == true) return;
      _period.value = (_endAt ?? DateTime.now()).difference(_startAt).toString().split(".").first;
    });
  }

  _stopTimer() async {
    final time = DateTime.now();
    final tempStartAt = _startAt.add(Duration(seconds: _delay));
    bool result = await widget.onChange(TimerModel(startAt: tempStartAt, endAt: time, durationInSecond: _delay, stopped: true));
    if (!result) return;
    _running = false;
    _endAt = time;
    _startAt = tempStartAt;
    _timer?.cancel();
  }

  _onPressed() async {
    _loading = true;
    setState(() {});
    if (!_running) {
      await _startTimer();
    } else {
      await _stopTimer();
    }
    _loading = false;
    setState(() {});
  }

  @override
  void initState() {
    _startAt = widget.timer?.startAt;
    _endAt = widget.timer?.endAt;
    _running = _startAt != null && _endAt == null;
    _delay = (widget.timer?.durationInSecond ?? 0);
    final difference = _startAt == null ? 0 : (_endAt ?? DateTime.now())?.difference(_startAt)?.inSeconds ?? 0;
    _period.value = Duration(seconds: _running ? difference : _delay + difference).toString().split(".").first;
    super.initState();
    if (_running) {
      _startTimer();
    }
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: 100 * AppStyle.getScaleFactor(context),
      height: 28 * AppStyle.getScaleFactor(context),
      child: ElevatedButton(
        style: ElevatedButton.styleFrom(
            minimumSize: const Size(1, 1), padding: EdgeInsets.all(4 * AppStyle.getScaleFactor(context)), backgroundColor: _running ? AColors.green[300] : AColors.grey, foregroundColor: Colors.black),
        onPressed: _loading || widget.enabled == false ? null : _onPressed,
        child: _loading
            ? const SizedBox.square(
                dimension: 18,
                child: CircularProgressIndicator(
                  color: Colors.white,
                ))
            : Row(
                children: [
                  if (widget.enabled) Icon(_running ? Icons.pause : Icons.play_arrow),
                  Expanded(
                    child: Center(
                      child: ValueListenableBuilder<String>(
                          valueListenable: _period,
                          builder: (context, value, _) {
                            return Text(
                              value,
                              style: widget.enabled ? widget.style : widget.style?.copyWith(color: Colors.black54),
                            );
                          }),
                    ),
                  ),
                ],
              ),
      ),
    );
  }
}
