from typing import Any, List, Callable

import dominate.tags as t
import dominate.util as tu

import papis.commands.doctor

import papis.web.paths as wp
import papis.web.html as wh
import papis.web.docform
import papis.web.header
import papis.web.notes
import papis.web.info
import papis.web.citations
import papis.web.pdfjs
import papis.web.djvujs


def _click_tab_selector_link_in_url() -> None:
    t.script(tu.raw("""
    window.addEventListener('load', () => {
        try {
            let url = window.location.href.split('#').pop();
            document.querySelector('#selector-'+url).click();
        } catch {}
    });
    """))


def html(libname: str, doc: papis.document.Document) -> t.html_tag:
    """
    View of a single document to edit the information of the yaml file,
    and maybe in the future to update the information.
    """
    checks = papis.commands.doctor.registered_checks_names()
    errors = papis.commands.doctor.run(doc, checks)
    libfolder = papis.config.get_lib_from_name(libname).paths[0]

    with papis.web.header.main_html_document(doc["title"]) as result:
        with result.body:
            _click_tab_selector_link_in_url()
            papis.web.navbar.navbar(libname=libname)
            with wh.container():
                t.h3(doc["title"])
                t.h5("{:.80}, {}".format(doc["author"], doc["year"]),
                     style="font-style: italic")
                tags = doc["tags"]
                with wh.flex("between"):
                    if tags:
                        papis.web.tags.tags_list_div(tags, libname)
                    for fpath in doc.get_files():
                        with t.a(href=wp.file_server_path(fpath,
                                                          libfolder,
                                                          libname)):
                            wh.file_icon(fpath)
                for error in errors:
                    with wh.alert(t.div, "danger"):
                        wh.icon_span("stethoscope", error.msg)

                with t.ul(cls="nav nav-tabs"):

                    def _tab_element(content: Callable[..., t.html_tag],
                                     args: List[Any],
                                     href: str,
                                     active: bool = False) -> t.html_tag:
                        with t.li(cls="active nav-item") as result:
                            with t.a(cls="nav-link" + (" active"
                                                       if active
                                                       else ""),
                                     aria_current="page",
                                     id="selector-" + href.replace("#", ""),
                                     href=href,
                                     data_bs_toggle="tab"):
                                content(*args)
                        return result

                    _tab_element(t.span,
                                 ["Form"],
                                 "#main-form-tab", active=True)
                    _tab_element(wh.icon_span,
                                 ["file-alt", "info.yaml"],
                                 "#yaml-form-tab")
                    _tab_element(t.span, ["Bibtex"], "#bibtex-form-tab")
                    for i, fpath in enumerate(doc.get_files()):
                        _tab_element(wh.file_icon,
                                     [fpath],
                                     "#file-tab-{}".format(i))
                    _tab_element(wh.icon_span,
                                 ["compress-alt", "Citations"],
                                 "#citations-tab")
                    _tab_element(wh.icon_span,
                                 ["expand-alt", "Cited by"],
                                 "#cited-by-tab")
                    _tab_element(wh.icon_span, ["file-edit", "Notes"],
                                 "#notes-tab")

                t.br()

                with t.div(cls="tab-content"):
                    with t.div(id="main-form-tab",
                               role="tabpanel",
                               aria_labelledby="main-form",
                               cls="tab-pane fade show active"):
                        papis.web.docform.html(libname, doc)

                    with t.div(id="yaml-form-tab",
                               role="tabpanel",
                               aria_labelledby="yaml-form",
                               cls="tab-pane fade"):
                        papis.web.info.widget(doc, libname)

                    with t.div(id="bibtex-form-tab",
                               role="tabpanel",
                               aria_labelledby="bibtex-form",
                               cls="tab-pane fade"):
                        _bibtex_id = "bibtex-source"
                        t.div(papis.bibtex.to_bibtex(doc),
                              id=_bibtex_id,
                              width="100%",
                              height=100,
                              style="min-height: 500px",
                              cls="form-control")
                        _script = """
                            let bib_editor = ace.edit("{}");
                            bib_editor.session.setMode("ace/mode/bibtex");
                        """.format(_bibtex_id)
                        t.script(tu.raw(_script),
                                 charset="utf-8",
                                 type="text/javascript")

                    with t.div(id="notes-tab",
                               role="tabpanel",
                               aria_labelledby="notes-form",
                               cls="tab-pane fade"):
                        papis.web.notes.widget(libname, doc)

                    for i, fpath in enumerate(doc.get_files()):
                        _unquoted_file_path = wp.file_server_path(fpath,
                                                                  libfolder,
                                                                  libname)

                        with t.div(id="file-tab-{}".format(i),
                                   role="tabpanel",
                                   aria_labelledby="file-tab",
                                   cls="tab-pane fade"):

                            if fpath.endswith("pdf"):
                                papis.web.pdfjs.widget(_unquoted_file_path)

                            if fpath.endswith("djvu"):
                                papis.web.djvujs.widget(_unquoted_file_path)

                            elif (fpath.endswith("png")
                                  or fpath.endswith("jpg")):
                                with t.div():
                                    t.img(src=_unquoted_file_path)

                    with t.div(id="citations-tab",
                               role="tabpanel",
                               aria_labelledby="citations-tab",
                               cls="tab-pane fade"):
                        papis.web.citations.render(
                            doc,
                            libname,
                            libfolder,
                            timeline_id="main-citations-timeline",
                            fetch_path=wp.fetch_citations_server_path,
                            checker=papis.citations.has_citations,
                            getter=papis.citations.get_citations,
                            ads_fmt=("https://ui.adsabs.harvard.edu/abs/"
                                     "{doi}/references"))

                    with t.div(id="cited-by-tab",
                               role="tabpanel",
                               aria_labelledby="cited-by-tab",
                               cls="tab-pane fade"):
                        papis.web.citations.render(
                            doc,
                            libname,
                            libfolder,
                            timeline_id="main-cited-by-timeline",
                            fetch_path=wp.fetch_cited_by_server_path,
                            checker=papis.citations.has_cited_by,
                            getter=papis.citations.get_cited_by,
                            ads_fmt=("https://ui.adsabs.harvard.edu/abs/"
                                     "{doi}/citations"))

    return result
