#!/usr/bin/env python3
"""Regeneriert einzelne Audio-IDs.  Usage: python regenerate-one.py r_wp_geo_villach r_xxx ..."""
import json, os, sys, subprocess, tempfile, shutil

KEY = os.environ.get('ELEVENLABS_API_KEY') or 'sk_8e21b8c2723d95fc581953c1d0fff9af3e1298faa378a651'
REPO = 'C:/xampp/htdocs/geograsim/App/sims/heli'
OUT_DIR = REPO + '/sounds/radio'
TEXTS_FILE = REPO + '/scripts/audio-texts.json'
MAP_FILE = REPO + '/data/aussprache-map.json'
DUR_FILE = REPO + '/data/audio-durations.json'

VOICE_SARAH = 'EXAVITQu4vr4xnSDxMaL'
VOICE_BELLA = 'hpp4J3VqNfWAUOO0d1Us'

def voice_for(aid):
    # Tower-Lotsin (Sarah): mission_intro/start sowie alle r_tower* (auch r_tower1/2/3/4 ohne Unterstrich)
    if aid.startswith('r_mission_intro_') or aid.startswith('r_mission_start_') or aid.startswith('r_tower'):
        return VOICE_SARAH, 'Sarah'
    return VOICE_BELLA, 'Bella'

def apply_pron(text, mapping):
    for k in sorted(mapping.keys(), key=len, reverse=True):
        text = text.replace(k, mapping[k])
    return text

def generate(aid, text, voice_id):
    out = OUT_DIR + '/' + aid + '.mp3'
    if os.path.exists(out):
        shutil.copy(out, out + '.bak-pre-regen')
    body = json.dumps({
        'text': text, 'model_id': 'eleven_multilingual_v2',
        'voice_settings': {'stability': 0.55, 'similarity_boost': 0.75, 'style': 0.1, 'use_speaker_boost': True}
    }, ensure_ascii=False)
    with tempfile.NamedTemporaryFile(mode='w', encoding='utf-8', suffix='.json', delete=False) as f:
        f.write(body); bpath = f.name
    r = subprocess.run(['curl','-sS','-w','%{http_code}','-o',out,
        '-X','POST','https://api.elevenlabs.io/v1/text-to-speech/' + voice_id,
        '-H','xi-api-key: ' + KEY,
        '-H','Content-Type: application/json; charset=utf-8',
        '--data-binary','@' + bpath], capture_output=True, text=True, timeout=90)
    os.unlink(bpath)
    return ('ok' if r.stdout.strip() == '200' else 'err-' + r.stdout), os.path.getsize(out) if os.path.exists(out) else 0

def main():
    aids = sys.argv[1:]
    if not aids:
        print(__doc__); sys.exit(1)
    texts = json.load(open(TEXTS_FILE, 'r', encoding='utf-8'))
    pron = json.load(open(MAP_FILE, 'r', encoding='utf-8'))['pronunciations']
    durs = json.load(open(DUR_FILE, 'r', encoding='utf-8'))
    for aid in aids:
        if aid not in texts:
            print(f'  -- {aid}: nicht in audio-texts.json'); continue
        text = texts[aid]
        tts = apply_pron(text, pron)
        voice, label = voice_for(aid)
        status, size = generate(aid, tts, voice)
        print(f'  {status:6s} {aid:40s} {size//1024}K [{label}]  text="{text[:60]}..."')
        if status == 'ok':
            durs['durations'].pop(aid, None)
    json.dump(durs, open(DUR_FILE, 'w', encoding='utf-8'), indent=2, ensure_ascii=False)

if __name__ == '__main__':
    main()
