/**
 * Prize Configuration Service
 * Loads prize config from JSON file and provides API for management
 */
import * as fs from 'fs';
import * as path from 'path';
import { fileURLToPath } from 'url';
import { logger } from '../utils/logger';
import type { PrizeConfig, LotteryRound } from '@gala/shared/types';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Default config path
const CONFIG_PATH = path.join(__dirname, '../../config/prizes.json');

export interface PrizeSettings {
    minStormDuration: number;
    revealAnimationDuration: number;
    allowRepeatWinner: boolean;
}

export interface PrizeConfigFile {
    prizes: PrizeConfig[];
    settings: PrizeSettings;
}

class PrizeConfigService {
    private config: PrizeConfigFile | null = null;
    private configPath: string;

    constructor() {
        this.configPath = CONFIG_PATH;
    }

    /**
     * Load config from file
     */
    async load(): Promise<void> {
        try {
            if (fs.existsSync(this.configPath)) {
                const content = fs.readFileSync(this.configPath, 'utf-8');
                this.config = JSON.parse(content);
                logger.info({
                    prizeCount: this.config?.prizes.length,
                    configPath: this.configPath
                }, 'Prize config loaded');
            } else {
                logger.warn({ configPath: this.configPath }, 'Prize config file not found, using defaults');
                this.config = this.getDefaults();
            }
        } catch (error) {
            logger.error({ error, configPath: this.configPath }, 'Failed to load prize config');
            this.config = this.getDefaults();
        }
    }

    /**
     * Get default configuration
     */
    private getDefaults(): PrizeConfigFile {
        return {
            prizes: [
                { round: 1 as LotteryRound, level: '第一轮抽奖', name: '幸运伴手礼', winnerCount: 7 },
                { round: 2 as LotteryRound, level: '第二轮抽奖', name: '幸运伴手礼', winnerCount: 3 },
                { round: 3 as LotteryRound, level: '第三轮抽奖', name: '幸运伴手礼', winnerCount: 4 },
                { round: 4 as LotteryRound, level: '第四轮抽奖', name: '幸运伴手礼', winnerCount: 1, zodiacFilter: 'horse' },
            ],
            settings: {
                minStormDuration: 3000,
                revealAnimationDuration: 2000,
                allowRepeatWinner: false,
            },
        };
    }

    /**
     * Get all prizes
     */
    getPrizes(): PrizeConfig[] {
        return this.config?.prizes || this.getDefaults().prizes;
    }

    /**
     * Get prize by round
     */
    getPrizeByRound(round: LotteryRound): PrizeConfig | undefined {
        return this.getPrizes().find(p => p.round === round);
    }

    /**
     * Get settings
     */
    getSettings(): PrizeSettings {
        return this.config?.settings || this.getDefaults().settings;
    }

    /**
     * Update prizes and save to file
     */
    async updatePrizes(prizes: PrizeConfig[]): Promise<{ success: boolean; error?: string }> {
        try {
            if (!this.config) {
                this.config = this.getDefaults();
            }
            this.config.prizes = prizes;
            await this.saveToFile();
            logger.info({ prizeCount: prizes.length }, 'Prizes updated');
            return { success: true };
        } catch (error) {
            logger.error({ error }, 'Failed to update prizes');
            return { success: false, error: (error as Error).message };
        }
    }

    /**
     * Update settings and save to file
     */
    async updateSettings(settings: Partial<PrizeSettings>): Promise<{ success: boolean; error?: string }> {
        try {
            if (!this.config) {
                this.config = this.getDefaults();
            }
            this.config.settings = { ...this.config.settings, ...settings };
            await this.saveToFile();
            logger.info({ settings: this.config.settings }, 'Prize settings updated');
            return { success: true };
        } catch (error) {
            logger.error({ error }, 'Failed to update settings');
            return { success: false, error: (error as Error).message };
        }
    }

    /**
     * Save config to file
     */
    private async saveToFile(): Promise<void> {
        const content = JSON.stringify(this.config, null, 2);
        fs.writeFileSync(this.configPath, content, 'utf-8');
    }

    /**
     * Get full config for API response
     */
    getFullConfig(): PrizeConfigFile {
        return this.config || this.getDefaults();
    }
}

export const prizeConfigService = new PrizeConfigService();
