/**
 * Environment variable validation
 * Validates all required environment variables at runtime
 */

import { z } from "zod"

const envSchema = z
  .object({
    // Payment Provider Toggle
    PAYMENT_PROVIDER: z.enum(["stripe", "paypal", "manual"]).default("manual"),
    NEXT_PUBLIC_PAYMENT_PROVIDER: z.enum(["stripe", "paypal", "manual"]).default("manual"),

    // Stripe Configuration (required when PAYMENT_PROVIDER=stripe)
    NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: z.string().optional(),
    STRIPE_SECRET_KEY: z.string().optional(),
    STRIPE_WEBHOOK_SECRET: z.string().optional(),

    // PayPal Configuration (required when PAYMENT_PROVIDER=paypal)
    PAYPAL_CLIENT_ID: z.string().optional(),
    PAYPAL_CLIENT_SECRET: z.string().optional(),
    NEXT_PUBLIC_PAYPAL_CLIENT_ID: z.string().optional(),
    PAYPAL_API_URL: z.string().url().optional(),

    // Manual Payment Configuration (required when PAYMENT_PROVIDER=manual)
    ZELLE_EMAIL: z.string().email().optional(),
    CASHAPP_LINK: z.string().url().optional(),
    SUPPORT_EMAIL: z.string().email().optional(),

    // WooCommerce Configuration
    WC_BASE_URL: z.string().url("WooCommerce base URL must be a valid URL"),
    WC_CONSUMER_KEY: z.string().min(1, "WooCommerce consumer key is required"),
    WC_CONSUMER_SECRET: z.string().min(1, "WooCommerce consumer secret is required"),
    NEXT_PUBLIC_WC_BASE_URL: z.string().url("WooCommerce base URL must be a valid URL (public)").optional(),

    // FedEx Configuration (optional — currently disabled)
    FEDEX_CLIENT_ID: z.string().optional(),
    FEDEX_CLIENT_SECRET: z.string().optional(),
    FEDEX_ACCOUNT_NUMBER: z.string().optional(),
    FEDEX_API_URL: z.string().url().optional(),

    // Klaviyo Configuration (optional — currently disabled)
    KLAVIYO_API_KEY: z.string().optional(),
    KLAVIYO_ADMIN_EMAIL: z.string().email().optional(),

    // Security
    CHECKOUT_TOKEN_SECRET: z
      .string()
      .min(32, "Checkout token secret must be at least 32 characters"),

    // Optional Configuration
    CHECKOUT_TOKEN_TTL_SECONDS: z.string().optional().default("900"),
    ALLOWED_ORIGINS: z.string().optional(),
    NODE_ENV: z.enum(["development", "production", "test"]).optional().default("development"),
  })
  .superRefine((data, ctx) => {
    if (data.PAYMENT_PROVIDER === "stripe") {
      if (!data.STRIPE_SECRET_KEY || !data.STRIPE_SECRET_KEY.startsWith("sk_")) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: "Stripe secret key is required and must start with 'sk_'",
          path: ["STRIPE_SECRET_KEY"],
        })
      }
      if (!data.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY || !data.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY.startsWith("pk_")) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: "Stripe publishable key is required and must start with 'pk_'",
          path: ["NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY"],
        })
      }
      if (!data.STRIPE_WEBHOOK_SECRET || !data.STRIPE_WEBHOOK_SECRET.startsWith("whsec_")) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: "Stripe webhook secret is required and must start with 'whsec_'",
          path: ["STRIPE_WEBHOOK_SECRET"],
        })
      }
    }

    if (data.PAYMENT_PROVIDER === "paypal") {
      if (!data.PAYPAL_CLIENT_ID || data.PAYPAL_CLIENT_ID.length < 10) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: "PayPal client ID is required",
          path: ["PAYPAL_CLIENT_ID"],
        })
      }
      if (!data.PAYPAL_CLIENT_SECRET || data.PAYPAL_CLIENT_SECRET.length < 10) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: "PayPal client secret is required",
          path: ["PAYPAL_CLIENT_SECRET"],
        })
      }
      if (!data.NEXT_PUBLIC_PAYPAL_CLIENT_ID || data.NEXT_PUBLIC_PAYPAL_CLIENT_ID.length < 10) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: "PayPal public client ID is required",
          path: ["NEXT_PUBLIC_PAYPAL_CLIENT_ID"],
        })
      }
    }

    if (data.PAYMENT_PROVIDER === "manual") {
      if (!data.ZELLE_EMAIL) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: "Zelle email is required for manual payment",
          path: ["ZELLE_EMAIL"],
        })
      }
      if (!data.CASHAPP_LINK) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          message: "CashApp link is required for manual payment",
          path: ["CASHAPP_LINK"],
        })
      }
    }
  })

export type Env = z.infer<typeof envSchema>

let cachedEnv: Env | null = null

/**
 * Validate environment variables
 * Exits process if validation fails
 */
export const validateEnv = (): Env => {
  if (cachedEnv) {
    return cachedEnv
  }

  try {
    cachedEnv = envSchema.parse(process.env)
    return cachedEnv
  } catch (error) {
    console.error("❌ Environment validation failed:")
    console.error("")
    if (error instanceof z.ZodError) {
      error.issues.forEach((issue) => {
        console.error(`  • ${issue.path.join(".")}: ${issue.message}`)
      })
    }
    console.error("")
    console.error("Please check your .env.local file and ensure all required variables are set.")
    console.error("See .env.example for the template.")
    process.exit(1)
  }
}

/**
 * Get validated environment variables
 * Call this instead of process.env to ensure type safety
 */
export const env = validateEnv()
