"""
版权所有 © 2025 金羿 & 诸葛亮与八卦阵
Copyright © 2025 Eilles & bgArray

开源相关声明请见 仓库根目录下的 License.md
Terms & Conditions: License.md in the root directory
"""

import os
import shutil
from typing import Optional, Tuple

import Musicreater.experiment
from Musicreater.old_plugin.archive import compress_zipfile
from Musicreater.utils import guess_deviation, is_in_diapason


def to_zip_pack_in_score(
    midi_cvt: Musicreater.experiment.FutureMidiConvertJavaE,
    dist_path: str,
    progressbar_style: Optional[Musicreater.experiment.ProgressBarStyle],
    scoreboard_name: str = "mscplay",
    sound_source: str = "ambient",
    auto_reset: bool = False,
) -> Tuple[int, int]:
    """
    将midi以计分播放器形式转换为我的世界函数附加包

    Parameters
    ----------
    midi_cvt: MidiConvert 对象
        用于转换的MidiConvert对象
    dist_path: str
        转换结果输出的目标路径
    progressbar_style: ProgressBarStyle 对象
        进度条对象
    scoreboard_name: str
        我的世界的计分板名称
    auto_reset: bool
        是否自动重置计分板

    Returns
    -------
    tuple[int指令数量, int音乐总延迟]
    """

    cmdlist, maxlen, maxscore = midi_cvt.to_command_list_in_java_score(
        scoreboard_name=scoreboard_name,
        source_of_sound=sound_source,
    )

    # 当文件f夹{self.outputPath}/temp/mscplyfuncs存在时清空其下所有项目，然后创建
    if os.path.exists(f"{dist_path}/temp/mscplyfuncs/"):
        shutil.rmtree(f"{dist_path}/temp/mscplyfuncs/")
    os.makedirs(f"{dist_path}/temp/mscplyfuncs/mscplay")

    # 写入stop.mcfunction
    with open(
        f"{dist_path}/temp/mscplyfuncs/stop.mcfunction", "w", encoding="utf-8"
    ) as f:
        f.write("scoreboard players reset @a {}".format(scoreboard_name))

    # 将命令列表写入文件
    index_file = open(
        f"{dist_path}/temp/mscplyfuncs/index.mcfunction", "w", encoding="utf-8"
    )
    for i in range(len(cmdlist)):
        index_file.write(f"function mscplyfuncs:mscplay/track{i + 1}\n")
        with open(
            f"{dist_path}/temp/mscplyfuncs/mscplay/track{i + 1}.mcfunction",
            "w",
            encoding="utf-8",
        ) as f:
            f.write("\n".join([single_cmd.mcfunction_command_string for single_cmd in cmdlist[i]]))
    index_file.writelines(
        (
            "scoreboard players add @a[score_{0}_min=1] {0} 1\n".format(
                scoreboard_name
            ),
            (
                "scoreboard players reset @a[score_{0}_min={1}] {0}\n".format(
                    scoreboard_name, maxscore + 20
                )
                if auto_reset
                else ""
            ),
            f"function mscplyfuncs:mscplay/progressShow\n" if progressbar_style else "",
        )
    )

    if progressbar_style:
        with open(
            f"{dist_path}/temp/mscplyfuncs/mscplay/progressShow.mcfunction",
            "w",
            encoding="utf-8",
        ) as f:
            f.writelines(
                "\n".join(
                    [
                        single_cmd.mcfunction_command_string
                        for single_cmd in midi_cvt.form_java_progress_bar(
                            maxscore, scoreboard_name, progressbar_style
                        )
                    ]
                )
            )

    index_file.close()

    if os.path.exists(f"{dist_path}/{midi_cvt.music_name}.zip"):
        os.remove(f"{dist_path}/{midi_cvt.music_name}.zip")
    compress_zipfile(
        f"{dist_path}/temp/",
        f"{dist_path}/{midi_cvt.music_name}[JEscore].zip",
    )

    shutil.rmtree(f"{dist_path}/temp/")

    return maxlen, maxscore


msc_cvt = Musicreater.experiment.FutureMidiConvertJavaE.from_midi_file(
    input("midi路径："),
    play_speed=float(input("播放速度：")),
    old_exe_format=True,
    note_table_replacement=Musicreater.old_init.MC_EILLES_RTJE12_INSTRUMENT_REPLACE_TABLE,
    # pitched_note_table=Musicreater.MM_NBS_PITCHED_INSTRUMENT_TABLE,
)

msc_cvt.set_deviation(
    guess_deviation(
        msc_cvt.total_note_count,
        len(msc_cvt.note_count_per_instrument),
        msc_cvt.note_count_per_instrument,
        music_channels=msc_cvt.channels,
    )
)

in_diapason_count = 0
for this_note in [k for j in msc_cvt.channels.values() for k in j]:
    if is_in_diapason(
        this_note.note_pitch + msc_cvt.music_deviation, this_note.sound_name
    ):
        in_diapason_count += 1


zip_res = to_zip_pack_in_score(
    msc_cvt,
    input("输出路径："),
    Musicreater.experiment.ProgressBarStyle(),
    # Musicreater.plugin.ConvertConfig(input("输出路径:"),),
    scoreboard_name=input("计分板名称："),
    sound_source=input("发音源："),
    auto_reset=True,
)
print(
    "符合音符播放音高的音符数量：{}/{}({:.2f}%)".format(
        in_diapason_count,
        msc_cvt.total_note_count,
        in_diapason_count * 100 / msc_cvt.total_note_count,
    ),
    "\n指令数量：{}；音乐总延迟：{}".format(*zip_res),
)
