"""
bilibili_api.ass

有关 ASS 文件的操作
"""
import os
from typing import Union

from .bangumi import Episode
from .cheese import CheeseVideo
from .exceptions.ArgsException import ArgsException

from .utils.Credential import Credential
from .utils.network_httpx import get_session
from .utils.danmaku2ass import Danmaku2ASS
from .utils.json2srt import json2srt
from .utils.srt2ass import srt2ass
from .video import Video
from tempfile import gettempdir


def export_ass_from_xml(
    file_local,
    output_local,
    stage_size,
    font_name,
    font_size,
    alpha,
    fly_time,
    static_time,
) -> None:
    """
    以一个 XML 文件创建 ASS
    一定看清楚 Arguments!

    Args:
        file_local   (str)       : 文件输入
        output_local (str)       : 文件输出
        stage_size   (tuple(int)): 视频大小
        font_name    (str)       : 字体
        font_size    (float)     : 字体大小
        alpha        (float)     : 透明度(0-1)
        fly_time     (float)     : 滚动弹幕持续时间
        static_time  (float)     : 静态弹幕持续时间
    """
    Danmaku2ASS(
        input_files=file_local,
        input_format="Bilibili",
        output_file=output_local,
        stage_width=stage_size[0],
        stage_height=stage_size[1],
        reserve_blank=0,
        font_face=font_name,
        font_size=font_size,
        text_opacity=alpha,
        duration_marquee=fly_time,
        duration_still=static_time,
    )


def export_ass_from_srt(file_local, output_local) -> None:
    """
    转换 srt 至 ass

    Args:
        file_local   (str): 文件位置
        output_local (str): 输出位置
    """
    srt2ass(file_local, output_local, "movie")


def export_ass_from_json(file_local, output_local) -> None:
    """
    转换 json 至 ass

    Args:
        file_local   (str): 文件位置
        output_local (str): 输出位置
    """
    json2srt(file_local, output_local.replace(".ass", ".srt"))
    srt2ass(output_local.replace(".ass", ".srt"), output_local, "movie")
    os.remove(output_local.replace(".ass", ".srt"))


async def make_ass_file_subtitle(
    obj: Union[Video, Episode], out="test.ass", name="中文（自动生成）"
) -> None:
    """
    生成视频字幕文件

    Args:
        obj        (Union[Video,Episode]): 对象
        out        (str, optional)       : 输出位置. Defaults to "test.ass".
        name       (str, optional)       : 字幕名，如”中文（自动生成）“,是简介的'subtitle'项的'list'项中的弹幕的'lan_doc'属性。Defaults to "中文（自动生成）".
    """
    info = await obj.get_info()
    json_files = info["subtitle"]["list"]
    for subtitle in json_files:
        if subtitle["lan_doc"] == name:
            url = subtitle["subtitle_url"]
            req = await get_session().request("GET", url)
            file_dir = gettempdir() + "/" + "subtitle.json"
            with open(file_dir, "wb") as f:
                f.write(req.content)
            export_ass_from_json(file_dir, out)
            return
    raise ValueError("没有找到指定字幕")


