import urllib

import django_tables2 as tables
from django.template.defaultfilters import safe
from django.urls import reverse
from django_tables2 import Column

from bpp.models import CHARAKTER_SLOTY
from bpp.models.cache import Cache_Punktacja_Autora_Query_View
from raport_slotow import const
from raport_slotow.columns import DecimalColumn, SummingColumn
from raport_slotow.models import (
    RaportEwaluacjaUpowaznieniaView,
    RaportUczelniaEwaluacjaView,
    RaportZerowyEntry,
)
from raport_slotow.models.uczelnia import RaportSlotowUczelniaWiersz


class RaportCommonMixin:
    def render_tytul_oryginalny(self, value):
        url = reverse("bpp:browse_rekord", args=(value.pk[0], value.pk[1]))
        return safe(f"<a href={url}>{value}</a>")

    def value_tytul_oryginalny(self, value):
        return value.tytul_oryginalny

    def render_zrodlo_informacje(self, value):
        if hasattr(value, "zrodlo_id") and value.zrodlo_id is not None:
            return f"{value.zrodlo} {value.szczegoly}"
        return f"{value.informacje} {value.szczegoly}"

    def render_autorzy_z_dyscypliny(self, value):
        if value:
            return ", ".join(value)

    def render_liczba_wszystkich_autorow(self, value):
        if value:
            return len(value)


class RaportSlotowAutorTable(RaportCommonMixin, tables.Table):
    class Meta:
        attrs = {"class": "small-table"}
        empty_text = "Brak danych"
        model = Cache_Punktacja_Autora_Query_View
        fields = (
            "tytul_oryginalny",
            "autorzy",
            "autorzy_z_dyscypliny",
            "liczba_autorow_z_dyscypliny",
            "liczba_wszystkich_autorow",
            "rok",
            "zrodlo_informacje",
            "dyscyplina",
            "punkty_kbn",
            "pkdaut",
            "slot",
        )

    tytul_oryginalny = Column("Tytuł oryginalny", "rekord")
    autorzy = Column(
        "Autorzy",
        "rekord__opis_bibliograficzny_zapisani_autorzy_cache",
        orderable=False,
    )
    rok = Column("Rok", "rekord__rok", orderable=True)
    dyscyplina = Column(orderable=False)
    punkty_kbn = Column("Punkty MNiSW/MEiN", "rekord__punkty_kbn")
    zrodlo_informacje = Column(
        "Źródło / informacje", "rekord", empty_values=(), orderable=False
    )
    pkdaut = SummingColumn("Punkty dla autora", "pkdaut")
    slot = SummingColumn("Slot")
    autorzy_z_dyscypliny = Column(
        "Autorzy z dyscypliny",
        "zapisani_autorzy_z_dyscypliny",
        orderable=False,
    )
    liczba_autorow_z_dyscypliny = Column(
        "Liczba autorów z dyscypliny",
        "zapisani_autorzy_z_dyscypliny",
        orderable=False,
    )
    liczba_wszystkich_autorow = Column(
        "Liczba wszystkich autorów",
        "rekord__opis_bibliograficzny_autorzy_cache",
        orderable=False,
    )

    def render_liczba_autorow_z_dyscypliny(self, value):
        if value:
            return len(value)


class RaportSlotowUczelniaBezJednostekIWydzialowTable(tables.Table):
    class Meta:
        empty_text = "Brak danych"
        model = RaportSlotowUczelniaWiersz
        fields = (
            "autor",
            "jednostka",
            "pbn_id",
            "orcid",
            "system_kadrowy_id",
            "dyscyplina",
            "pkd_aut_sum",
            "slot",
            "avg",
        )

    pkd_aut_sum = DecimalColumn("Suma punktów dla autora")
    slot = DecimalColumn("Slot")
    avg = Column("Średnio punktów dla autora na slot")
    dyscyplina = Column()
    pbn_id = Column("PBN ID", "autor__pbn_id")
    orcid = Column("ORCID", "autor__orcid")
    system_kadrowy_id = Column("System kadrowy ID", "autor__system_kadrowy_id")
    jednostka = Column("Aktualna jednostka")

    def __init__(self, od_roku, do_roku, slot, *args, **kw):
        self.od_roku = od_roku
        self.do_roku = do_roku
        self.slot = slot
        super().__init__(*args, **kw)

    def render_avg(self, value):
        return round(value, 4)

    def render_autor(self, value):
        url = (
            reverse("raport_slotow:index")
            + "?"
            + urllib.parse.urlencode(
                {
                    "obiekt": value.pk,
                    "od_roku": self.od_roku,
                    "do_roku": self.do_roku,
                    "dzialanie": const.DZIALANIE_SLOT,
                    "slot": self.slot,
                }
            )
        )

        autor_url = reverse("bpp:browse_autor", args=(value.pk,))
        return safe(
            f"<a href={autor_url}>{value}</a>"
            f' <a href={url}><span class="fi-results"/></a>'
        )

    def value_autor(self, value):
        return value


