
/**
 * Robust iTunes Refresh Script
 * 
 * Usage: 
 *   ADMIN_PASSWORD='your_password' node scripts/slow-refresh-itunes.js
 * 
 * Options:
 *   --force    Overwrite existing release years
 */

const API_URL = process.env.API_URL || 'http://localhost:3010';
const ADMIN_PASSWORD = process.env.ADMIN_PASSWORD;

if (!ADMIN_PASSWORD) {
    console.error('❌ Error: ADMIN_PASSWORD environment variable is required.');
    process.exit(1);
}

const FORCE_UPDATE = process.argv.includes('--force');
const USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36';

// Helper for delays
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));

// Helper to clean search terms
function cleanSearchTerm(text) {
    return text
        .replace(/_Unplugged/gi, '')
        .replace(/_Remastered/gi, '')
        .replace(/_Live/gi, '')
        .replace(/_Acoustic/gi, '')
        .replace(/_Radio Edit/gi, '')
        .replace(/_Extended/gi, '')
        .replace(/_/g, ' ')
        .trim();
}

async function main() {
    console.log(`🎵 Starting iTunes Refresh Script`);
    console.log(`   Target: ${API_URL}`);
    console.log(`   Force Update: ${FORCE_UPDATE}`);
    console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');

    try {
        // 1. Authenticate
        console.log('🔑 Authenticating...');
        const loginRes = await fetch(`${API_URL}/api/admin/login`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ password: ADMIN_PASSWORD })
        });

        if (!loginRes.ok) {
            throw new Error(`Login failed: ${loginRes.status} ${loginRes.statusText}`);
        }

        // We need to manually manage the cookie/header if the API uses cookies, 
        // but the Admin UI uses a custom header 'x-admin-auth'.
        // Let's verify if the login endpoint returns a token or if we just use the password/flag.
        // Looking at the code, the client sets 'x-admin-auth' to 'authenticated' in localStorage.
        // The API middleware likely checks a cookie or just this header?
        // Let's check lib/auth.ts... actually, let's just assume we need to send the header.
        // Wait, the frontend sets 'x-admin-auth' to 'authenticated' after successful login.
        // The middleware likely checks the session cookie set by the login route.

        // Let's get the cookie from the login response
        const cookie = loginRes.headers.get('set-cookie');
        const headers = {
            'Content-Type': 'application/json',
            'Cookie': cookie || '',
            'x-admin-auth': 'authenticated' // Just in case
        };

        // 2. Fetch Songs
        console.log('📥 Fetching song list...');
        const songsRes = await fetch(`${API_URL}/api/songs`, { headers });
        if (!songsRes.ok) throw new Error(`Failed to fetch songs: ${songsRes.status}`);

        const songs = await songsRes.json();
        console.log(`📊 Found ${songs.length} songs.`);

        let processed = 0;
        let updated = 0;
        let skipped = 0;
        let failed = 0;

        for (const song of songs) {
            processed++;
            const progress = `[${processed}/${songs.length}]`;

            // Skip if year exists and not forcing
            if (song.releaseYear && !FORCE_UPDATE) {
                // console.log(`${progress} Skipping "${song.title}" (Year: ${song.releaseYear})`);
                skipped++;
                continue;
            }

            console.log(`${progress} Processing: "${song.title}" by "${song.artist}"`);

            const cleanArtist = cleanSearchTerm(song.artist);
            const cleanTitle = cleanSearchTerm(song.title);
            console.log(`   → Searching: "${cleanTitle}" by "${cleanArtist}"`);

            // 3. Query iTunes with Retry Logic
            let year = null;
            let retries = 0;
            const MAX_RETRIES = 3;

            while (retries < MAX_RETRIES) {
                try {
                    const term = encodeURIComponent(`${cleanArtist} ${cleanTitle}`);
                    const itunesUrl = `https://itunes.apple.com/search?term=${term}&entity=song&limit=5`;

                    const res = await fetch(itunesUrl, {
                        headers: {
                            'User-Agent': USER_AGENT,
                            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
                            'Accept-Language': 'en-US,en;q=0.9'
                        }
                    });

                    if (res.status === 403 || res.status === 429) {
                        console.warn(`   ⚠️  iTunes Rate Limit (${res.status}). Pausing for 60s...`);
                        await sleep(60000);
                        retries++;
                        continue;
                    }

                    if (!res.ok) {
                        console.error(`   ❌ iTunes Error: ${res.status}`);
                        break;
                    }

                    const data = await res.json();

                    if (data.resultCount > 0) {
                        // Simple extraction logic (same as lib/itunes.ts)
                        let earliestYear = null;
                        const normalizedTitle = song.title.toLowerCase().replace(/[^\w\s]/g, '');
                        const normalizedArtist = song.artist.toLowerCase().replace(/[^\w\s]/g, '');

                        for (const result of data.results) {
                            const resTitle = result.trackName.toLowerCase().replace(/[^\w\s]/g, '');
                            const resArtist = result.artistName.toLowerCase().replace(/[^\w\s]/g, '');

                            if (resTitle.includes(normalizedTitle) && resArtist.includes(normalizedArtist)) {
                                if (result.releaseDate) {
                                    const y = new Date(result.releaseDate).getFullYear();
                                    if (!isNaN(y) && (earliestYear === null || y < earliestYear)) {
                                        earliestYear = y;
                                    }
                                }
                            }
                        }
                        year = earliestYear;
                    }
                    break; // Success

                } catch (e) {
                    console.error(`   ❌ Network Error: ${e.message}`);
                    retries++;
                    await sleep(5000);
                }
            }

            if (year) {
                if (year !== song.releaseYear) {
                    console.log(`   ✅ Found Year: ${year} (Old: ${song.releaseYear})`);

                    // 4. Update Song
                    const updateRes = await fetch(`${API_URL}/api/songs`, {
                        method: 'PUT',
                        headers,
                        body: JSON.stringify({
                            id: song.id,
                            title: song.title,
                            artist: song.artist,
                            releaseYear: year
                        })
                    });

                    if (updateRes.ok) {
                        updated++;
                    } else {
                        console.error(`   ❌ Failed to update API: ${updateRes.status}`);
                        failed++;
                    }
                } else {
                    console.log(`   Create (No Change): ${year}`);
                    skipped++;
                }
            } else {
                console.log(`   ⚠️  No year found.`);
                failed++;
            }

            // Rate Limit Delay (15s = 4 req/min)
            await sleep(15000);
        }

        console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
        console.log('✅ Done!');
        console.log(`Updated: ${updated} | Skipped: ${skipped} | Failed: ${failed}`);

    } catch (error) {
        console.error('❌ Fatal Error:', error);
    }
}

main();
