import { config as loadDotenv } from 'dotenv'
import { z } from 'zod'

// Tests must be hermetic: never pick up a developer's local .env.
if (process.env.NODE_ENV !== 'test') loadDotenv({ quiet: true })

/**
 * Parse `process.env` against a schema, failing fast with every problem listed at once.
 * Each app composes its own schema from the fragments below.
 */
export function loadEnv<S extends z.ZodType>(schema: S, source: NodeJS.ProcessEnv = process.env): z.infer<S> {
  const result = schema.safeParse(source)
  if (!result.success) {
    const problems = result.error.issues.map(i => `  - ${i.path.join('.')}: ${i.message}`).join('\n')
    throw new Error(`Invalid environment configuration:\n${problems}`)
  }
  return result.data
}

const csv = z
  .string()
  .optional()
  .transform(v => (v ? v.split(',').map(s => s.trim()).filter(Boolean) : []))

export const baseEnv = z.object({
  NODE_ENV: z.enum(['development', 'test', 'production']).default('development'),
  LOG_LEVEL: z.enum(['fatal', 'error', 'warn', 'info', 'debug', 'trace']).default('info'),
})

export const databaseEnv = z.object({
  DATABASE_URL: z.url(),
})

export const magentoEnv = z.object({
  MAGENTO_BASE_URL: z.url().transform(u => u.replace(/\/$/, '')),
  MAGENTO_ACCESS_TOKEN: z.string().min(1),
  MAGENTO_ACCESS_TOKEN_SECRET: z.string().optional(),
  MAGENTO_CONSUMER_KEY: z.string().optional(),
  MAGENTO_CONSUMER_SECRET: z.string().optional(),
  /** Store view codes to sync. Empty = every active store view. */
  MAGENTO_STORE_CODES: csv,
  /** Store view used when a caller does not name one. */
  MAGENTO_DEFAULT_STORE: z.string().default('default'),
  /** MSI stock id for salable-qty lookups (1 = default stock). */
  MAGENTO_STOCK_ID: z.coerce.number().int().positive().default(1),
})

/** Feature switches shared by sync, catalog API and MCP server. */
export const featureEnv = z.object({
  /** false when stock is not managed in Magento: no inventory sync, no stock tools or stock checks. */
  CATALOG_STOCK_ENABLED: z.enum(['true', 'false']).default('true').transform(v => v === 'true'),
})

export const catalogApiClientEnv = z.object({
  CATALOG_API_URL: z.url().transform(u => u.replace(/\/$/, '')),
  CATALOG_API_TOKEN: z.string().min(24, 'use at least 24 random characters'),
})

export { csv as csvEnv }
