from my.config import codeforces as config  # type: ignore[attr-defined]


from datetime import datetime, timezone
from functools import cached_property
import json
from typing import NamedTuple, Dict, Iterator


from my.core import get_files, Res
from my.core.konsume import ignore, wrap


Cid = int

class Contest(NamedTuple):
    cid: Cid
    when: datetime

    @classmethod
    def make(cls, j) -> 'Contest':
        return cls(
            cid=j['id'],
            when=datetime.fromtimestamp(j['startTimeSeconds'], tz=timezone.utc),
        )

Cmap = Dict[Cid, Contest]


def get_contests() -> Cmap:
    last = max(get_files(config.export_path, 'allcontests*.json'))
    j = json.loads(last.read_text())
    d = {}
    for c in j['result']:
        cc = Contest.make(c)
        d[cc.cid] = cc
    return d


class Competition(NamedTuple):
    contest_id: Cid
    contest: str
    cmap: Cmap

    @cached_property
    def uid(self) -> Cid:
        return self.contest_id

    def __hash__(self):
        return hash(self.contest_id)

    @cached_property
    def when(self) -> datetime:
        return self.cmap[self.uid].when

    @cached_property
    def summary(self) -> str:
        return f'participated in {self.contest}' # TODO 

    @classmethod
    def make(cls, cmap, json) -> Iterator[Res['Competition']]:
        # TODO try here??
        contest_id = json['contestId'].zoom().value
        contest = json['contestName'].zoom().value
        yield cls(
            contest_id=contest_id,
            contest=contest,
            cmap=cmap,
        )
        # TODO ytry???
        ignore(json, 'rank', 'oldRating', 'newRating')


def data() -> Iterator[Res[Competition]]:
    cmap = get_contests()
    last = max(get_files(config.export_path, 'codeforces*.json'))

    with wrap(json.loads(last.read_text())) as j:
        j['status'].ignore()  # type: ignore[index]
        res = j['result'].zoom()  # type: ignore[index]

        for c in list(res): # TODO maybe we want 'iter' method??
            ignore(c, 'handle', 'ratingUpdateTimeSeconds')
            yield from Competition.make(cmap=cmap, json=c)
            c.consume()
            # TODO maybe if they are all empty, no need to consume??
