import shutil
import subprocess

RIGHT_PAD = 32
MAIN_WIDTH = 2_000
WIDTH = MAIN_WIDTH + RIGHT_PAD
EXTRA_HEIGHT = 65

LANE_THICKNESS = 2
LANE_TEXT_X, LANE_TEXT_Y = 12, 15
Y_PAD = 12

TIME_X = 32
TIME_WIDTH = MAIN_WIDTH - TIME_X
TIME_THICKNESS = 4
TICK_HEIGHT = 24 - 1

DASH_ARRAY = [6, 6]
RX = 8

WHITE = "#e6e6e6"
GREY = "#666666"
(
    TEXTURE_COLOR_0,
    TEXTURE_COLOR_1,
    TEXTURE_COLOR_2,
    TEXTURE_COLOR_3,
    TEXTURE_COLOR_4,
) = ("#5e1675", "#ee4266", "#ffd23f", "#337357", "#42b8ad")

TEXT_STYLE = f'fill: {WHITE}; font-size: 18px; font-family: InterVariable, Inter, "Inter Variable", FreeSerif, sans-serif; font-variant-numeric: tabular-nums;'
LEGEND_TEXT_STYLE = 'fill: #fff; font-size: 24px; font-family: InterVariable, Inter, "Inter Variable", FreeSerif, sans-serif; font-variant-numeric: tabular-nums;'
ICON_TEXT_STYLE = 'fill: #fff; font-size: 24px; font-family: "Gentium Plus", Gentium, FreeSerif, serif; font-variant-numeric: tabular-nums;'
SMALL_ICON_TEXT_STYLE = 'fill: #fff; font-size: 18px; font-family: "Gentium Plus", Gentium, FreeSerif, serif; font-variant-numeric: tabular-nums;'
BLACK_ICON_TEXT_STYLE = 'fill: #000; font-size: 24px; font-family: "Gentium Plus", Gentium, FreeSerif, serif; font-variant-numeric: tabular-nums;'

TOTAL_DUR = 4 * 60 + 44
SECTS = [
    ("\u03b1", 15),
    ("A", 41),
    ("A\u2032", 55),
    ("B", 1 * 60 + 15),
    ("C", 1 * 60 + 32),
    ("D", 1 * 60 + 45),
    ("E", 2 * 60 + 5),
    ("F", 2 * 60 + 27),
    ("G", 2 * 60 + 47),
    ("H", 3 * 60 + 10),
    ("I", 3 * 60 + 39),
    ("J", 4 * 60 + 21),
    ("K", 4 * 60 + 44),
]


def fmt_time(sec):
    if isinstance(sec, int):
        return f"{sec // 60}:{sec % 60:02}"

    return f"{int(sec) // 60}:{sec % 60.0:05.2f}".rstrip("0")


def fmt_datetime(sec):
    if isinstance(sec, int):
        return f"PT{sec // 60}M{sec % 60}S"

    return f"PT{int(sec) // 60}M{sec % 60.0:.2f}".rstrip("0") + "S"


def draw_template(dwg, lane_count, lane_height):
    height = lane_count * lane_height + EXTRA_HEIGHT
    bg_rect = dwg.add(dwg.rect(insert=(0, 0), size=(WIDTH, height)))
    bg_rect.fill(color="#181818")

    time_y = lane_count * lane_height - LANE_THICKNESS

    time_line = dwg.add(
        dwg.line(
            start=(TIME_X - TIME_THICKNESS / 2, time_y),
            end=(MAIN_WIDTH + TIME_THICKNESS / 2, time_y),
        )
    )
    time_line.stroke(WHITE, width=TIME_THICKNESS)
    prev_end = 0
    for name, t_end in [(None, 0)] + SECTS:
        tick_x = TIME_X + TIME_WIDTH * (t_end / TOTAL_DUR)
        tick = dwg.add(
            dwg.line(
                start=(tick_x, 1 + time_y),
                end=(tick_x, 1 + time_y + TICK_HEIGHT),
            )
        )
        tick.stroke(WHITE, width=TIME_THICKNESS)

        dwg.add(
            dwg.text(
                fmt_time(t_end),
                insert=(tick_x - 20, time_y + 48),
                style=TEXT_STYLE,
            )
        )

        if name is None:
            continue

        dwg.add(
            dwg.text(
                name,
                insert=(
                    TIME_X
                    + TIME_WIDTH * ((prev_end + t_end) / (2 * TOTAL_DUR))
                    - 5,
                    time_y + 24,
                ),
                style=ICON_TEXT_STYLE,
            )
        )

        prev_end = t_end


def draw_lanes(dwg, lanes, lane_height):
    for lane, (name, offset) in enumerate(lanes):
        if lane < len(lanes) - 1:
            lane_y = lane_height * (lane + 1) - LANE_THICKNESS
            lane_line = dwg.add(
                dwg.line(start=(0, lane_y), end=(WIDTH, lane_y))
            )
            lane_line.stroke(GREY, width=LANE_THICKNESS).dasharray(DASH_ARRAY)

        text_y = LANE_TEXT_Y + lane_height * lane + offset
        text = dwg.add(
            dwg.text(name, insert=(LANE_TEXT_X, text_y), style=TEXT_STYLE)
        )
        text.rotate(90, (LANE_TEXT_X, text_y))


def drawing_save(dwg):
    opt_filename = dwg.filename.replace(".svg", ".opt.svg")

    dwg.save(pretty=True)

    subprocess.run(
        [
            "inkscape",
            "--export-type=svg",
            "--vacuum-defs",
            "-l",
            "-D",
            "-T",
            "--export-area-snap",
            "--export-overwrite",
            dwg.filename,
        ],
        check=True,
        capture_output=True,
    )
    subprocess.run(
        [
            "svgo",
            "-i",
            dwg.filename,
            "-o",
            opt_filename,
            "--multipass",
            "--eol",
            "lf",
            "--final-newline",
            "--config",
            "svgo.config.mjs",
        ],
        check=True,
        capture_output=True,
    )
    shutil.move(opt_filename, dwg.filename)


def sect_ths(ts):
    s = ""
    prev_end_t = 0
    for name, end_t in SECTS:
        i, n = 0, 0
        while i < len(ts) and ts[i] < end_t:
            if ts[i] >= prev_end_t:
                n += 1
            i += 1
        colspan_text = f' colspan="{n}"' if n != 1 else ""
        name_code = name.replace("\u03b1", "a").replace("\u2032", "'")
        s += f'\n      <th scope="col"{colspan_text}>{{% m "{name_code}", "form" %}}</th>'

        prev_end_t = end_t

    s += """
      <th scope="col">&#x1d102;</th>
    </tr>
    <tr>"""

    for t in ts:
        datetime = fmt_datetime(t)
        s += f'\n      <th scope="col"><time datetime="{datetime}">{fmt_time(t)}</time></th>'

    s += """
    </tr>
  </thead>
  <tbody>"""

    return s
