import 'package:logging/logging.dart';
import 'package:relatica/models/instance_info.dart';
import 'package:relatica/utils/active_profile_selector.dart';
import 'package:result_monad/result_monad.dart';

import '../globals.dart';
import '../models/exec_error.dart';
import '../models/friendica_version.dart';
import '../models/friendica_version_requirement.dart';

enum RelaticaFeatures {
  diasporaReshare('Resharing Diaspora Posts'),
  directMessageCreation('Direct message creation with OAuth login'),
  postSpoilerText('Spoiler Text on Posts'),
  reshareIdFix('Reshare ID fix'),
  statusEditing('Post/Comment Editing'),
  usingActualFollowRequests(
      'Using Follow Request System not Friend Request Notifications'),
  ;

  final String errorLabel;

  const RelaticaFeatures(this.errorLabel);

  String get label => errorLabel;
}

class FriendicaVersionChecker {
  static final _logger = Logger('FriendicaVersionTest');

  const FriendicaVersionChecker();

  bool canUseFeature(RelaticaFeatures feature) {
    final requirement = featureVersionRequirement[feature];
    if (requirement == null) {
      _logger.severe(
        'Return false since no minimum version data in table for: $feature',
      );
      return false;
    }

    return getIt<ActiveProfileSelector<InstanceInfo>>()
        .activeEntry
        .andThenSuccess(
          (info) => requirement.versionMeetsRequirement(info.friendicaVersion),
        )
        .fold(
          onSuccess: (versionMet) => versionMet,
          onError: (error) {
            _logger.severe(
                'Unable to calculate needed version data so returning false: $error');
            return false;
          },
        );
  }

  Result<bool, ExecError> canUseFeatureResult(RelaticaFeatures feature) {
    if (canUseFeature(feature)) {
      return Result.ok(true);
    }

    return buildErrorResult(
      type: ErrorType.minVersionError,
      message: versionErrorString(feature),
    );
  }

  FriendicaVersionRequirement getVersionRequirement(RelaticaFeatures feature) =>
      featureVersionRequirement[feature] ?? unknownRequirement;

  String versionErrorString(RelaticaFeatures feature) =>
      "${feature.label} ${getVersionRequirement(feature)}";

  static final featureVersionRequirement =
      <RelaticaFeatures, FriendicaVersionRequirement>{
    RelaticaFeatures.diasporaReshare: FriendicaVersionRequirement(v2023_04),
    RelaticaFeatures.directMessageCreation: FriendicaVersionRequirement(
      v2023_04,
    ),
    RelaticaFeatures.postSpoilerText: FriendicaVersionRequirement(v2023_04),
    RelaticaFeatures.statusEditing: FriendicaVersionRequirement(v2023_04),
    RelaticaFeatures.usingActualFollowRequests: FriendicaVersionRequirement(
      v2023_04,
    ),
  };
}