class RaportSlotowUczelniaTable(RaportSlotowUczelniaBezJednostekIWydzialowTable):
    class Meta:
        empty_text = "Brak danych"
        model = RaportSlotowUczelniaWiersz
        fields = (
            "autor",
            "pbn_id",
            "orcid",
            "system_kadrowy_id",
            "jednostka",
            "wydzial",
            "dyscyplina",
            "pkd_aut_sum",
            "slot",
            "avg",
        )

    jednostka = Column("Jednostka")

    wydzial = Column("Wydział", accessor="jednostka__wydzial__nazwa")


class RaportSlotowZerowyTable(tables.Table):
    class Meta:
        empty_text = "Brak danych"
        model = RaportZerowyEntry
        fields = (
            "autor",
            "autor__aktualna_jednostka",
            "autor__pbn_id",
            "autor__system_kadrowy_id",
            "autor__pbn_uid_id",
            "autor__orcid",
            "lata",
            "dyscyplina_naukowa",
        )


class RaportSlotowEwaluacjaTable(RaportCommonMixin, tables.Table):
    class Meta:
        attrs = {"class": "very-small-table"}
        empty_text = "Brak danych"
        model = RaportUczelniaEwaluacjaView
        fields = (
            "id",
            "tytul_oryginalny",
            "autorzy",
            "rok",
            "zrodlo_lub_wydawnictwo_nadrzedne",
            "informacje",
            "rodzaj_publikacji",
            "liczba_autorow_z_dyscypliny",
            "liczba_wszystkich_autorow",
            "punkty_pk",
            "impact_factor",
            "kwartyl_w_wos",
            "kwartyl_w_scopus",
            "licencja_openaccess",
            "autor",
            "aktualna_jednostka",
            "afiliowana_jednostka",
            "pbn_id",
            "orcid",
            "dyscyplina",
            "procent_dyscypliny",
            "subdyscyplina",
            "procent_subdyscypliny",
            "dyscyplina_rekordu",
            "upowaznienie_pbn",
            "pbn_uid_id",
            "profil_orcid",
            "pkdaut",
            "slot",
        )

    id = Column("ID publikacji", "rekord__id")
    tytul_oryginalny = Column("Tytuł oryginalny", "rekord")
    pbn_uid_id = Column("PBN UID", "rekord__pbn_uid_id")
    autorzy = Column(
        "Autorzy",
        "rekord__opis_bibliograficzny_zapisani_autorzy_cache",
        orderable=False,
    )
    aktualna_jednostka = Column(
        "Aktualna jednostka", "autorzy__autor__aktualna_jednostka__nazwa"
    )

    afiliowana_jednostka = Column("Afiliowana jednostka", "autorzy__jednostka__nazwa")
    rok = Column("Rok", "rekord__rok", orderable=True)
    zrodlo_informacje = None
    # Column(
    #    "Źródło / informacje", "rekord", empty_values=(), orderable=False
    # )
    zrodlo_lub_wydawnictwo_nadrzedne = Column(
        "Zródło lub wydawnictwo nadrzędne", "rekord", orderable=False
    )
    informacje = Column("Informacje", "rekord")

    upowaznienie_pbn = Column("Upoważnienie PBN", "autorzy")

    profil_orcid = Column("Profil ORCID", "autorzy")

    def render_upowaznienie_pbn(self, value):
        return value.upowaznienie_pbn

    def render_profil_orcid(self, value):
        return value.profil_orcid

    def render_zrodlo_lub_wydawnictwo_nadrzedne(self, value):
        if (
            hasattr(value, "wydawnictwo_nadrzedne_id")
            and value.wydawnictwo_nadrzedne_id is not None
        ):
            return value.wydawnictwo_nadrzedne.tytul_oryginalny
        if hasattr(value, "zrodlo_id") and value.zrodlo_id is not None:
            return value.zrodlo.nazwa
        return "123"

    def render_informacje(self, value):
        if (
            hasattr(value, "wydawnictwo_nadrzedne_id")
            and value.wydawnictwo_nadrzedne_id is not None
        ):
            return value.szczegoly
        return value.informacje

    rodzaj_publikacji = Column("Rodzaj", "rekord")
    liczba_autorow_z_dyscypliny = Column(
        "Liczba autorów z dyscypliny",
        "autorzy_z_dyscypliny",
        orderable=False,
    )
    liczba_wszystkich_autorow = Column(
        "Liczba wszystkich autorów",
        "rekord__opis_bibliograficzny_autorzy_cache",
        orderable=False,
    )
    punkty_pk = Column("PK", "rekord__punkty_kbn")
    impact_factor = Column("IF", "rekord__impact_factor")
    autor = Column("Autor ewaluowany", "autorzy__autor")
    pbn_id = Column("PBN ID", "autorzy__autor__pbn_id")
    orcid = Column("ORCID", "autorzy__autor__orcid")
    dyscyplina = Column(
        "Dyscyplina 1", "autor_dyscyplina__dyscyplina_naukowa", orderable=False
    )
    procent_dyscypliny = Column(
        "% dyscypliny 1", "autor_dyscyplina__procent_dyscypliny", orderable=False
    )
    subdyscyplina = Column(
        "Dyscyplina 2", "autor_dyscyplina__subdyscyplina_naukowa", orderable=False
    )
    procent_subdyscypliny = Column(
        "% dyscypliny 2",
        "autor_dyscyplina__procent_subdyscypliny",
        orderable=False,
    )
    dyscyplina_rekordu = Column("dyscyplina rekordu", "autorzy__dyscyplina_naukowa")
    pkdaut = SummingColumn("Punkty dla autora", "pkdaut")
    slot = SummingColumn("Slot")

    kwartyl_w_wos = Column("Kwartyl WoS", accessor="rekord__kwartyl_w_wos")
    licencja_openaccess = Column(
        "Licencja OpenAccess", accessor="rekord__openaccess_licencja"
    )
    kwartyl_w_scopus = Column("Kwartyl SCOPUS", accessor="rekord__kwartyl_w_scopus")

    def render_liczba_autorow_z_dyscypliny(self, value):
        if value:
            return len(value)

    def render_rodzaj_publikacji(self, value):
        if value.charakter_formalny.charakter_sloty:
            return CHARAKTER_SLOTY[value.charakter_formalny.charakter_sloty]
        if hasattr(value, "zrodlo_id") and value.zrodlo_id is not None:
            return "Artykuł"

    def render_autorzy(self, value):
        if value:
            if len(value) > 100:
                return value[:100] + "(...)"
            return value

    def value_autorzy(self, value):
        return value

    system_kadrowy_id = Column(
        "System kadrowy ID", accessor="autorzy__autor__system_kadrowy_id"
    )


class RaportEwaluacjaUpowaznieniaTable(RaportSlotowEwaluacjaTable):
    class Meta:
        attrs = {"class": "very-small-table"}
        model = RaportEwaluacjaUpowaznieniaView
        empty_text = "Brak danych"
        fields = (
            "id",
            "tytul_oryginalny",
            "autorzy",
            "rok",
            "zrodlo_lub_wydawnictwo_nadrzedne",
            "informacje",
            "rodzaj_publikacji",
            "liczba_wszystkich_autorow",
            "punkty_pk",
            "autor",
            "pbn_id",
            "system_kadrowy_id",
            "orcid",
            "aktualna_jednostka",
            "afiliowana_jednostka",
            "dyscyplina",
            "procent_dyscypliny",
            "subdyscyplina",
            "procent_subdyscypliny",
            "dyscyplina_rekordu",
            "upowaznienie_pbn",
            "profil_orcid",
        )

    pbn_uid_id = Column("PBN UID ID", accessor="autor")

    pkdaut = None
    slot = None
