#!/usr/bin/env python3
"""
对讲机音频转换器
将文字转换为对讲机可以发送的音频信号
"""

import sys
import numpy as np
import wave
import time
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent / "src"))

from src.morse_protocol_integration import MorseProtocolSystem


class WalkieTalkieAudioConverter:
    """
    对讲机音频转换器

    功能：
    1. 文字 → 摩斯密码 → 音频信号
    2. 音频信号 → 摩斯密码 → 文字
    3. 生成WAV音频文件
    4. 实时播放音频
    """

    def __init__(self,
                 frequency: int = 800,
                 sample_rate: int = 44100,
                 dot_duration: float = 0.1):
        """
        初始化转换器

        参数：
        frequency: 音频频率（Hz），建议600-1000Hz
        sample_rate: 采样率（Hz），标准44100Hz
        dot_duration: 点的持续时间（秒）
        """
        self.frequency = frequency
        self.sample_rate = sample_rate
        self.dot_duration = dot_duration
        self.dash_duration = dot_duration * 3

        # 初始化摩斯系统
        self.morse_system = MorseProtocolSystem(
            enable_ai=False,
            enable_protocol=False
        )

    def text_to_morse(self, text: str) -> str:
        """
        文字转摩斯密码

        参数：
        text: 输入文字

        返回：
        摩斯密码字符串
        """
        return self.morse_system.encode(text)

    def morse_to_audio(self, morse_code: str) -> tuple:
        """
        摩斯密码转音频信号

        参数：
        morse_code: 摩斯密码字符串

        返回：
        (audio_data, sample_rate)
        """
        audio_samples = []

        for char in morse_code:
            if char == '・':  # 点
                # 生成点音
                tone = self._generate_tone(self.dot_duration)
                audio_samples.extend(tone)
                # 点后间隔
                silence = self._generate_silence(self.dot_duration)
                audio_samples.extend(silence)

            elif char == '-':  # 划
                # 生成划音
                tone = self._generate_tone(self.dash_duration)
                audio_samples.extend(tone)
                # 划后间隔
                silence = self._generate_silence(self.dot_duration)
                audio_samples.extend(silence)

            elif char == ' ':  # 字符内间隔
                silence = self._generate_silence(self.dot_duration * 2)
                audio_samples.extend(silence)

            elif char == '/':  # 单词间隔
                silence = self._generate_silence(self.dot_duration * 4)
                audio_samples.extend(silence)

        return np.array(audio_samples, dtype=np.float32), self.sample_rate

    def text_to_audio(self, text: str) -> tuple:
        """
        文字直接转音频（一步完成）

        参数：
        text: 输入文字

        返回：
        (audio_data, sample_rate)
        """
        # 先转摩斯
        morse = self.text_to_morse(text)
        print(f"摩斯密码: {morse}")

        # 再转音频
        return self.morse_to_audio(morse)

    def save_to_wav(self, audio_data, sample_rate, filename: str):
        """
        保存音频为WAV文件

        参数：
        audio_data: 音频数据
        sample_rate: 采样率
        filename: 文件名
        """
        # 转换为16位整数
        audio_int16 = (audio_data * 32767).astype(np.int16)

        # 保存WAV文件
        with wave.open(filename, 'w') as wav_file:
            wav_file.setnchannels(1)  # 单声道
            wav_file.setsampwidth(2)  # 16位
            wav_file.setframerate(sample_rate)
            wav_file.writeframes(audio_int16.tobytes())

        print(f"✓ 音频已保存: {filename}")

    def _generate_tone(self, duration: float) -> np.ndarray:
        """
        生成音频音调

        参数：
        duration: 持续时间（秒）

        返回：
        音频样本数组
        """
        # 生成时间轴
        t = np.linspace(0, duration, int(self.sample_rate * duration), False)

        # 生成正弦波
        tone = 0.5 * np.sin(2 * np.pi * self.frequency * t)

        return tone

    def _generate_silence(self, duration: float) -> np.ndarray:
        """
        生成静音

        参数：
        duration: 持续时间（秒）

        返回：
        静音样本数组
        """
        num_samples = int(self.sample_rate * duration)
        return np.zeros(num_samples, dtype=np.float32)

    def play_audio(self, audio_data, sample_rate):
        """
        播放音频（需要sounddevice库）

        参数：
        audio_data: 音频数据
        sample_rate: 采样率
        """
        try:
            import sounddevice as sd
            sd.play(audio_data, sample_rate)
            sd.wait()  # 等待播放完成
            print("✓ 播放完成")
        except ImportError:
            print("⚠️  需要安装 sounddevice: pip install sounddevice")
        except Exception as e:
            print(f"✗ 播放失败: {e}")

    def get_audio_info(self, audio_data, sample_rate) -> dict:
        """
        获取音频信息

        参数：
        audio_data: 音频数据
        sample_rate: 采样率

        返回：
        音频信息字典
        """
        duration = len(audio_data) / sample_rate
        max_amplitude = np.max(np.abs(audio_data))

        return {
            'duration': duration,
            'sample_rate': sample_rate,
            'num_samples': len(audio_data),
            'max_amplitude': max_amplitude,
            'frequency': self.frequency,
            'dot_duration': self.dot_duration,
            'dash_duration': self.dash_duration
        }


