/**
 * V3 website feature and write flags.
 *
 * Every flag defaults to `false`. There is no code path that enables V3 by
 * absence, by inference, or by parse fallback: only the exact literal string
 * `"true"` turns a flag on, and an unrecognised value is treated as off and
 * reported as a configuration problem.
 */

export type ProtocolVersion = "v2" | "v3";

/** V2 is the only default. Nothing may change this constant. */
export const DEFAULT_PROTOCOL_VERSION: ProtocolVersion = "v2";

export type V3FeatureFlags = {
  /** Renders V3 surfaces at all (read-only exploration). */
  readonly v3UiEnabled: boolean;
  /** Allows V3 read calls (indexer / view functions). */
  readonly v3ReadsEnabled: boolean;
  /** Allows any V3 state-changing transaction to be prepared. */
  readonly v3WritesEnabled: boolean;
  /** Allows V3 actions that move funds. Strictly narrower than writes. */
  readonly v3MoneyMovementEnabled: boolean;
  /** Asserts the audited-pilot operating envelope is live and ratified. */
  readonly v3AuditedPilotEnabled: boolean;
};

export const V3_FLAG_ENV_KEYS: Readonly<Record<keyof V3FeatureFlags, string>> = {
  v3UiEnabled: "NEXT_PUBLIC_VAULTFIRE_V3_UI",
  v3ReadsEnabled: "NEXT_PUBLIC_VAULTFIRE_V3_READS",
  v3WritesEnabled: "VAULTFIRE_V3_WRITES",
  v3MoneyMovementEnabled: "VAULTFIRE_V3_MONEY_MOVEMENT",
  v3AuditedPilotEnabled: "VAULTFIRE_V3_AUDITED_PILOT",
} as const;

/** Default-off flag set. Exported frozen so callers cannot mutate the default. */
export const DEFAULT_V3_FLAGS: V3FeatureFlags = Object.freeze({
  v3UiEnabled: false,
  v3ReadsEnabled: false,
  v3WritesEnabled: false,
  v3MoneyMovementEnabled: false,
  v3AuditedPilotEnabled: false,
});

export type FlagReadResult = {
  readonly flags: V3FeatureFlags;
  /** Non-empty when a value was present but not exactly "true" or "false". */
  readonly configErrors: readonly string[];
};

function readOne(
  env: Readonly<Record<string, string | undefined>>,
  key: string,
  errors: string[],
): boolean {
  const raw = env[key];
  if (raw === undefined || raw === "") return false;
  if (raw === "true") return true;
  if (raw === "false") return false;
  errors.push(`${key}: unrecognised value; treated as false`);
  return false;
}

/**
 * Reads flags from an environment map. Missing env, empty env, and malformed
 * values all yield the default-off flag set.
 */
export function readV3Flags(
  env: Readonly<Record<string, string | undefined>> = {},
): FlagReadResult {
  const errors: string[] = [];
  const flags: V3FeatureFlags = {
    v3UiEnabled: readOne(env, V3_FLAG_ENV_KEYS.v3UiEnabled, errors),
    v3ReadsEnabled: readOne(env, V3_FLAG_ENV_KEYS.v3ReadsEnabled, errors),
    v3WritesEnabled: readOne(env, V3_FLAG_ENV_KEYS.v3WritesEnabled, errors),
    v3MoneyMovementEnabled: readOne(env, V3_FLAG_ENV_KEYS.v3MoneyMovementEnabled, errors),
    v3AuditedPilotEnabled: readOne(env, V3_FLAG_ENV_KEYS.v3AuditedPilotEnabled, errors),
  };
  return { flags: Object.freeze(flags), configErrors: Object.freeze(errors) };
}

/**
 * Explicit, per-session version selection. `undefined`/absent selection is a
 * V2 session; there is no "auto" or "latest" option by design.
 */
export type VersionSelection = {
  /** Set only by a deliberate user action on a V3 surface. */
  readonly selectedVersion?: ProtocolVersion;
  /** True only when the user acknowledged the V3 risk copy in this session. */
  readonly v3Acknowledged?: boolean;
};

/** Never returns "v3" unless the user explicitly selected it and V3 UI is on. */
export function resolveActiveVersion(
  selection: VersionSelection = {},
  flags: V3FeatureFlags = DEFAULT_V3_FLAGS,
): ProtocolVersion {
  if (selection.selectedVersion !== "v3") return DEFAULT_PROTOCOL_VERSION;
  if (!flags.v3UiEnabled) return DEFAULT_PROTOCOL_VERSION;
  return "v3";
}
