import '../about/internal/application/EscalationTier.dart';
import '../about/internal/application/Standing.dart';
import '../about/internal/application/ToneLevel.dart';

/// All user-facing enforcement copy comes from here, so the hard cap is
/// enforceable in one place: language may criticise behaviour, never the
/// person. Nothing that mocks the user's worth ships.
class ToneEngine {
  /// The escalation ladder. Disappointment is deliberately placed above anger
  /// because it works better as a lever.
  static EscalationTier tierFor(int unacknowledgedCount) {
    if (unacknowledgedCount <= 0) {
      return EscalationTier.Reminder;
    }
    if (unacknowledgedCount == 1) {
      return EscalationTier.Nudge;
    }
    if (unacknowledgedCount == 2) {
      return EscalationTier.Nag;
    }
    if (unacknowledgedCount == 3) {
      return EscalationTier.Disappointed;
    }
    return EscalationTier.Cold;
  }

  /// Notification body for a commitment at a given tier and tone.
  static String nudge(
    EscalationTier tier,
    ToneLevel tone,
    String title,
  ) {
    switch (tier) {
      case EscalationTier.Reminder:
        return "$title is due now.";
      case EscalationTier.Nudge:
        return "$title is still sitting there.";
      case EscalationTier.Nag:
        return tone == ToneLevel.Firm
            ? "$title is overdue. It needs a decision."
            : "Third time: $title. Do it or abandon it.";
      case EscalationTier.Disappointed:
        return "You said you would do $title. You have not.";
      case EscalationTier.Cold:
        return "$title. No more reminders about this one.";
    }
  }

  /// The header copy on app open, which shifts with standing.
  static String standingHeadline(Standing standing, ToneLevel tone) {
    switch (standing) {
      case Standing.Good:
        return "You are in good standing.";
      case Standing.Warned:
        return "You are slipping.";
      case Standing.Grounded:
        return tone == ToneLevel.Firm
            ? "You are grounded until this is cleared."
            : "Grounded. Nothing new until the queue is empty.";
      case Standing.Lockdown:
        return "Lockdown. One item at a time.";
    }
  }

  static String standingBody(Standing standing, ToneLevel tone) {
    switch (standing) {
      case Standing.Good:
        return "Keep the plan honest and it stays this way.";
      case Standing.Warned:
        return "New electives are blocked. Clear some debt before adding more.";
      case Standing.Grounded:
        return "Your plans are hidden. This is what is actually outstanding.";
      case Standing.Lockdown:
        return "Complete or abandon each item below. There is no third option.";
    }
  }

  /// Praise is rationed but real. A parent who only criticises gets tuned out —
  /// this returns empty unless something specific was genuinely earned.
  static String praise(String specificAchievement) {
    if (specificAchievement.isEmpty) {
      return "";
    }
    return specificAchievement;
  }

  /// The register the app switches to when distress is detected. The strict
  /// persona drops entirely — this is the difference between a product people
  /// keep and one they resent.
  static String distressHeadline() {
    return "Let us cut this back.";
  }

  static String distressBody() {
    return "Something has clearly been hard lately. Pick three things that "
        "genuinely matter this week and let the rest go. Nothing here is "
        "counting against you right now.";
  }

  /// Copy shown when a deferral is refused because the cap is spent.
  static String deferralRefused(int maxDeferrals) {
    return "This has been deferred $maxDeferrals times. It can now only be "
        "completed or abandoned.";
  }

  /// Copy shown when a non-negotiable deferral is attempted.
  static String nonNegotiableRefused() {
    return "Non-negotiables are not deferrable. That is what makes them "
        "non-negotiable.";
  }

  /// Copy shown when the excuse is too short.
  static String excuseTooShort(int minimum) {
    return "Write at least $minimum characters. If it is not worth explaining, "
        "it is not worth deferring.";
  }
}