def demo_conversion():
    """演示音频转换"""
    print("="*60)
    print("  对讲机音频转换演示")
    print("="*60)

    # 创建转换器
    converter = WalkieTalkieAudioConverter(
        frequency=800,        # 800Hz音调
        sample_rate=44100,    # 标准采样率
        dot_duration=0.1      # 点=100ms
    )

    # 测试文字
    test_messages = [
        "SOS",
        "HELP",
        "Hello World",
        "紧急求助"
    ]

    for text in test_messages:
        print(f"\n{'='*60}")
        print(f"输入: {text}")
        print('='*60)

        # 转换为摩斯
        morse = converter.text_to_morse(text)
        print(f"摩斯: {morse}")

        # 转换为音频
        audio, sr = converter.text_to_audio(text)

        # 获取音频信息
        info = converter.get_audio_info(audio, sr)
        print(f"\n音频信息:")
        print(f"  时长: {info['duration']:.2f} 秒")
        print(f"  采样率: {info['sample_rate']} Hz")
        print(f"  样本数: {info['num_samples']}")
        print(f"  频率: {info['frequency']} Hz")
        print(f"  点时长: {info['dot_duration']*1000:.0f} ms")
        print(f"  划时长: {info['dash_duration']*1000:.0f} ms")

        # 保存为WAV文件
        filename = f"morse_{text.replace(' ', '_').replace('/', '_')}.wav"
        converter.save_to_wav(audio, sr, filename)

        # 询问是否播放
        play = input(f"\n是否播放音频? (y/n): ").lower()
        if play == 'y':
            print("播放中...")
            converter.play_audio(audio, sr)

    print(f"\n{'='*60}")
    print("  转换完成！")
    print('='*60)
    print("\n生成的WAV文件可以直接：")
    print("  1. 用音频播放器播放")
    print("  2. 连接到对讲机MIC接口")
    print("  3. 通过对讲机发送")


def interactive_converter():
    """交互式转换器"""
    print("""
╔══════════════════════════════════════════════════════════╗
║           对讲机摩斯音频转换器                           ║
║                                                          ║
║  将文字转换为对讲机可以发送的摩斯密码音频               ║
╚══════════════════════════════════════════════════════════╝
    """)

    # 创建转换器
    converter = WalkieTalkieAudioConverter()

    print("\n设置:")
    print(f"  音频频率: {converter.frequency} Hz")
    print(f"  采样率: {converter.sample_rate} Hz")
    print(f"  点时长: {converter.dot_duration} 秒")
    print(f"  划时长: {converter.dash_duration} 秒")

    # 主循环
    while True:
        print("\n" + "="*60)
        print("菜单:")
        print("  1. 文字转摩斯音频")
        print("  2. 调整设置")
        print("  3. 演示模式")
        print("  4. 退出")

        choice = input("\n选择 (1-4): ").strip()

        if choice == "1":
            # 文字转音频
            text = input("\n输入文字: ")
            if not text:
                continue

            # 转换
            morse = converter.text_to_morse(text)
            print(f"\n摩斯密码: {morse}")

            audio, sr = converter.text_to_audio(text)
            info = converter.get_audio_info(audio, sr)

            print(f"\n音频信息:")
            print(f"  时长: {info['duration']:.2f} 秒")
            print(f"  文件大小: {info['num_samples']*2:,} 字节")

            # 保存
            filename = input(f"\n保存文件名 (默认: morse_output.wav): ").strip()
            if not filename:
                filename = "morse_output.wav"

            if not filename.endswith('.wav'):
                filename += '.wav'

            converter.save_to_wav(audio, sr, filename)

            # 播放
            play = input("\n是否播放? (y/n): ").lower()
            if play == 'y':
                converter.play_audio(audio, sr)

        elif choice == "2":
            # 调整设置
            print("\n当前设置:")
            print(f"  1. 音频频率: {converter.frequency} Hz")
            print(f"  2. 采样率: {converter.sample_rate} Hz")
            print(f"  3. 点时长: {converter.dot_duration} 秒")

            setting = input("\n调整哪项 (1-3, 其他=跳过): ").strip()

            if setting == "1":
                try:
                    freq = int(input("新频率 (Hz, 建议600-1000): "))
                    converter.frequency = freq
                    print(f"✓ 频率已设置为 {freq} Hz")
                except ValueError:
                    print("✗ 无效输入")

            elif setting == "2":
                try:
                    sr = int(input("新采样率 (Hz, 建议44100): "))
                    converter.sample_rate = sr
                    print(f"✓ 采样率已设置为 {sr} Hz")
                except ValueError:
                    print("✗ 无效输入")

            elif setting == "3":
                try:
                    duration = float(input("新的点时长 (秒, 建议0.1-0.2): "))
                    converter.dot_duration = duration
                    converter.dash_duration = duration * 3
                    print(f"✓ 点时长已设置为 {duration} 秒")
                except ValueError:
                    print("✗ 无效输入")

        elif choice == "3":
            # 演示模式
            demo_conversion()

        elif choice == "4":
            print("\n👋 再见！")
            break

        else:
            print("✗ 无效选择")


if __name__ == "__main__":
    import sys

    if len(sys.argv) > 1 and sys.argv[1] == "demo":
        demo_conversion()
    else:
        interactive_converter()
