"""
EXAMPLE GOALS — written for the USER, not for the developer.

A port of `features/goals/data/mock.js`, which carries the rule and the reason:
"Fill with example data" is an ONBOARDING action, so what it loads must be a
page a real person would be glad to have set. The set this replaced was a
stress fixture — an untitled goal, a target date already nine days gone, a
chain of eleven steps built purely to make the road map wrap — and a page of
behind-schedule goals with a nameless one among them is not an invitation to
plan.

It still teaches. Between them the goals show one clean example of each thing a
goal can be, and the list is here so a row cannot be deleted without noticing
what went with it:

    a road map — an ordered route      1, 6
    a tree — what the goal is made of  4
    no diagram — a standing intention  3
    steps driving progress             1, 4, 6
    weights set by hand                4
    a progress number set by hand      2
    no target date, and that is OK     3
    a goal already achieved            5

FOUR OF THE SIX CARRY A COLOUR and two do not, which is the ratio the diagram
has to survive: a page where everything is coloured never shows that an
uncoloured chain still reads, and a page where nothing is never shows the
feature exists.

Deliberately absent: overdue targets, untitled goals, and chains long enough to
wrap. Those still matter; they are typed in by hand.

ONE DIFFERENCE FROM THE CLIENT'S SET, and it is forced. **`task_ids` is empty
on every row.** The client's `g-6` is the goal its example Tasks page links a
task to, and that link is a pair of real ids which only exist once both pages
have been seeded and written back. A pointer at nothing is worse than no
pointer — the same reason the Tasks sample drops its goal link.
"""

from datetime import date, timedelta


def _sample(index, **fields):
    """
    One example goal.

    Ids are synthetic and local to the response. Nothing is persisted here; the
    client maps them through `fromWire` and they are replaced by real ids the
    moment the set is written back through `bulk`.
    """
    row = {
        'id': f'sample-{index}',
        'title': '',
        'notes': '',
        'status': 'todo',
        'tags': [],
        'target_date': None,
        'color': None,
        'diagram': 'roadmap',
        'progress_fraction': None,
        'steps': [],
        'note_link': None,
        'task_ids': [],
        'properties': {},
        'is_sample': True,
        'completed_at': None,
    }
    row.update(fields)
    return row


def _step(title, done=False, weight=None):
    """
    A step. `weight` stays null unless the case is specifically about
    weighting — null means "split what is left evenly", and a set of weights
    that sums to less than one is left alone rather than normalised.
    """
    slug = ''.join(c if c.isalnum() else '-' for c in title.lower())[:16]
    return {'id': f'st-{slug}', 'title': title, 'done': done, 'weight': weight}


def sample_goals(today=None):
    """
    The example set, dated relative to TODAY at request time.

    A fixture with absolute dates rots into a screen of stale rows, and every
    target date here is in the future — except the achieved goal's, which is in
    the past because that is what achieved means — so a freshly filled page
    opens with nothing already behind.
    """
    today = today or date.today()
    day = lambda offset: (today + timedelta(days=offset)).isoformat()  # noqa: E731
    ago = lambda days: (today - timedelta(days=days)).isoformat() + 'T09:00:00Z'  # noqa: E731

    return [
        _sample(
            1,
            title='Run 10k without stopping',
            notes='One step at a time, in order. That is what the road map is for.',
            status='in_progress',
            tags=['health'],
            target_date=day(70),
            color='green',
            diagram='roadmap',
            steps=[
                _step('Run three times a week', done=True),
                _step('Reach 5k without stopping', done=True),
                _step('Reach 8k'),
                _step('Reach 10k'),
                _step('Pick a route and run it properly'),
            ],
        ),
        _sample(
            2,
            title='Save for a new laptop',
            # A progress number typed by hand. It wins outright over anything
            # the steps would work out, because only the person can see the
            # balance.
            notes='The steps are set up. The number is how much of it is actually saved.',
            status='in_progress',
            tags=['money'],
            target_date=day(150),
            # TEAL, WHERE THE CLIENT'S SET SAYS `mint`. There is no
            # `--icon-mint`: `ICON_COLORS` has ten ids and that is not one of
            # them, so `iconColorStyle` returns undefined and the goal draws
            # uncoloured. The client's own docstring claims four of the six
            # carry a colour, and with `mint` in there only three do.
            color='teal',
            progress_fraction=0.4,
            steps=[
                _step('Open a separate savings account', done=True),
                _step('Move a set amount every month', done=True),
                _step('Compare three models before buying'),
            ],
        ),
        _sample(
            3,
            # NO DIAGRAM and NO TARGET DATE. Not every goal is a project — some
            # are a direction you want to keep going in, and drawing a route
            # for one would be the page insisting otherwise.
            title='Learn to cook six meals properly',
            notes='No deadline on purpose. This one is a direction, not a project.',
            status='in_progress',
            tags=['learning', 'home'],
            diagram='none',
        ),
        _sample(
            4,
            # THE TREE, so the example page shows both drawings side by side.
            # It is also the right one here: weights set by hand are a statement
            # about what the goal is MADE OF, which is the question the tree
            # answers.
            title='Ship the first version of the side project',
            notes='The steps are not equal, so each one is given its own share of the work.',
            status='in_progress',
            tags=['career', 'creative'],
            target_date=day(60),
            color='violet',
            diagram='tree',
            steps=[
                _step('Decide what it actually does', done=True, weight=0.1),
                _step('Design the screens', done=True, weight=0.2),
                _step('Build it', weight=0.5),
                _step('Show it to five people', weight=0.2),
            ],
        ),
        _sample(
            5,
            # ALREADY ACHIEVED, so the Done group is not empty on the first run.
            # It sinks to the bottom and reads 100% from its status alone.
            title='Finish the first-aid course',
            notes='Done. Worth keeping on the page — a finished goal is a good thing to see.',
            status='done',
            tags=['learning', 'health'],
            target_date=day(-14),
            steps=[
                _step('Book a place', done=True),
                _step('Attend both sessions', done=True),
                _step('Pass the test', done=True),
            ],
            completed_at=ago(14),
        ),
        _sample(
            6,
            title='Read 12 books this year',
            notes='Four down. A steady one — a few pages most days is the whole trick.',
            status='in_progress',
            tags=['learning'],
            target_date=day(120),
            color='amber',
            diagram='roadmap',
            steps=[
                _step('Pick the first four', done=True),
                _step('Read one a month', done=True),
                _step('Keep a short note on each'),
                _step('Choose the last three in autumn'),
            ],
        ),
    ]
