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

// Load environment variables
config()

/**
 * Configuration schema for the fixture system
 */
export const FixtureConfigSchema = z.object({
  environment: z.enum(['development', 'testing', 'staging', 'demo']),
  seed: z.string().default('veza-platform-2025'),
  locale: z.string().default('fr'),
  database: z.object({
    host: z.string().default('localhost'),
    port: z.number().default(5432),
    username: z.string().default('veza'),
    password: z.string().default('veza_password'),
    databases: z.object({
      main: z.string().default('veza_dev'),
      chat: z.string().default('veza_chat'),
      test: z.string().default('veza_test'),
    })
  }),
  redis: z.object({
    host: z.string().default('localhost'),
    port: z.number().default(6379),
    password: z.string().optional().nullable(),
  }),
  services: z.object({
    web: z.object({
      port: z.number().default(5176),
      url: z.string().default('http://localhost:5176')
    }),
    chat: z.object({
      port: z.number().default(8080),
      wsPort: z.number().default(8081),
      url: z.string().default('http://localhost:8080')
    }),
    stream: z.object({
      port: z.number().default(8082),
      wsPort: z.number().default(8083),
      url: z.string().default('http://localhost:8082')
    }),
    api: z.object({
      port: z.number().default(8000),
      url: z.string().default('http://localhost:8000')
    }),
    docs: z.object({
      port: z.number().default(3000),
      url: z.string().default('http://localhost:3000')
    })
  }),
  generation: z.object({
    users: z.object({
      count: z.number().default(100),
      adminCount: z.number().default(3),
      artistCount: z.number().default(20),
      producerCount: z.number().default(10),
    }),
    audio: z.object({
      trackCount: z.number().default(500),
      albumCount: z.number().default(50),
      playlistCount: z.number().default(100),
      genreCount: z.number().default(15),
    }),
    conversations: z.object({
      directCount: z.number().default(200),
      groupCount: z.number().default(50),
      channelCount: z.number().default(20),
      messagesPerConversation: z.number().default(50),
    }),
    performance: z.object({
      concurrentUsers: z.number().default(1000),
      messagesPerSecond: z.number().default(100),
      concurrentStreams: z.number().default(500),
    })
  }),
  paths: z.object({
    audioFiles: z.string().default('./fixtures/assets/audio'),
    images: z.string().default('./fixtures/assets/images'),
    exports: z.string().default('./fixtures/exports'),
  })
})

export type FixtureConfig = z.infer<typeof FixtureConfigSchema>

/**
 * Default configuration for different environments
 */
const environmentDefaults: Record<string, Partial<FixtureConfig>> = {
  development: {
    generation: {
      users: { count: 50, adminCount: 2, artistCount: 10, producerCount: 5 },
      audio: { trackCount: 200, albumCount: 20, playlistCount: 30, genreCount: 15 },
      conversations: { directCount: 50, groupCount: 10, channelCount: 5, messagesPerConversation: 30 },
    }
  },
  testing: {
    generation: {
      users: { count: 20, adminCount: 1, artistCount: 5, producerCount: 2 },
      audio: { trackCount: 50, albumCount: 5, playlistCount: 10, genreCount: 10 },
      conversations: { directCount: 10, groupCount: 3, channelCount: 2, messagesPerConversation: 20 },
    }
  },
  staging: {
    generation: {
      users: { count: 200, adminCount: 5, artistCount: 40, producerCount: 20 },
      audio: { trackCount: 1000, albumCount: 100, playlistCount: 200, genreCount: 15 },
      conversations: { directCount: 500, groupCount: 100, channelCount: 50, messagesPerConversation: 50 },
    }
  },
  demo: {
    generation: {
      users: { count: 30, adminCount: 2, artistCount: 8, producerCount: 5 },
      audio: { trackCount: 100, albumCount: 15, playlistCount: 20, genreCount: 12 },
      conversations: { directCount: 20, groupCount: 5, channelCount: 3, messagesPerConversation: 25 },
    }
  }
}

/**
 * Load configuration for a specific environment
 */
export function loadConfig(environment: string = 'development'): FixtureConfig {
  const baseConfig = {
    environment,
    seed: process.env.FIXTURES_SEED || 'veza-platform-2025',
    locale: process.env.FIXTURES_LOCALE || 'fr',
    database: {
      host: process.env.DB_HOST || 'localhost',
      port: parseInt(process.env.DB_PORT || '5432'),
      username: process.env.DB_USERNAME || 'veza',
      password: process.env.DB_PASSWORD || 'veza_password',
      databases: {
        main: process.env.DB_MAIN || 'veza_dev',
        chat: process.env.DB_CHAT || 'veza_chat',
        test: process.env.DB_TEST || 'veza_test',
      }
    },
    redis: {
      host: process.env.REDIS_HOST || 'localhost',
      port: parseInt(process.env.REDIS_PORT || '6379'),
      password: process.env.REDIS_PASSWORD,
    },
    // Apply environment-specific defaults
    ...environmentDefaults[environment],
  }

  return FixtureConfigSchema.parse(baseConfig)
}

/**
 * Global configuration instance
 */
export let globalConfig: FixtureConfig = loadConfig()

/**
 * Update global configuration
 */
export function setGlobalConfig(config: FixtureConfig): void {
  globalConfig = config
}