#!/usr/bin/env python3
import json
import mimetypes
import time
import urllib.request
import uuid
from pathlib import Path

PROJECT = Path('/data/video-pipeline/Channel-Loi-Co-Nhan/project/13062026-008-Gia-Dinh-Hung-Thinh-Nhan-Hoa-Hieu')
TTS_URL = 'http://192.168.1.201:3900/generate'
REF_AUDIO = Path('/data/video-pipeline/Youtube-Video-Maker/data/voices/template1/refaudio.mp3')
REF_TEXT = Path('/data/video-pipeline/Youtube-Video-Maker/data/voices/template1/reftext.txt')
OUT = PROJECT / 'output/intro/intro_audio.wav'
TEXT = 'Gia đình hưng thịnh nhờ ba chữ: Nhẫn, Hòa, Hiếu. Lời cổ nhân dạy.'


def multipart(fields, files):
    boundary = '----OmniVoiceBoundary' + uuid.uuid4().hex
    chunks = []
    for key, value in fields.items():
        chunks.append(f'--{boundary}\r\nContent-Disposition: form-data; name="{key}"\r\n\r\n{value}\r\n'.encode())
    for key, path in files.items():
        p = Path(path)
        mime = mimetypes.guess_type(str(p))[0] or 'application/octet-stream'
        chunks.append(
            f'--{boundary}\r\nContent-Disposition: form-data; name="{key}"; filename="{p.name}"\r\nContent-Type: {mime}\r\n\r\n'.encode()
            + p.read_bytes() + b'\r\n'
        )
    chunks.append(f'--{boundary}--\r\n'.encode())
    return boundary, b''.join(chunks)


def main():
    OUT.parent.mkdir(parents=True, exist_ok=True)
    ref_text = REF_TEXT.read_text(encoding='utf-8') if REF_TEXT.exists() else ''
    for attempt in range(1, 6):
        try:
            fields = {
                'text': TEXT,
                'language': 'vi',
                'ref_text': ref_text,
                'speed': '0.82',
                'num_step': '24',
                'guidance_scale': '2.0',
                'effect_preset': 'broadcast',
            }
            boundary, body = multipart(fields, {'ref_audio': REF_AUDIO})
            req = urllib.request.Request(
                TTS_URL,
                data=body,
                headers={'Content-Type': 'multipart/form-data; boundary=' + boundary},
                method='POST',
            )
            with urllib.request.urlopen(req, timeout=180) as resp:
                blob = resp.read()
            if not (blob[:4] == b'RIFF' and b'WAVE' in blob[:12]):
                raise RuntimeError(blob[:100])
            tmp = OUT.with_suffix('.tmp')
            tmp.write_bytes(blob)
            tmp.replace(OUT)
            print('created', OUT, OUT.stat().st_size)
            return
        except Exception as exc:
            print('retry', attempt, type(exc).__name__, exc, flush=True)
            if attempt == 5:
                raise
            time.sleep(10 * attempt)


if __name__ == '__main__':
    main()
