package com.cameleer.server.app.license;

import com.cameleer.server.core.license.LicenseInfo;
import com.cameleer.server.core.license.LicenseState;

import java.time.Duration;
import java.time.Instant;

public final class LicenseMessageRenderer {

    private LicenseMessageRenderer() {}

    public static String forCap(LicenseState state, LicenseInfo info, String limit, long current, long cap) {
        return forCap(state, info, limit, current, cap, null);
    }

    public static String forCap(LicenseState state, LicenseInfo info, String limit, long current, long cap, String invalidReason) {
        switch (state) {
            case ABSENT:
                return "No license installed: default tier applies (cap = " + cap + " for " + limit
                        + "). Install a license to raise this.";
            case ACTIVE:
                return "License cap reached: " + limit + " = " + cap + ". Current usage is " + current
                        + ". Contact your vendor to raise the cap.";
            case GRACE: {
                long expiredDaysAgo = info == null ? 0 : daysSince(info.expiresAt());
                long graceRemaining = info == null ? 0
                        : Math.max(0, info.gracePeriodDays() - expiredDaysAgo);
                return "License expired " + expiredDaysAgo + " day(s) ago and is in its grace period "
                        + "(ends in " + graceRemaining + " days). Cap unchanged at " + cap
                        + ". Renew before grace ends.";
            }
            case EXPIRED: {
                long expiredDaysAgo = info == null ? 0 : daysSince(info.expiresAt());
                return "License expired " + expiredDaysAgo + " days ago: system reverted to default tier (cap = "
                        + cap + " for " + limit + "). Current usage is " + current
                        + ". Renew the license to lift the cap.";
            }
            case INVALID:
                return "License rejected (" + (invalidReason == null ? "unknown reason" : invalidReason)
                        + "): default tier applies (cap = " + cap + " for " + limit + "). Fix the license to raise this.";
            default:
                return "License cap reached: " + limit + " = " + cap;
        }
    }

    /**
     * State-only message used by the /usage endpoint and metrics surfaces where no specific
     * cap is being checked. Mirrors forCap() phrasing but omits limit/current/cap details.
     */
    public static String forState(LicenseState state, LicenseInfo info) {
        return forState(state, info, null);
    }

    public static String forState(LicenseState state, LicenseInfo info, String invalidReason) {
        switch (state) {
            case ABSENT:
                return "No license installed: default tier applies. Install a license to raise the caps.";
            case ACTIVE:
                return "License is active.";
            case GRACE: {
                long expiredDaysAgo = info == null ? 0 : daysSince(info.expiresAt());
                long graceRemaining = info == null ? 0
                        : Math.max(0, info.gracePeriodDays() - expiredDaysAgo);
                return "License expired " + expiredDaysAgo + " day(s) ago and is in its grace period "
                        + "(ends in " + graceRemaining + " days). Renew before grace ends.";
            }
            case EXPIRED: {
                long expiredDaysAgo = info == null ? 0 : daysSince(info.expiresAt());
                return "License expired " + expiredDaysAgo + " days ago: system reverted to default tier. Renew the license to lift the caps.";
            }
            case INVALID:
                return "License rejected (" + (invalidReason == null ? "unknown reason" : invalidReason)
                        + "): default tier applies. Fix the license to raise the caps.";
            default:
                return "License state: " + state.name();
        }
    }

    private static long daysSince(Instant t) {
        return Math.max(0, Duration.between(t, Instant.now()).toDays());
    }
}
