<?php

namespace app\ic;

use app\MarkupUtil;

class TZO
{
    const array PARTS = [1, 21, 22, 31, 32, 33, 41, 42, 43, 44, 51, 52, 53, 61, 62, 7];

    public readonly array $strings;

    public function __construct() {
        $this->strings = yaml_parse_file(APP_ROOT.'/data/tzo/info.yaml');
    }

    public function isPartValid(int $n): bool {
        return isset($this->strings['part_'.$n]);
    }

    public function getPartLabel(int $n): string {
        return $this->strings['part_'.$n]['label'];
    }

    public function getParts(): array {
        return static::PARTS;
    }

    public function getPartWithDots(int $n): string {
        return implode('.', str_split((string)$n));
    }

    public function getPartHtml(int $n): string {
        $markdown_file = APP_ROOT.'/data/tzo/'.$n.'.md';
        $md = file_get_contents($markdown_file);
        $html = MarkupUtil::markdownToHtml($md,
            use_image_previews: false);

        // images
        $html = preg_replace_callback('/!\[]\((https:\/\/kniganews\.org\/wp-content\/uploads\/(\d{4})\/(\d{2})\/([^\/)]+))\)/', function($matches) {
            $year = $matches[2];
            $month = $matches[3];
            $filename = $matches[4];
            $new_filename = $year.$month.'_'.$filename;
            // TODO cache image size
            list($w, $h) = $this->getImageSize(APP_ROOT.'/public/ic/images/tzo/'.$new_filename);
            return '<img src="'.htmlescape('/images/tzo/'.$new_filename).'" width="'.$w.'" height="'.$h.'" alt="">';
        }, $html);

        // links
        $html = preg_replace_callback(
            '/<center>\s*\(\[([^]]+)\]\(([^)]+)\)\)\s*<\/center>/',
            function ($matches) {
                $linkText = $matches[1];
                $url = $matches[2];
                return '<center>(<a href="'.htmlescape($url).'">'.htmlescape($linkText).'</a>)</center>';
            },
            $html
        );

        // chapter markers
        $html = preg_replace_callback(
            '/<center>\((\d+)\)<\/center>/',
            function ($matches) {
                $number = $matches[1];
                return '<p class="tzo-chapter" id="chapter'.$number.'">('.$number.')</p>';
            },
            $html
        );

        return $html;
    }

    protected function getImageSize(string $local_path): array {
        list($w, $h) = getimagesize($local_path);
        return [$w, $h];
    }

    public function getPartNavigationTree(int $part): string {
        if ($part == 1)
            return '';

        $buf_last_line = [];
        $buf_all_lines = [];

        $part_row = intval($part > 10 ? floor($part / 10) : $part);
        $part_column = ($part < 10 ? $part*10 : $part) % 10;
        if ($part_column == 0)
            $part_column = 1;

        for ($cur_row = 1;
             $cur_row <= $part_row;
             $cur_row++)
        {
            $columns = 4 - abs($cur_row - 4);
            for ($cur_column = 1; $cur_column <= $columns; $cur_column++) {
                $cur_part = $cur_row;
                if ($columns > 1) {
                    $cur_part *= 10;
                    $cur_part += $cur_column;
                }
                $label = $this->getPartLabel($cur_part);
                if ($cur_row == $part_row && $cur_column > $part_column) {
                    $label_len = strlen($label);
                    $label = $label[0].str_repeat('_', $label_len-1);
                }
                $cur_part_label = $this->getPartWithDots($cur_part).'_'.$label;
                if ($cur_row < $part_row || $cur_column < $part_column) {
                    $buf_last_line[] = '<a href="/tbc/'.$cur_part.'/">'.htmlescape($cur_part_label).'</a>';
                } else {
                    $buf_last_line[] = $cur_part_label;
                }
            }
            $buf_all_lines[] = implode(' <span>|</span> ', $buf_last_line);
            $buf_last_line = [];
        }

        return implode('<br>', $buf_all_lines);
    }
}