from __future__ import annotations
from typing import TYPE_CHECKING, Dict, List, Optional, Callable
import pybi.utils.data_gen as data_gen
import jinja2
from pathlib import Path


_pj_root = data_gen.get_project_root()
_static_path = _pj_root / "static"


def _get_file_path_from_static(file_name: str):
    return str(_static_path / file_name)


def js_online_resource(src: str):
    def fn():
        return f'<script src="{src}"></script>'

    return fn


def js_offline_resource(path: str, id=""):
    def fn():
        return f'<script id="{id}">{Path(path).read_text("utf8")}</script>'

    return fn


def css_online_resource(href: str):
    def fn():
        return f'<link rel="stylesheet" type="text/css" href="{href}">'

    return fn


def css_offline_resource(path: str, id=""):
    def fn():
        return f'<style id="{id}">{Path(path).read_text("utf8")}</style>'

    return fn


def material_icons_resource():
    def fn():
        woff = _get_file_path_from_static("Material-Icons.woff2")
        b64 = data_gen.file2html_base64_src(woff, "woff2")
        return f"""
   <style id='Material-Icons'>
        @font-face {{
            font-family: 'Material Icons';
            font-style: normal;
            font-weight: 400;
            src: url({b64}) format('woff2');
        }}


        .material-icons {{
font-family: 'Material Icons';
  font-weight: normal;
  font-style: normal;
  display: inline-block;
  line-height: 1;
  text-transform: none;
  letter-spacing: normal;
  word-wrap: normal;
  white-space: nowrap;
  direction: ltr;

  /* Support for all WebKit browsers. */
  -webkit-font-smoothing: antialiased;
  /* Support for Safari and Chrome. */
  text-rendering: optimizeLegibility;

  /* Support for Firefox. */
  -moz-osx-font-smoothing: grayscale;

  /* Support for IE. */
  font-feature-settings: 'liga';
        }}
    </style>
        """

    return fn


def empty_resource():
    def fn():
        return ""

    return fn


TResource = Callable


_system_resources: Dict[str, TResource] = {
    "sysApp": js_offline_resource(
        _get_file_path_from_static("sysApp.iife.js"), id="sysApp"
    ),
    "sysApp-css": css_offline_resource(
        _get_file_path_from_static("sysApp-style.css"), id="sysApp-css"
    ),
    "vue-js": js_offline_resource(
        _get_file_path_from_static("vue.global.prod.min.js"), id="vue-js"
    ),
    "echarts-js": js_offline_resource(
        _get_file_path_from_static("echarts.min.js"), id="echarts-js"
    ),
}


_env = jinja2.Environment(loader=jinja2.PackageLoader("pybi", "template"))
_html_template = _env.get_template("index.html")


class ResourceManager:
    def __init__(self):
        pass
        # self.system_resources =
        self.sysApp_css = _system_resources["sysApp-css"]
        self.sysApp_js = _system_resources["sysApp"]
        self.vue_js = _system_resources["vue-js"]
        self.material_icons = material_icons_resource()

        self.echarts_core_js = empty_resource()
        self.echarts_cps_js = empty_resource()
        self.echarts_cps_css = empty_resource()

        self.element_cps_js = empty_resource()
        self.element_cps_css = empty_resource()

        self.mermaid_cps_js = empty_resource()

        self.zip_js = None

    def register_echarts(self):
        self.echarts_cps_js = js_offline_resource(
            _get_file_path_from_static("echartsCps.iife.js"), id="echartsCps-js"
        )
        self.echarts_cps_css = css_offline_resource(
            _get_file_path_from_static("echartsCps-style.css"), id="echartsCps-style"
        )
        self.echarts_core_js = js_offline_resource(
            _get_file_path_from_static("echarts.min.js"), id="echarts-js"
        )
        return self

    def register_element_cps(self):
        self.element_cps_js = js_offline_resource(
            _get_file_path_from_static("elementCps.iife.js"), id="elementCps-js"
        )
        self.element_cps_css = css_offline_resource(
            _get_file_path_from_static("elementCps-style.css"), id="elementCps-style"
        )
        return self

    def register_mermaid_cps(self):
        self.mermaid_cps_js = js_offline_resource(
            _get_file_path_from_static("mermaidCps.iife.js"), id="mermaidCps-js"
        )

        return self

    def build_html(self, appConfig: str) -> str:

        res = _html_template.render(app_config=appConfig, resources=self)
        assert isinstance(res, str)
        return res
