import { isLicenseFeatureEnabledInMap, mergeLicenseFeaturesWithPlan } from './license.catalog';
import type { AsukaLicenseEntitlements, AsukaLicenseFeature, AsukaLicensePlan } from './license.types';

function toTimestamp(value?: string): number | null {
  if (!value) return null;
  const ts = new Date(value).getTime();
  return Number.isFinite(ts) ? ts : null;
}

export function isLicenseUsable(license: AsukaLicenseEntitlements | null | undefined): boolean {
  if (!license?.active) return false;
  if (license.status === 'active' || license.status === 'trial_active') {
    const expiresAt = toTimestamp(license.expiresAt);
    if (expiresAt !== null && Date.now() > expiresAt) {
      return isLicenseWithinGrace(license);
    }
    return true;
  }
  if (license.status === 'grace') return isLicenseWithinGrace(license);
  return false;
}

export function isLicenseWithinGrace(license: AsukaLicenseEntitlements | null | undefined): boolean {
  const graceUntil = toTimestamp(license?.graceUntil);
  if (graceUntil === null) return false;
  return Date.now() <= graceUntil;
}

export function canUseFeature(
  license: AsukaLicenseEntitlements | null | undefined,
  feature: AsukaLicenseFeature | string,
): boolean {
  if (!isLicenseUsable(license ?? null)) return false;
  const features = mergeLicenseFeaturesWithPlan(license?.plan ?? 'free', license?.features ?? {});
  return isLicenseFeatureEnabledInMap(features, feature);
}

export function hasPlan(
  license: AsukaLicenseEntitlements | null | undefined,
  plan: Extract<AsukaLicensePlan, 'starter' | 'pro' | 'agency'>,
): boolean {
  if (!isLicenseUsable(license ?? null)) return false;
  if (plan === 'starter') return license?.plan === 'starter' || license?.plan === 'pro' || license?.plan === 'agency';
  if (plan === 'pro') return license?.plan === 'pro' || license?.plan === 'agency';
  return license?.plan === 'agency';
}
