# -*- coding: utf-8 -*-
"""Junta as asas numa tabela propria: Data/Items/Wings.ini.

    python tools/importar_asas.py            mostra
    python tools/importar_asas.py --aplicar  grava

NAO HA FICHEIRO DE ASAS NO CLIENT

Procurei: nao existe nenhum .lod dedicado, e as asas nao estao nas tabelas de pet. Sao itens
normais, espalhados pelo catalogo. Esta tabela nao descobre nada novo -- junta num sitio so
o que estava disperso pelo Item.ini e pelo ItemOption.ini, que e coisa que se faz muitas
vezes e nunca fica escrita.

O que a torna util e o cruzamento: nome, categoria, slot, nivel exigido, duracao e os
atributos do refino 0, tudo na mesma linha.

DUAS FAMILIAS, E A DIFERENCA IMPORTA

    categoria 25, slot 17     6 asas    defesa 180, def_mag 25, dano 40-90, 14 refinos
                                        nivel 45 a 105, e as UNICAS que se encantam
                                        (a categoria 25 e uma das tres do ItemEnchant)

    categoria 68, slot 30   131 asas    defesa 0, dano 0 -- puramente visuais
                                        nivel 5, com duracao de 1 dia a eternas

    categoria  7             37 asas    caixas que contem asas, nao se equipam (slot 0)

Sao portanto DOIS slots de asa diferentes, 17 e 30, e nao um.

O nivel exigido acompanha o poder: Caos aos 45, anjo e demonio aos 50, Campeao e poderosas
aos 90, Heroi aos 105. As visuais ficam todas nos 5. Nenhuma asa equipavel exige nivel 0.

O classe_req e 0 em todas as 179: qualquer classe usa qualquer asa.

TEMPORARIA E PERMANENTE SAO ITENS DIFERENTES

"Asas da lua (7 dias)" e "Asas da lua (eternos)" tem item_id distintos -- nao e um campo que
se liga nem se apaga. Quem for dar asas no servidor tem de escolher o id certo; a coluna
duracao_seg diz qual e qual (604800 contra 0).
"""
import collections
import os
import sys

RAIZ = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(RAIZ, "server"))
import data_files as D                                              # noqa: E402

TAB = chr(9)
CR = chr(13) + chr(10)


def asas():
    return [r for r in D.tabela("Item") if str(r.get("nome") or "")[:6].find("sas") >= 0]


def main() -> int:
    aplicar = "--aplicar" in sys.argv
    D.carregar()
    lista = asas()
    op = collections.defaultdict(dict)
    for r in D.tabela("ItemOption"):
        if r.get("refino") == 0:
            op[r["item_id"]] = r

    print("asas no catalogo: %d" % len(lista))
    print("por categoria: %s"
          % sorted(collections.Counter(r.get("categoria") for r in lista).items(),
                   key=lambda x: -x[1]))
    print("por slot     : %s"
          % sorted(collections.Counter(r.get("slot") for r in lista).items(),
                   key=lambda x: -x[1]))
    print("com atributos: %d" % sum(1 for r in lista if r["item_id"] in op))
    print()
    print("%-11s %-5s %-5s %-6s %-32s %-8s %s"
          % ("item_id", "cat", "slot", "nivel", "nome", "defesa", "duracao"))
    for r in sorted(lista, key=lambda r: (r.get("categoria") or 0, r["item_id"])):
        if r.get("categoria") != 25:
            continue
        a = op.get(r["item_id"], {})
        print("%-11d %-5s %-5s %-6s %-32s %-8s %s"
              % (r["item_id"], r.get("categoria"), r.get("slot"), r.get("nivel_req"),
                 str(r["nome"])[:32], a.get("defesa", "-"), r.get("duracao_seg")))

    if not aplicar:
        print()
        print("nada gravado. rode com --aplicar")
        return 0

    destino = os.path.join(RAIZ, "server", "Data", "Items", "Wings.ini")
    cols = ["item_id", "nome", "categoria", "slot", "nivel_req", "duracao_seg",
            "modelo", "defesa", "defesa_mag", "dano_min", "dano_max", "refinos"]
    refinos = collections.Counter(r["item_id"] for r in D.tabela("ItemOption"))
    with open(destino, "w", encoding="utf-8", newline="") as fp:
        w = fp.write
        for l in [
            "; Asas -- juntadas do Item.ini e do ItemOption.ini.",
            ";",
            "; NAO HA ficheiro de asas no client: nao existe .lod dedicado e elas nao estao nas",
            "; tabelas de pet. Sao itens normais. Esta tabela nao descobre nada -- poupa o",
            "; cruzamento que se faria a mao de cada vez.",
            ";",
            "; DUAS FAMILIAS:",
            ";   categoria 25, slot 17    6 asas   defesa 180, dano 40-90, 14 refinos,",
            ";                                     nivel 45 a 105, e as UNICAS que se encantam",
            ";   categoria 68, slot 30  131 asas   defesa 0 -- visuais, nivel 5, com duracao",
            ";   categoria  7            37 asas   caixas, nao se equipam (slot 0)",
            ";",
            "; Sao DOIS slots de asa, 17 e 30, e nao um.",
            ";",
            "; classe_req e 0 em todas: qualquer classe usa qualquer asa.",
            ";",
            "; Temporaria e permanente sao ITENS DIFERENTES, com item_id proprio -- nao e um",
            "; campo que se apaga. A coluna duracao_seg diz qual e qual (604800 contra 0).",
            "",
        ]:
            w(l + CR)
        w("//" + TAB.join(cols) + CR)
        for r in sorted(lista, key=lambda r: r["item_id"]):
            a = op.get(r["item_id"], {})
            nome = str(r.get("nome") or "")
            modelo = str(r.get("modelo") or "")
            def c(v):
                s = "" if v is None else str(v)
                return (chr(34) + s + chr(34)) if " " in s else s
            w(TAB.join([
                str(r["item_id"]), c(nome), c(r.get("categoria")), c(r.get("slot")),
                c(r.get("nivel_req")), c(r.get("duracao_seg")), c(modelo),
                c(a.get("defesa")), c(a.get("defesa_mag")),
                c(a.get("dano_min")), c(a.get("dano_max")),
                str(refinos.get(r["item_id"], 0)),
            ]) + CR)

    D.carregar()
    t = D.tabela("Wings")
    print()
    print("gravado: %s (%s bytes)" % (destino, "{:,}".format(os.path.getsize(destino))))
    print("relido: %d linhas, colunas %s" % (len(t), list(t[0].keys())))
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
