# Серверная часть/обработка
import subprocess as sp
import os


def get_video_info(entry: str, input_file_path: str) -> list:
    """
    entry (str) — можно делать списком \n
    Возвращает list(str)
    """
    entry_get_command = [
        "ffprobe",
        "-v",
        "error",
        "-hide_banner",
        "-select_streams",
        "v:0",
        "-show_entries",
        f"stream={entry}",
        "-of",
        "default=noprint_wrappers=1",
        "-of",
        "csv=p=0:s=|",
        input_file_path,
    ]
    result = sp.run(entry_get_command, capture_output=True, text=True)
    out = result.stdout.strip().split("|")
    print(out)
    return out


# Общая часть — запуск комманды с параметрами
def runWithCommandLine(command: list) -> None:
    """
    Запускает программу command
    """
    print(command)
    # input='y' и text=True нужны для перезаписи файла при обработке ffmpeg-ом
    return sp.run(command, text=True)


def ffmpeg_video_cutter(user_id, data: dict, timings: str) -> str:
    session, name, ext, *_ = data["video"]
    root_directory = os.path.abspath(f"workdir{os.sep}{user_id}{os.sep}{session}")
    video_path = os.path.join(root_directory, f"{name}.{ext}")
    out_path = os.path.join(root_directory, f"{name}_cut.{ext}")

    arr = [
        [j.replace(":", "\\:") for j in line.split("-")] for line in timings.split("\n")
    ]
    time_arr = []
    concat_n = len(arr)
    if concat_n < 1:
        raise ValueError
    for n, timing in enumerate(arr):
        out = f"[0:v]trim=start='{timing[0]}':end='{timing[1]}',setpts=PTS-STARTPTS[vout{n + 1}];[0:a]atrim=start='{timing[0]}':end='{timing[1]}',asetpts=PTS-STARTPTS[aout{n + 1}]"
        time_arr.append(out)
    outs = "{}concat=n={}:v=1:a=0[v];{}concat=n={}:v=0:a=1[a]".format(
        "".join([f"{f'[vout{t}]'}" for t in range(1, len(time_arr) + 1)]),
        concat_n,
        "".join([f"{f'[aout{t}]'}" for t in range(1, len(time_arr) + 1)]),
        concat_n,
    )

    complex_statement = f"{';'.join(time_arr)};{outs}"

    final = [
        "ffmpeg",
        "-i",
        video_path,
        "-filter_complex",
        complex_statement,
        "-map",
        "[v]",
        "-map",
        "[a]",
        "-y",
        out_path,
    ]
    print(final)

    runWithCommandLine(final)

    return out_path


def ffmpeg_logo_writer(user_id, data: dict) -> list:
    """
    Производит list с аргументами для командной строки ffmpeg. \n
    user_id — получается из message.from_user.id, его нужно передавать для формирования пути \n
    data получается из State.get_data(). Можно закидывать всё, алгоритм ищет только значения по ключам 'subs', 'watermark', и список по ключу 'video'.
    Возвращает список из 2 элементов. 1 — аргументы; 2 — прямая ссылка на выходной файл в системе
    """

    session, name, ext, width, height = data["video"]
    root_directory = os.path.abspath(f"workdir{os.sep}{user_id}{os.sep}{session}")
    video_path = os.path.join(root_directory, f"{name}.{ext}")
    out_path = os.path.join(root_directory, f"{name}_edited.{ext}")
    watermark_path = (
        "klops_icon_white.png" if data["watermark"] == "w" else "klops_icon_black.png"
    )  # изменить перед тестами
    logo_path = "klops_logo_white.png"
    video_info = get_video_info(
        entry="width,height,color_space,duration", input_file_path=video_path
    )
    print(video_info)
    real_width, real_height = int(video_info[0]), int(video_info[1])
    color_space = video_info[2]
    duration = float(video_info[3])
    print(f"Ширина из data: {width}, реальная: {real_width}\nВысота из data: {height}, реальная: {real_height}\nДлительность: {duration}")

    if real_width > real_height:
        print("Видео горизонтальное")
        scaleExpr = "scale=w=oh*dar:h=rw/5"
        RscaleExpr = "scale=w=rh/3:h=ow/dar"
    else:
        print("Видео вертикальное")
        scaleExpr = "scale=w=rh/5:h=ow/dar"
        RscaleExpr = "scale=w=rw/3:h=ow/dar"

    if color_space == "reserved":
        print(f"У видео нестандартное пространство: {color_space}")
        decode = [
            "-bsf:v",
            "h264_metadata=colour_primaries=1:transfer_characteristics=1:matrix_coefficients=1",
            "-colorspace",
            1,
            "-color_trc",
            1,
            "-color_primaries",
            1,
        ]
    else:
        print(f"У видео стандартное пространство: {color_space}")
        decode = []

    complex_statement = f"[1][3:v]{scaleExpr}[icon];[3:v][icon]overlay=(W-w)/2:(H-h)/2:format=auto[iot];[0:v][iot]blend=all_mode=overlay:all_opacity=0.5[back];[2:v][3:v]{RscaleExpr}[logo];[back][logo]overlay=(W-w)-h:h:format=auto,format=yuv420p[out]"

    final = [
        "ffmpeg",
        *decode,
        "-i",
        video_path,
        "-i",
        watermark_path,
        "-i",
        logo_path,
        "-f",
        "lavfi",
        "-i",
        f"color=c=0x7F7F7F:s={real_width}x{real_height}:d={duration}",
        "-filter_complex",
        complex_statement,
        "-map",
        "[out]",
        "-map",
        "0:a?",
        "-c:v",
        "libx264",
        "-preset",
        "fast",
        "-y",
        out_path,
    ]

    return final


# debug
if __name__ == "__main__":
    input_video = r"E:\pythonB0T\834893201\test2\root.mp4"
    output_video = r"E:\pythonB0T\834893201\test2\wat_sub.mp4"
    watermark = r"E:\pythonB0T\834893201\test2\klops_logo_white.png"
    subs = r"E:\pythonB0T\834893201\test2\root.srt"
    # if os.path.exists(subs):

    #     # args = ffmpeg_command_writer(video_path=input_video,watermark_path=watermark,out_path=output_video)
    #     # ffmpeg_path = r"E:\ffmpeg\bin\ffmpeg.exe"
    #     # runWithCommandLine(ffmpeg_path,args)
    #     # # embedWatermarkAndSubs(input_video,watermark,subs,output_video)
    # else:
    #     subs = get_subs(input_video,r"E:\pythonB0T\834893201\test2")
    #     args = ffmpeg_command_writer(input_video,watermark_path=watermark,out_path=output_video)
    #     ffmpeg_path = r"E:\ffmpeg\bin\ffmpeg.exe"
    #     runWithCommandLine(ffmpeg_path,args)
    #     # embedWatermarkAndSubs(input_video,watermark,subs,output_video)
    # # embedSubsInVideo(input_video,subs,r"E:\Курсы_v2\Lynda After Effects Duik Rigging and Animation Tools\01. Getting Started with Duik\492721_01_01_XR30_gettingstarted_out.mp4")
