import "server-only";
import { z } from "zod";
import { getServerEnvironment } from "./env";

const real = z
  .string()
  .min(1)
  .refine(
    (value) => !/mock|replace[_-]?me|example\.(invalid|com)/i.test(value),
  );
const liveSchema = z.object({
  APPLICATION_MODE: z.literal("live"),
  FIREBASE_STORAGE_BUCKET: real.regex(/^[a-z0-9][a-z0-9._-]+[a-z0-9]$/),
  FIREBASE_AUTH_API_KEY: real,
  APPLICATION_SIGNING_SECRET: real.min(32),
  APPLICATION_NOTIFICATION_EMAIL: z.email().pipe(real),
  STAFF_EMAIL_ALLOWLIST: z
    .string()
    .transform((value) =>
      value.split(",").map((email) => email.trim().toLowerCase()),
    )
    .pipe(z.array(z.email().pipe(real)).min(1).max(50)),
  CRON_SECRET: real.min(32),
});
let hostedMockWarned = false;
export function parseApplicationConfig(
  input: Record<string, string | undefined>,
) {
  const hosted = Boolean(input.VERCEL || input.VERCEL_ENV);
  const mode =
    input.APPLICATION_MODE ??
    (hosted || input.CONTACT_MODE !== "mock" ? "disabled" : "mock");
  if (mode === "disabled") return { APPLICATION_MODE: "disabled" as const };
  if (mode === "preview") return { APPLICATION_MODE: "preview" as const };
  if (mode === "mock") {
    if (hosted) {
      if (!hostedMockWarned) {
        hostedMockWarned = true;
        console.warn(
          "APPLICATION_MODE=mock is local-only; the hosted deployment keeps the legacy application handoff.",
        );
      }
      return { APPLICATION_MODE: "disabled" as const };
    }
    if (input.CONTACT_MODE !== "mock")
      throw new Error(
        "Application mock mode requires an isolated local contact preview.",
      );
    return {
      APPLICATION_MODE: "mock" as const,
      APPLICATION_SIGNING_SECRET:
        "local-fixture-only-application-signing-secret",
      APPLICATION_NOTIFICATION_EMAIL: "staff@example.invalid",
      STAFF_EMAIL_ALLOWLIST: ["reviewer@example.invalid"],
      CRON_SECRET: "local-fixture-only-scheduler-secret",
    };
  }
  const parsed = liveSchema.safeParse(input);
  if (!parsed.success)
    throw new Error(
      `Invalid application configuration: ${[...new Set(parsed.error.issues.map((issue) => issue.path[0]))].join(", ")}`,
    );
  if (input.CONTACT_MODE !== "live")
    throw new Error("Live applications require live server configuration.");
  return parsed.data;
}
export type ApplicationConfig = Extract<
  ReturnType<typeof parseApplicationConfig>,
  { APPLICATION_MODE: "mock" | "live" }
>;
export const applicationServiceEnabled = (
  config: ReturnType<typeof parseApplicationConfig>,
): config is ApplicationConfig =>
  config.APPLICATION_MODE === "mock" || config.APPLICATION_MODE === "live";
export const getApplicationConfig = () => {
  const config = parseApplicationConfig(process.env);
  if (applicationServiceEnabled(config)) getServerEnvironment();
  return config;
};
