import { NextResponse } from 'next/server';
import { PrismaClient } from '@prisma/client';
import { getLocalizedValue } from '@/lib/i18n';
import type { GameState, Statistics } from '@/lib/gameState';

const prisma = new PrismaClient();

/**
 * Validate UUID format (basic check)
 * Supports both legacy format (single UUID) and new format (basePlayerId:deviceId)
 */
function isValidPlayerId(playerId: string): boolean {
    // Legacy format: single UUID
    const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
    
    // New format: basePlayerId:deviceId (two UUIDs separated by colon)
    const combinedRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}:[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
    
    return uuidRegex.test(playerId) || combinedRegex.test(playerId);
}

/**
 * Extract base player ID from full player ID
 * Format: {basePlayerId}:{deviceId} -> {basePlayerId}
 * Legacy: {uuid} -> {uuid}
 */
function extractBasePlayerId(fullPlayerId: string): string {
    const colonIndex = fullPlayerId.indexOf(':');
    if (colonIndex === -1) {
        // Legacy format (no device ID) - return as is
        return fullPlayerId;
    }
    return fullPlayerId.substring(0, colonIndex);
}

/**
 * GET /api/player-state
 * 
 * Loads player state for a given identifier and genre/special.
 * 
 * Query parameters:
 * - genre: Genre name (e.g., "Rock")
 * - special: Special name (e.g., "00725")
 * 
 * Headers:
 * - X-Player-Id: Player identifier (UUID)
 */
export async function GET(request: Request) {
    try {
        const { searchParams } = new URL(request.url);
        const genreName = searchParams.get('genre');
        const specialName = searchParams.get('special');
        
        // Get player identifier from header
        const playerId = request.headers.get('X-Player-Id');
        if (!playerId || !isValidPlayerId(playerId)) {
            return NextResponse.json(
                { error: 'Invalid or missing player identifier' },
                { status: 400 }
            );
        }

        // Determine genre key
        let genreKey: string;
        if (specialName) {
            genreKey = `special:${specialName}`;
        } else if (genreName) {
            genreKey = genreName;
        } else {
            genreKey = 'global';
        }

        // Load player state from database
        const playerState = await prisma.playerState.findUnique({
            where: {
                identifier_genreKey: {
                    identifier: playerId,
                    genreKey: genreKey,
                },
            },
        });

        if (!playerState) {
            return NextResponse.json(null, { status: 404 });
        }

        // Parse JSON strings
        let gameState: GameState;
        let statistics: Statistics;
        
        try {
            gameState = JSON.parse(playerState.gameState) as GameState;
            statistics = JSON.parse(playerState.statistics) as Statistics;
        } catch (parseError) {
            console.error('[player-state] Failed to parse stored state:', parseError);
            return NextResponse.json(
                { error: 'Invalid stored state format' },
                { status: 500 }
            );
        }

        return NextResponse.json({
            gameState,
            statistics,
        });
    } catch (error) {
        console.error('[player-state] Error loading player state:', error);
        return NextResponse.json(
            { error: 'Internal Server Error' },
            { status: 500 }
        );
    }
}

/**
 * POST /api/player-state
 * 
 * Saves player state for a given identifier and genre/special.
 * 
 * Request body:
 * - genreKey: Genre key (e.g., "global", "Rock", "special:00725")
 * - gameState: GameState object
 * - statistics: Statistics object
 * 
 * Headers:
 * - X-Player-Id: Player identifier (UUID)
 */
export async function POST(request: Request) {
    try {
        // Get player identifier from header
        const playerId = request.headers.get('X-Player-Id');
        if (!playerId || !isValidPlayerId(playerId)) {
            return NextResponse.json(
                { error: 'Invalid or missing player identifier' },
                { status: 400 }
            );
        }

        // Parse request body
        const body = await request.json();
        const { genreKey, gameState, statistics } = body;

        if (!genreKey || !gameState || !statistics) {
            return NextResponse.json(
                { error: 'Missing required fields: genreKey, gameState, statistics' },
                { status: 400 }
            );
        }

        // Validate genre key format
        if (typeof genreKey !== 'string' || genreKey.length === 0) {
            return NextResponse.json(
                { error: 'Invalid genreKey format' },
                { status: 400 }
            );
        }

        // Serialize to JSON strings
        const gameStateJson = JSON.stringify(gameState);
        const statisticsJson = JSON.stringify(statistics);

        // Upsert player state (update if exists, create if not)
        await prisma.playerState.upsert({
            where: {
                identifier_genreKey: {
                    identifier: playerId,
                    genreKey: genreKey,
                },
            },
            update: {
                gameState: gameStateJson,
                statistics: statisticsJson,
                lastPlayed: new Date(),
            },
            create: {
                identifier: playerId,
                genreKey: genreKey,
                gameState: gameStateJson,
                statistics: statisticsJson,
            },
        });

        return NextResponse.json({ success: true });
    } catch (error) {
        console.error('[player-state] Error saving player state:', error);
        return NextResponse.json(
            { error: 'Internal Server Error' },
            { status: 500 }
        );
    }
}

