import gradio as gr
import edge_tts
import asyncio
import tempfile
import re
import emoji
from flask import Flask, request, jsonify, render_template_string

app = Flask(__name__)

# Функция для очистки текста от нежелательных символов и эмодзи
def clean_text(text):
    # Удаление указанных символов
    text = re.sub(r'[*_~><]', '', text)
    # Удаление эмодзи
    text = emoji.replace_emoji(text, replace='')
    return text

# Get all available voices
async def get_voices():
    voices = await edge_tts.list_voices()
    return {f"{v['ShortName']} - {v['Locale']} ({v['Gender']})": v['ShortName'] for v in voices}

# Text-to-speech function
async def text_to_speech(text, voice, rate, pitch):
    if not text.strip():
        return None, "Пожалуйста, введите текст для озвучки."
    if not voice:
        return None, "Пожалуйста, выберите голос."
    
    # Очистка текста
    text = clean_text(text)
    
    voice_short_name = voice.split(" - ")[0]
    rate_str = f"{rate:+d}%"
    pitch_str = f"{pitch:+d}Hz"
    communicate = edge_tts.Communicate(text, voice_short_name, rate=rate_str, pitch=pitch_str)
    with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmp_file:
        tmp_path = tmp_file.name
        try:
            await communicate.save(tmp_path)
        except Exception as e:
            return None, f"Произошла ошибка при конвертации текста в речь: {str(e)}"
    return tmp_path, None

# HTML шаблон
HTML_TEMPLATE = """
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Озвучка с музыкальной атмосферой</title>
    <style>
        body {
            background-color: white;
            color: #FF6347; /* Томатный оранжевый */
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
        }

        header {
            background-color: #FF6347;
            color: white;
            padding: 10px 20px;
            text-align: center;
        }

        .container {
            padding: 20px;
        }

        .audio-control {
            position: fixed;
            bottom: 20px;
            left: 20px;
            background-color: white;
            border: 1px solid #FF6347;
            padding: 10px;
            border-radius: 5px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }

        button {
            background-color: #FF6347;
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 5px;
            cursor: pointer;
            margin-top: 10px;
        }

        button:hover {
            background-color: #FF4500; /* Темный томатный оранжевый */
        }
    </style>
</head>
<body>
    <header>
        <h1>Озвучка с музыкальной атмосферой</h1>
    </header>
    <div class="container">
        <textarea id="text-input" rows="5" placeholder="Введите текст для озвучки"></textarea>
        <br>
        <select id="voice-select">
            <!-- Опции будут заполнены через JavaScript -->
        </select>
        <br>
        <label for="rate-slider">Скорость озвучки:</label>
        <input type="range" id="rate-slider" min="-50" max="50" value="0" step="1">
        <br>
        <label for="pitch-slider">Тон озвучки:</label>
        <input type="range" id="pitch-slider" min="-20" max="20" value="0" step="1">
        <br>
        <button onclick="generateAudio()">Озвучить</button>
        <br>
        <audio id="audio-player" controls style="display:none;"></audio>
    </div>
    <div class="audio-control">
        <label for="atmosphere-select">Атмосфера:</label>
        <select id="atmosphere-select">
            <option value="dynamic">Динамичная</option>
            <option value="calm">Спокойная</option>
        </select>
        <br>
        <button onclick="toggleMusic()">Выключить музыку</button>
        <audio id="background-music" loop></audio>
    </div>
    <script>
        let voices = [];
        let currentMusic = null;

        document.addEventListener('DOMContentLoaded', () => {
            fetch('/get_voices')
                .then(response => response.json())
                .then(data => {
                    voices = data;
                    const voiceSelect = document.getElementById('voice-select');
                    Object.keys(voices).forEach(key => {
                        const option = document.createElement('option');
                        option.value = voices[key];
                        option.textContent = key;
                        voiceSelect.appendChild(option);
                    });
                });

            const atmosphereSelect = document.getElementById('atmosphere-select');
            atmosphereSelect.addEventListener('change', () => {
                changeMusic(atmosphereSelect.value);
            });

            changeMusic(atmosphereSelect.value); // Устанавливаем музыку по умолчанию
        });

        function generateAudio() {
            const text = document.getElementById('text-input').value;
            const voice = document.getElementById('voice-select').value;
            const rate = document.getElementById('rate-slider').value;
            const pitch = document.getElementById('pitch-slider').value;

            if (!text.trim()) {
                alert('Пожалуйста, введите текст для озвучки.');
                return;
            }
            if (!voice) {
                alert('Пожалуйста, выберите голос.');
                return;
            }

            fetch('/tts', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ text, voice, rate, pitch })
            })
            .then(response => response.json())
            .then(data => {
                if (data.warning) {
                    alert(data.warning);
                } else {
                    const audioPlayer = document.getElementById('audio-player');
                    audioPlayer.src = data.audio;
                    audioPlayer.style.display = 'block';
                    audioPlayer.play();
                    audioPlayer.addEventListener('ended', () => {
                        document.getElementById('background-music').play();
                    });
                }
            });
        }

        function changeMusic(atmosphere) {
            const backgroundMusic = document.getElementById('background-music');
            backgroundMusic.src = `/music/${atmosphere}.mp3`;
            backgroundMusic.play();
            currentMusic = atmosphere;
        }

        function toggleMusic() {
            const backgroundMusic = document.getElementById('background-music');
            if (backgroundMusic.paused) {
                backgroundMusic.play();
                document.querySelector('.audio-control button').textContent = 'Выключить музыку';
            } else {
                backgroundMusic.pause();
                document.querySelector('.audio-control button').textContent = 'Включить музыку';
            }
        }
    </script>
</body>
</html>
"""

@app.route('/get_voices', methods=['GET'])
async def get_voices_route():
    voices = await get_voices()
    return jsonify(voices)

@app.route('/tts', methods=['POST'])
async def tts_route():
    data = request.get_json()
    text = data.get('text', '')
    voice = data.get('voice', '')
    rate = data.get('rate', 0)
    pitch = data.get('pitch', 0)
    
    audio, warning = await text_to_speech(text, voice, rate, pitch)
    if warning:
        return jsonify({'warning': warning})
    else:
        return jsonify({'audio': audio})

@app.route('/')
def index():
    return render_template_string(HTML_TEMPLATE)

@app.route('/music/<path:path>')
def serve_music(path):
    return app.send_static_file(f'music/{path}')

if __name__ == "__main__":
    app.run(debug=True)