'''
Weight data (manually logged)
'''

from datetime import datetime
from typing import NamedTuple, Iterator

from ..core import LazyLogger
from ..core.error import Res, set_error_datetime, extract_error_datetime

from .. import orgmode

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


log = LazyLogger('my.body.weight')


class Entry(NamedTuple):
    dt: datetime
    value: float
    # TODO comment??


Result = Res[Entry]


def from_orgmode() -> Iterator[Result]:
    orgs = orgmode.query()
    for o in orgmode.query().all():
        if 'weight' not in o.tags:
            continue
        try:
            # TODO can it throw? not sure
            created = o.created
            assert created is not None
        except Exception as e:
            log.exception(e)
            yield e
            continue
        try:
            w = float(o.heading)
        except Exception as e:
            set_error_datetime(e, dt=created)
            log.exception(e)
            yield e
            continue
        # FIXME use timezone provider
        created = config.default_timezone.localize(created)
        assert created is not None #??? somehow mypy wasn't happy?
        yield Entry(
            dt=created,
            value=w,
            # TODO add org note content as comment?
        )


def make_dataframe(data: Iterator[Result]):
    import pandas as pd
    def it():
        for e in data:
            if isinstance(e, Exception):
                dt = extract_error_datetime(e)
                yield {
                    'dt'    : dt,
                    'error': str(e),
                }
            else:
                yield {
                    'dt'    : e.dt,
                    'weight': e.value,
                }
    df = pd.DataFrame(it())
    df.set_index('dt', inplace=True)
    # TODO not sure about UTC??
    df.index = pd.to_datetime(df.index, utc=True)
    return df


def dataframe():
    entries = from_orgmode()
    return make_dataframe(entries)

# TODO move to a submodule? e.g. my.body.weight.orgmode?
# so there could be more sources
# not sure about my.body thing though
