import { ExactGitShaSchema, type LoadedFeatureDefinition, type RuntimeDefinitionResolution } from "./definitions";
import type { DeliveryFeatureStateRecord } from "../store";

export interface FeatureStateProvider { getDeliveryFeatureState(featureId: string): DeliveryFeatureStateRecord | null; }
export interface TrustedRuntimeIdentity { componentId: string; deployedSha: string; subjectId?: string; }
/** Eligibility is controller-derived and bound to the exact state/deployment, never request flags. */
export interface AudienceEligibility { featureId: string; definitionDigest: string; stateRevision: number; deploymentId: string; deployedSha: string; subjectId: string; tier: "INTERNAL" | "CANARY"; eligible: boolean; }
export interface AudienceEligibilityProvider { eligibility(identity: TrustedRuntimeIdentity, state: DeliveryFeatureStateRecord): AudienceEligibility | null; }
export interface ControllerReadinessDecision { admitted: boolean; deploymentId?: string; deployedSha?: string; reason?: string; }
export interface FeatureEvaluation { state: "OFF" | "INTERNAL" | "CANARY" | "ON"; enabled: boolean; reason: "enabled" | "missing-definition" | "invalid-definition" | "definition-unavailable" | "expired-definition" | "missing-state" | "stale-definition" | "invalid-observed-identity" | "corrupt-stored-identity" | "sha-mismatch" | "readiness-unavailable" | "eligibility-unavailable" | "ineligible-audience" | "retired"; }
const disabled = (reason: Exclude<FeatureEvaluation["reason"], "enabled">): FeatureEvaluation => ({ state: "OFF", enabled: false, reason });

/** Fail closed against malformed identities, corrupted persisted state, absent readiness, and absent audience context. */
export function evaluateFeature(
  input: LoadedFeatureDefinition | RuntimeDefinitionResolution | undefined,
  provider: FeatureStateProvider,
  identity: TrustedRuntimeIdentity,
  readiness?: ControllerReadinessDecision,
  audience?: AudienceEligibilityProvider,
  now: () => number = () => Date.now(),
): FeatureEvaluation {
  if (!input) return disabled("missing-definition");
  if ("available" in input) { if (!input.available) return disabled(input.reason); input = input.definition; }
  const definition = input;
  if (now() > Date.parse(`${definition.definition.reviewDate}T23:59:59.999Z`)) return disabled("expired-definition");
  if (!ExactGitShaSchema.safeParse(identity.deployedSha).success) return disabled("invalid-observed-identity");
  try {
    const state = provider.getDeliveryFeatureState(definition.definition.id);
    if (!state || state.state === "OFF") return disabled("missing-state");
    if (state.definitionDigest !== definition.digest) return disabled("stale-definition");
    if (state.state === "RETIRED") return disabled("retired");
    if (!ExactGitShaSchema.safeParse(state.deployedSha).success) return disabled("corrupt-stored-identity");
    if (!readiness?.admitted || !readiness.deploymentId || !ExactGitShaSchema.safeParse(readiness.deployedSha).success) return disabled("readiness-unavailable");
    if (state.deployedSha !== identity.deployedSha || readiness.deployedSha !== identity.deployedSha) return disabled("sha-mismatch");
    if (state.state === "ON") return { state: "ON", enabled: true, reason: "enabled" };
    if (!audience || !identity.subjectId) return disabled("eligibility-unavailable");
    const eligibility = audience.eligibility(identity, state);
    if (!eligibility || eligibility.featureId !== state.featureId || eligibility.definitionDigest !== state.definitionDigest || eligibility.stateRevision !== state.revision || eligibility.deploymentId !== readiness.deploymentId || eligibility.deployedSha !== identity.deployedSha || eligibility.subjectId !== identity.subjectId || eligibility.tier !== state.state || !eligibility.eligible) return disabled("ineligible-audience");
    return { state: state.state, enabled: true, reason: "enabled" };
  } catch { return disabled("readiness-unavailable"); }
}
