import fs from 'fs'
import path from 'path'
import { configService } from './ConfigService'

interface PortMap {
    php: Record<string, number>;
    mariadb: Record<string, number>;
}

export class PortMappingService {
    private configFile: string
    private portMap: PortMap = { php: {}, mariadb: {} }
    private nextPhpPort = 9001
    private nextMariaDbPort = 3306

    constructor() {
        this.configFile = path.join(configService.getBasePath(), 'port_mappings.json')
        this.load()
    }

    private load() {
        if (fs.existsSync(this.configFile)) {
            try {
                this.portMap = JSON.parse(fs.readFileSync(this.configFile, 'utf-8'))

                const phpPorts = Object.values(this.portMap.php || {})
                if (phpPorts.length > 0) this.nextPhpPort = Math.max(...phpPorts) + 1

                // Backward compatibility: switch mysql to mariadb
                if (!this.portMap.mariadb) {
                    this.portMap.mariadb = (this.portMap as any).mysql || {}
                    delete (this.portMap as any).mysql
                    this.save()
                }

                const mariaDbPorts = Object.values(this.portMap.mariadb)
                if (mariaDbPorts.length > 0) this.nextMariaDbPort = Math.max(...mariaDbPorts) + 1
            } catch (e) {
                console.error('Failed to load port mappings', e)
            }
        }
    }

    private save() {
        fs.writeFileSync(this.configFile, JSON.stringify(this.portMap, null, 2))
    }

    getPhpPort(version: string): number {
        if (!this.portMap.php[version]) {
            this.portMap.php[version] = this.nextPhpPort++
            this.save()
        }
        return this.portMap.php[version]
    }

    getMariaDbPort(version: string): number {
        if (!this.portMap.mariadb[version]) {
            this.portMap.mariadb[version] = this.nextMariaDbPort++
            this.save()
        }
        return this.portMap.mariadb[version]
    }
}

export const portMappingService = new PortMappingService()
