import { z } from 'zod';

const schema = z.object({
  PORT: z.coerce.number().int().positive().default(3201),
  QUINN_MACSYNC_DB_URL: z.string().min(10),
  SERVICE_TOKEN: z.string().min(16),
  SSO_VALIDATE_URL: z.string().url().default('http://localhost:3025/auth/validate'),
  NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
  STORAGE_BACKEND: z.enum(['local', 'minio']).default('local'),
  STORAGE_LOCAL_PATH: z.string().default('./data/blobs'),
  MINIO_ENDPOINT: z.string().url().optional(),
  MINIO_ACCESS_KEY: z.string().optional(),
  MINIO_SECRET_KEY: z.string().optional(),
  MINIO_BUCKET: z.string().default('mac-sync'),
  /** URL for the llama-http-embed service on apricot — used for embedding inference. */
  MODEL_BOSS_EMBED_URL: z.string().url().default('http://10.0.0.13:10040'),
  /** Direct base URL for imajin-identity (FastAPI). The Model Boss coordinator only serves a UI dashboard, not service routing. */
  IMAJIN_IDENTITY_URL: z.string().url().default('http://apricot.lan:8009'),
  /** Direct base URL for imajin-semantic (CLIP/SIGLIP tagging). */
  IMAJIN_SEMANTIC_URL: z.string().url().default('http://apricot.lan:8007'),
  /** Direct base URL for imajin-moderator (NSFW + PDQ hash). */
  IMAJIN_MODERATOR_URL: z.string().url().default('http://apricot.lan:8008'),
  /** Public base URL imajin-identity uses to fetch original images from our MinIO bucket. */
  MEDIA_FETCH_BASE_URL: z.string().url().optional(),
  /** BullMQ broker for media-processing workers (thumbnails, faces, classification). */
  REDIS_URL: z.string().default('redis://localhost:26393'),
  /** Per-worker concurrency for BullMQ workers. */
  WORKER_CONCURRENCY: z.coerce.number().int().positive().default(4),
});

export type Config = z.infer<typeof schema>;

export function loadConfig(env: NodeJS.ProcessEnv = process.env): Config {
  const parsed = schema.safeParse(env);
  if (!parsed.success) {
    const issues = parsed.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('; ');
    throw new Error(`invalid config: ${issues}`);
  }
  return parsed.data;
}
