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

A port of `features/calendar/data/mock.js`, which carries the rule and the
reason: the set it replaced was a geometry stress fixture — an untitled event, a
title longer than any column, a backup job at midnight, a block ending at 23:59,
three meetings in one hour — and all of that found real bugs and none of it
belongs on a person's calendar on their first run.

The rule is **an ordinary, liveable week.** Enough on it to be worth looking at,
quiet enough to read at a glance. It still teaches, and the list is here so a
row cannot be deleted without noticing what went with it:

    all four calendars, colour-coded
    a short 15-minute block             the stand-up
    an early block before work          the swim
    two events that overlap             Thursday afternoon
    a reminder, and two on one event    the design review, the dentist
    an all-day event                    the birthday
    a multi-day all-day span            the trip, which crosses the week edge
    an evening that runs past midnight  the party
    something last week and next month, so paging lands on data

Deliberately absent: untitled events, three-deep clusters and anything at 00:00
or 23:59. Those are still worth testing — drag one out on the grid.

**DATES ARE PINNED TO THE START OF THIS WEEK, not to today.** Anchoring on today
puts everything in the right-hand columns on a Friday, so the week view opens
half empty depending on which day somebody first ran the app.

ONE DIFFERENCE FROM THE CLIENT'S SET, and it is forced. **The essay block
carries no `task_id`.** The client's `ev-essay` links to `t-1` in its own Tasks
fixture, 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 and Goals samples drop theirs.
"""

from datetime import date, timedelta


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

    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}',
        'calendar_id': 'personal',
        'title': '',
        'location': '',
        'notes': '',
        'all_day': False,
        'reminders': [],
        'task_id': None,
        'goal_id': None,
        'link_page_id': None,
        'is_sample': True,
    }
    row.update(fields)
    return row


def sample_events(today=None):
    """
    The example week, relative to the SUNDAY of the current week.

    `week_start` is computed from `date.weekday()`, which counts Monday as 0 —
    so Sunday is `(weekday + 1) % 7` days back. Sunday-first because that is
    what the client's fixture anchors on (`startOfWeek(NOW, {weekStartsOn: 0})`),
    and a set generated a day out would draw the stand-up on the wrong morning.
    """
    today = today or date.today()
    week_start = today - timedelta(days=(today.weekday() + 1) % 7)
    day = lambda offset: (week_start + timedelta(days=offset)).isoformat()  # noqa: E731
    at = lambda offset, hhmm: f'{day(offset)}T{hhmm}'  # noqa: E731

    return [
        # ---------------------------------------------------------- Monday
        _sample(
            1,
            calendar_id='health',
            title='Swim',
            location='Pool',
            # Before the working day, so the quiet early hours are not empty.
            start_at=at(1, '06:30'),
            end_at=at(1, '07:30'),
        ),
        _sample(
            2,
            # Fifteen minutes — the shortest block the grid draws.
            calendar_id='work',
            title='Team stand-up',
            location='Meet link',
            start_at=at(1, '09:30'),
            end_at=at(1, '09:45'),
        ),
        _sample(
            3,
            calendar_id='social',
            title='Mum’s birthday',
            notes='Card posted. Ring in the evening.',
            all_day=True,
            # ONE DAY, AND `end_at` IS THAT SAME DAY. Inclusive — the opposite
            # of iCal, where this would end on the Tuesday.
            start_at=day(1),
            end_at=day(1),
        ),
        # --------------------------------------------------------- Tuesday
        _sample(
            4,
            title='Work on the history essay',
            notes='Blocked out for the task of the same name.',
            start_at=at(2, '14:00'),
            end_at=at(2, '16:00'),
        ),
        _sample(
            5,
            title='Groceries',
            start_at=at(2, '18:00'),
            end_at=at(2, '18:45'),
        ),
        # ------------------------------------------------------- Wednesday
        _sample(
            6,
            calendar_id='work',
            title='Design review',
            location='Room 2',
            notes='Bring the two mock-ups.',
            # Two reminders, which is the real shape of one: the day before to
            # get ready, ten minutes before to walk there.
            reminders=[24 * 60, 10],
            start_at=at(3, '10:00'),
            end_at=at(3, '11:30'),
        ),
        _sample(
            7,
            calendar_id='health',
            title='Strength training',
            start_at=at(3, '18:30'),
            end_at=at(3, '19:30'),
        ),
        # -------------------------------------------------------- Thursday
        _sample(
            8,
            # This and the next one run into each other, which is what a real
            # afternoon looks like. The grid splits the hour between them
            # rather than hiding one behind the other.
            calendar_id='health',
            title='Dentist',
            location='12 Bridge Street',
            reminders=[60],
            start_at=at(4, '14:00'),
            end_at=at(4, '15:00'),
        ),
        _sample(
            9,
            calendar_id='social',
            title='Coffee with Mina',
            location='The place by the station',
            start_at=at(4, '14:30'),
            end_at=at(4, '15:30'),
        ),
        # ---------------------------------------------------------- Friday
        _sample(
            10,
            calendar_id='work',
            title='One-to-one with Sam',
            start_at=at(5, '11:00'),
            end_at=at(5, '11:30'),
        ),
        _sample(
            11,
            # Runs past midnight, so it is drawn on both days instead of
            # spilling off the bottom of Friday.
            calendar_id='social',
            title='Reza’s birthday',
            notes='Taxi back — do not drive.',
            start_at=at(5, '22:00'),
            end_at=at(6, '01:00'),
        ),
        # --------------------------------------------------------- all-day
        _sample(
            12,
            # Several days at once, and it runs past the end of the week — so
            # the band clips it and marks that it carries on.
            title='Away visiting family',
            all_day=True,
            start_at=day(5),
            end_at=day(10),
        ),
        # ------------------------------ outside this week, so paging lands
        _sample(
            13,
            calendar_id='health',
            title='Optician',
            start_at=at(-4, '15:00'),
            end_at=at(-4, '15:30'),
        ),
        _sample(
            14,
            calendar_id='work',
            title='Contract renewal',
            start_at=at(26, '11:00'),
            end_at=at(26, '12:00'),
        ),
    ]
