import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'
import { spawn } from 'child_process'

const __dirname = path.dirname(fileURLToPath(import.meta.url))
const dropsDir = path.join(__dirname, '../drops')

/**
 * Get all published drops by reading their meta.json files
 */
const getPublishedDrops = () => {
    const drops = fs
        .readdirSync(dropsDir, { withFileTypes: true })
        .filter((dirent) => dirent.isDirectory())
        .map((dirent) => dirent.name)

    const publishedDrops = drops.filter((dropName) => {
        const metaPath = path.join(dropsDir, dropName, 'public/meta.json')

        if (!fs.existsSync(metaPath)) {
            console.warn(
                `Warning: meta.json not found for drop "${dropName}", skipping...`,
            )
            return false
        }

        try {
            const meta = JSON.parse(fs.readFileSync(metaPath, 'utf-8'))
            return meta.published === true
        } catch (err) {
            console.error(
                `Error reading meta.json for drop "${dropName}":`,
                err.message,
            )
            return false
        }
    })

    return publishedDrops
}

/**
 * Build a single drop
 */
const buildDrop = (dropName) => {
    return new Promise((resolve, reject) => {
        console.log(`Building drop: ${dropName}`)

        const child = spawn('npm', ['run', 'build', '-w', `drops/${dropName}`], {
            stdio: 'inherit',
            shell: true,
        })

        child.on('close', (code) => {
            if (code === 0) {
                console.log(`✓ Successfully built: ${dropName}`)
                resolve()
            } else {
                reject(new Error(`Failed to build ${dropName} (exit code ${code})`))
            }
        })

        child.on('error', reject)
    })
}

/**
 * Build all published drops
 */
const buildAllPublishedDrops = async () => {
    const publishedDrops = getPublishedDrops()

    if (publishedDrops.length === 0) {
        console.log('No published drops found.')
        return
    }

    console.log(`Found ${publishedDrops.length} published drop(s):`, publishedDrops)
    console.log('Starting builds...\n')

    for (const dropName of publishedDrops) {
        try {
            await buildDrop(dropName)
        } catch (err) {
            console.error(`Error building ${dropName}:`, err.message)
            process.exit(1)
        }
    }

    console.log('\n✓ All published drops built successfully!')
}

buildAllPublishedDrops().catch((err) => {
    console.error('Build failed:', err)
    process.exit(1)
})
