<?php
namespace Isekai;

use Html;

class IsekaiChart {
    /**
     * @param \Parser &$parser
     * @return bool
     * @throws \MWException
     */
    public static function onParserSetup(&$parser) {
		$parser->setHook('isekaichart', self::class . '::create');
		return true;
	}

    /**
     * @param string $input
     * @param string[] $args
     * @param \Parser $parser
     * @param \PPFrame $frame
     */
    public static function create($input, $args, $parser, $frame) {
        if (isset($args['type'])) {
            switch ($args['type']) {
                case 'radar':
                    return self::createRadar($input, $args, $parser, $frame);
            }
            return '<span class="error">' . wfMessage("isekai-chart-unknow-type", $args['type'])->parse() . '</span>';
        }
        return '<span class="error">' . wfMessage("isekai-chart-undefined-type")->parse() . '</span>';
    }

    public static function parseArgs(&$args, $defaultArgs = []) {
        $newArgs = array_merge([
            'legend' => true,
            'width' => 350,
            'height' => 300,
        ], $defaultArgs);
        $argsType = [
            'width' => 'int',
            'height' => 'int',
        ];
        foreach ($args as $key => $arg) {
            if (isset($argsType[$key])) {
                switch ($argsType[$key]) {
                    case 'int':
                        $arg = intval($arg);
                        break;
                    case 'float':
                        $arg = floatval($arg);
                        break;
                }
            }
            $newArgs[$key] = $arg;
        }
        return $newArgs;
    }

    /**
     * @param string $input
     * @param array $inputArgs
     * @param \Parser $parser
     * @param \PPFrame $frame
     * @return string
     */
    public static function createRadar($input, &$inputArgs, $parser, $frame) {
        $parser->getOutput()->addModules(["ext.isekai.chart"]); // 添加样式和脚本

        $allowedArgs = ['width', 'height', 'shape'];
        $args = self::parseArgs($inputArgs, [
            'shape' => 'polygon'
        ]);
        $legend = $args['legend'];

        $lines = explode("\n", $input);
        $csvData = [];
        foreach ($lines as $line) {
            if (!empty(trim($line))) {
                $csvData[] = str_getcsv($line);
            }
        }
        
        $names = [];
        $values = [];
        if (count($csvData) > 1) {
            if (count($csvData[0]) > 1 && $csvData[0][0] === "") { // 标题行
                $names = array_slice($csvData[0], 1);
                array_splice($csvData, 0, 1);
            } else { // 不存在标题行
                $legend = false;
                $valueLen = count($csvData[0]);
                for ($i = 0; $i < $valueLen; $i ++) { // 创建默认标题
                    $names[] = wfMessage('isekai-chart-default-row-name', $i + 1)->text();
                }
            }
        }

        foreach ($csvData as $csvLine) {
            $valueLine = [];
            foreach ($csvLine as $pos => $csvCol) {
                if ($pos === 0) {
                    $valueLine[$pos] = $csvCol;
                } else {
                    $valueLine[$pos] = floatval($csvCol);
                }
            }
            $values[] = $valueLine;
        }

        $nameJson = json_encode($names, JSON_UNESCAPED_UNICODE);
        $valueJson = json_encode($values, JSON_UNESCAPED_UNICODE);
        if (!$valueJson) {
            return '<span class="error">' . wfMessage("isekai-chart-transform-error", "Cannot encode json")->parse() . '</span>';
        }

        $attr = [];
        foreach ($args as $key => $val) {
            if (in_array($key, $allowedArgs)) {
                $attr['data-' . $key] = $val;
            }
        }

        $attr = array_merge($attr, [
            'class' => 'isekai-chart',
            'style' => "width: {$args['width']}px; height: {$args['height']}px; display: inline-block",
            'data-name' => $nameJson,
            'data-value' => $valueJson,
            'data-legend' => $legend ? 'on' : 'off',
        ]);

        ksort($attr);
        $chartId = md5(serialize($attr));

        $attr['data-chart-id'] = $chartId;
        
        $html = Html::openElement('div', $attr);
        $html .= Html::closeElement('div');
        return $html;
    }
}