import 'package:didvan/models/category.dart';
import 'package:didvan/models/enums.dart';
import 'package:didvan/models/overview_data.dart';
import 'package:didvan/models/statistic_data/data.dart';
import 'package:didvan/models/tag.dart';
import 'package:didvan/providers/core.dart';
import 'package:didvan/services/network/request.dart';
import 'package:didvan/services/network/request_helper.dart';
// ignore: depend_on_referenced_packages
import 'package:collection/collection.dart';

class StatisticDetailsState extends CoreProvier {
  late bool marked;
  late String label;
  late String volume;
  late String currency;
  final List<Data> datas = [];
  final List<Tag> tags = [];
  String? startDate;
  String? endDate;
  int currentDateRangeId = 0;
  List<OverviewData>? relatedContents = [];
  Data? data;
  double maxValue = 0;
  double? minValue;

  AppState chartState = AppState.idle;

  final dateRanges = [
    CategoryData(
      id: 0,
      label: 'هفتگی',
      asset: 'weekly',
    ),
    CategoryData(
      id: 1,
      label: 'ماهانه',
      asset: 'monthly',
    ),
    CategoryData(
      id: 2,
      label: 'شش ماهه',
      asset: 'semiyearly',
    ),
    CategoryData(
      id: 3,
      label: 'سالانه',
      asset: 'yearly',
    ),
  ];

  CategoryData get currentDateRange => dateRanges.firstWhere(
        (element) => element.id == currentDateRangeId,
      );

  Future<void> getStatisticDetails() async {
    if (data == null) {
      final result = await getStatisticCurrentDetails();
      if (!result) {
        appState = AppState.failed;
        return;
      }
    }
    minValue = null;
    maxValue = 0;
    if (datas.isEmpty) {
      appState = AppState.busy;
    } else {
      chartState = AppState.busy;
      notifyListeners();
    }
    datas.clear();
    final service = RequestService(
      RequestHelper.statisticDetails(
        label,
        dateRanges[currentDateRangeId].asset!,
      ),
    );
    await service.httpGet();
    if (service.isSuccess) {
      final result = service.result['data'];
      volume = service.result['volume'];
      currency = service.result['currency'];
      tags.clear();
      for (var i = 0; i < service.result['tags'].length; i++) {
        tags.add(Tag.fromJson(service.result['tags'][i]));
      }
      for (var i = 0; i < result.length; i++) {
        datas.add(Data.fromList(result[i]));
      }
      if (currentDateRangeId != 0 && currentDateRangeId != 1) {
        final grouped =
            datas.groupListsBy((element) => element.tEn!.split('/')[1]);
        datas.clear();
        grouped.forEach((key, value) {
          datas.add(
            Data(
              p: _average(value),
              h: '',
              l: '',
              d: '',
              dp: 0,
              dt: '',
              t: '',
              tEn: value.first.tEn!.substring(0, 7),
              tG: '',
              ts: '',
            ),
          );
        });
      }
      for (var i = 0; i < datas.length; i++) {
        final current = _stringToDouble(datas[i].p);
        if (maxValue < current) {
          maxValue = current;
        }
        if (minValue == null || minValue! > current) {
          minValue = current;
        }
      }
      getRelatedContents();
      datas.replaceRange(0, datas.length, datas.reversed);
      chartState = AppState.idle;
      appState = AppState.idle;
      return;
    }
    if (datas.isEmpty) {
      appState = AppState.failed;
    } else {
      chartState = AppState.failed;
      notifyListeners();
    }
  }

  Future<bool> getStatisticCurrentDetails() async {
    final service = RequestService(
      RequestHelper.statisticDetails(
        label,
        'current',
      ),
    );
    await service.httpGet();
    if (service.isSuccess) {
      data = Data.fromJson(service.result['data']);
    }
    return service.isSuccess;
  }

  String _average(List<Data> inputs) {
    double sum = 0;
    for (var i = 0; i < inputs.length; i++) {
      sum += _stringToDouble(inputs[i].p);
    }
    return (sum / inputs.length).toString();
  }

  double _stringToDouble(String value) =>
      double.parse(value.replaceAll(',', ''));

  Future<void> getRelatedContents() async {
    if (relatedContents?.isNotEmpty ?? true) return;
    final service = RequestService(RequestHelper.tag(
      ids: tags.map((tag) => tag.id).toList(),
    ));
    await service.httpGet();
    if (service.isSuccess) {
      final relateds = service.result['contents'];
      for (var i = 0; i < relateds.length; i++) {
        relatedContents!.add(OverviewData.fromJson(relateds[i]));
      }
      if (relatedContents!.isEmpty) {
        relatedContents = null;
      }
      notifyListeners();
    }
  }
}
