import { DomainError } from "../shared/errors.ts";

export interface AppEnvironment {
  readonly nodeEnv: "development" | "test" | "production";
  readonly port: number;
  readonly appOrigin: URL;
  readonly appTimezone: string;
  readonly paypalMode: "disabled" | "sandbox" | "live";
}

export function parseEnvironment(source: NodeJS.ProcessEnv): AppEnvironment {
  const nodeEnv = source.NODE_ENV ?? "development";
  if (!(["development", "test", "production"] as const).includes(nodeEnv as never)) throw new DomainError("INVALID_ENV", "NODE_ENV is invalid.");
  const port = Number(source.PORT ?? 3000);
  if (!Number.isInteger(port) || port < 1 || port > 65_535) throw new DomainError("INVALID_ENV", "PORT is invalid.");
  let appOrigin: URL;
  try { appOrigin = new URL(source.APP_ORIGIN ?? "http://localhost:3000"); }
  catch { throw new DomainError("INVALID_ENV", "APP_ORIGIN is invalid."); }
  const appTimezone = source.APP_TIMEZONE ?? "UTC";
  try { new Intl.DateTimeFormat("en", { timeZone: appTimezone }).format(); }
  catch { throw new DomainError("INVALID_ENV", "APP_TIMEZONE is invalid."); }
  const paypalMode = source.PAYPAL_MODE ?? "disabled";
  if (!(["disabled", "sandbox", "live"] as const).includes(paypalMode as never)) throw new DomainError("INVALID_ENV", "PAYPAL_MODE is invalid.");
  if (nodeEnv === "production") {
    if (source.APP_DEBUG === "true") throw new DomainError("UNSAFE_PRODUCTION_ENV", "APP_DEBUG must be false in production.");
    if (appOrigin.protocol !== "https:") throw new DomainError("UNSAFE_PRODUCTION_ENV", "Production APP_ORIGIN must use HTTPS.");
    if (!source.SESSION_SECRET || source.SESSION_SECRET.length < 32) throw new DomainError("UNSAFE_PRODUCTION_ENV", "A strong SESSION_SECRET is required.");
    if (!source.KYC_ENCRYPTION_KEY || source.KYC_ENCRYPTION_KEY.length < 32) throw new DomainError("UNSAFE_PRODUCTION_ENV", "A dedicated KYC encryption key is required.");
    if (paypalMode === "live" && source.PAYPAL_ACCEPTANCE_PASSED !== "true") throw new DomainError("UNSAFE_PRODUCTION_ENV", "PayPal live mode requires recorded acceptance.");
  }
  return { nodeEnv: nodeEnv as AppEnvironment["nodeEnv"], port, appOrigin, appTimezone, paypalMode: paypalMode as AppEnvironment["paypalMode"] };
}