async def make_ass_file_danmakus_protobuf(
    obj: Union[Video, Episode, CheeseVideo],
    page: int = 0,
    out="test.ass",
    cid: Union[int, None] = None,
    credential: Union[Credential, None] = None,
    date=None,
    font_name="Simsun",
    font_size=25.0,
    alpha=1,
    fly_time=7,
    static_time=5,
) -> None:
    """
    生成视频弹幕文件 *★,°*:.☆(￣▽￣)/$:*.°★* 。
    强烈推荐 PotPlayer, 电影与电视全部都是静态的，不能滚动。
    来源：protobuf

    Args:
        obj         (Union[Video,Episode,CheeseVideo])       : 对象
        page        (int, optional)                          : 分 P 号. Defaults to 0.
        out         (str, optional)                          : 输出文件. Defaults to "test.ass"
        cid         (int | None, optional)                   : cid. Defaults to None.
        credential  (Credential | None, optional)            : 凭据. Defaults to None.
        date        (datetime.date, optional)                : 获取时间. Defaults to None.
        font_name   (str, optional)                          : 字体. Defaults to "Simsun".
        font_size   (float, optional)                        : 字体大小. Defaults to 25.0.
        alpha       (float, optional)                        : 透明度(0-1). Defaults to 1.
        fly_time    (float, optional)                        : 滚动弹幕持续时间. Defaults to 7.
        static_time (float, optional)                        : 静态弹幕持续时间. Defaults to 5.
    """
    credential = credential if credential else Credential()
    if date:
        credential.raise_for_no_sessdata()
    if isinstance(obj, Video):
        v = obj
        if isinstance(obj, Episode):
            cid = 0
        else:
            if cid is None:
                if page is None:
                    raise ArgsException("page_index 和 cid 至少提供一个。")
                cid = await v._Video__get_page_id_by_index(page)  # type: ignore
        try:
            info = await v.get_info()
        except:
            info = {"dimension": {"width": 1440, "height": 1080}}
        width = info["dimension"]["width"]
        height = info["dimension"]["height"]
        if width == 0:
            width = 1440
        if height == 0:
            height = 1080
        stage_size = (width, height)
        if isinstance(obj, Episode):
            danmakus = await v.get_danmakus()
        else:
            danmakus = await v.get_danmakus(cid=cid, date=date)  # type: ignore
    elif isinstance(obj, CheeseVideo):
        stage_size = (1440, 1080)
        danmakus = await obj.get_danmakus()
    else:
        raise ValueError("请传入 Video/Episode/CheeseVideo 类！")
    with open(gettempdir() + "/danmaku_temp.xml", "w+", encoding="utf-8") as file:
        file.write("<i>")
        for d in danmakus:
            file.write(d.to_xml())
        file.write("</i>")
    export_ass_from_xml(
        gettempdir() + "/danmaku_temp.xml",
        out,
        stage_size,
        font_name,
        font_size,
        alpha,
        fly_time,
        static_time,
    )


async def make_ass_file_danmakus_xml(
    obj: Union[Video, Episode, CheeseVideo],
    page: int = 0,
    out="test.ass",
    cid: Union[int, None] = None,
    font_name="Simsun",
    font_size=25.0,
    alpha=1,
    fly_time=7,
    static_time=5,
) -> None:
    """
    生成视频弹幕文件 *★,°*:.☆(￣▽￣)/$:*.°★* 。
    强烈推荐 PotPlayer, 电影与电视全部都是静态的，不能滚动。
    来源：xml
    Args:
        obj         (Union[Video,Episode,Cheese]): 对象
        page        (int, optional)              : 分 P 号. Defaults to 0.
        out         (str, optional)              : 输出文件. Defaults to "test.ass".
        cid         (int | None, optional)       : cid. Defaults to None.
        font_name   (str, optional)              : 字体. Defaults to "Simsun".
        font_size   (float, optional)            : 字体大小. Defaults to 25.0.
        alpha       (float, optional)            : 透明度(0-1). Defaults to 1.
        fly_time    (float, optional)            : 滚动弹幕持续时间. Defaults to 7.
        static_time (float, optional)            : 静态弹幕持续时间. Defaults to 5.
    """
    if isinstance(obj, Video):
        v = obj
        if isinstance(obj, Episode):
            cid = 0
        else:
            if cid is None:
                if page is None:
                    raise ArgsException("page_index 和 cid 至少提供一个。")
                cid = await v._Video__get_page_id_by_index(page)  # type: ignore
        try:
            info = await v.get_info()
        except:
            info = {"dimension": {"width": 1440, "height": 1080}}
        width = info["dimension"]["width"]
        height = info["dimension"]["height"]
        if width == 0:
            width = 1440
        if height == 0:
            height = 1080
        stage_size = (width, height)
        if isinstance(obj, Episode):
            xml_content = await v.get_danmaku_xml()
        else:
            xml_content = await v.get_danmaku_xml(cid=cid)  # type: ignore
    elif isinstance(obj, CheeseVideo):
        stage_size = (1440, 1080)
        xml_content = await obj.get_danmaku_xml()
    else:
        raise ValueError("请传入 Video/Episode/CheeseVideo 类！")
    with open(gettempdir() + "/danmaku_temp.xml", "w+", encoding="utf-8") as file:
        file.write(xml_content)
    export_ass_from_xml(
        gettempdir() + "/danmaku_temp.xml",
        out,
        stage_size,
        font_name,
        font_size,
        alpha,
        fly_time,
        static_time,
    )
