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


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


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


def _get_latest() -> Json:
    pp = max(get_files(config.export_path))
    return json.loads(pp.read_text())


class Competition(NamedTuple):
    contest_id: str
    contest: str
    percentile: float
    dates: str

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

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

    @cached_property
    def when(self) -> datetime:
        return datetime.strptime(self.dates, '%Y-%m-%dT%H:%M:%S.%fZ')

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

    @classmethod
    def make(cls, json) -> Iterator[Res['Competition']]:
        ignore(json, 'rating', 'placement')
        cid = json['challengeId'].zoom().value
        cname = json['challengeName'].zoom().value
        percentile = json['percentile'].zoom().value
        dates = json['date'].zoom().value
        yield cls(
            contest_id=cid,
            contest=cname,
            percentile=percentile,
            dates=dates,
        )


def data() -> Iterator[Res[Competition]]:
    with wrap(_get_latest()) as j:
        ignore(j, 'id', 'version')

        res = j['result'].zoom()  # type: ignore[index]
        ignore(res, 'success', 'status', 'metadata')

        cont = res['content'].zoom()
        ignore(cont, 'handle', 'handleLower', 'userId', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy')

        cont['DEVELOP'].ignore() # TODO handle it??
        ds = cont['DATA_SCIENCE'].zoom()

        mar, srm = zoom(ds, 'MARATHON_MATCH', 'SRM')

        mar = mar['history'].zoom()
        srm = srm['history'].zoom()
    # TODO right, I guess I could rely on pylint for unused variables??

        for c in mar + srm:
            yield from Competition.make(json=c)
            c.consume()

