import 'dart:async';
import 'dart:ui';

import 'package:daily_challenge/data/db/daily_challenge_db.dart';
import 'package:daily_challenge/data/db/entities/entities.dart';
import 'package:daily_challenge/l10n/generated/app_localizations.dart';
import 'package:daily_challenge/l10n/localizations/app_strings.dart';
import 'package:daily_challenge/mgr/daily_challenge_manager.dart';
import 'package:flutter/src/widgets/localizations.dart';
import 'package:guru_utils/log/log.dart';
import 'package:guru_utils/packages/guru_package.dart';
import 'package:guru_utils/router/router.dart';
import 'package:rxdart/rxdart.dart';
import 'package:guru_utils/extensions/extensions.dart';

/// Created by Haoyi on 2023/10/9

class DailyChallengeState {
  final String id;
  final int at;
  final int progress;

  DailyChallengeState(this.id, this.at, this.progress);
}

enum DailyChallengeAccessMode { free, reward, iap, igc }

class DailyChallengeCallbacks {
  void onCongratulationsPageImpression(DateTime dateTime) {}

  void onCongratulationsPageCollect(DateTime dateTime) {}

  void onCalendarCollected(DateTime dateTime) {}
}

class DailyChallengeConfig {
  final DateTime start;
  final AwardPolicy policy;
  final List<TrophyAsset> trophies;
  final List<TrophyAsset> exhibitedTrophies;
  final RoutePath awardRoute;
  final DailyChallengeCallbacks? callbacks;

  DailyChallengeConfig(this.start, this.awardRoute, this.trophies,
      {this.policy = const AwardPolicy(),
      this.exhibitedTrophies = const <TrophyAsset>[],
      this.callbacks});
}

class TrophyAsset {
  final String initial;
  final List<String> achieved;

  TrophyAsset({required this.initial, required this.achieved});
}

class AwardPolicy {
  final List<double> achievedPercentages;

  const AwardPolicy({this.achievedPercentages = const [1.0]});
}

class DailyChallengeRequest {
  final DateTime focusDate;
  final List<DailyChallengeEntity> entities;
  void Function(DailyChallengeState)? updater;

  DailyChallengeRequest(this.focusDate, this.updater,
      {this.entities = const <DailyChallengeEntity>[]});

  void update(DailyChallengeState state) {
    updater?.call(state);
  }

  void dispose() {
    updater = null;
  }
}

abstract class DailyChallengeDelegate {
  Future<DailyChallengeConfig> loadConfig();

  DailyChallengeAccessMode getAccessMode(
      DateTime dateTime, List<DailyChallengeEntity> entities);

  int getDailyProgress(DateTime dateTime, List<DailyChallengeEntity> entities);

  void playOrReplay(DailyChallengeRequest request);
}

class DailyChallengePackage extends GuruPackage {
  final DailyChallengeDelegate delegate;

  DailyChallengePackage(this.delegate) : super("daily_challenge");

  @override
  Future initialize() async {
    await DailyChallengeManager.instance.init(delegate);
  }

  @override
  Iterable<LocalizationsDelegate> get localizationsDelegates =>
      AppLocalizations.localizationsDelegates;

  @override
  Iterable<Locale> get supportedLocales => AppLocalizations.supportedLocales;
}
