from datetime import datetime, timedelta

from dateutil.relativedelta import relativedelta


def start_of_month(dt: datetime, offset: int) -> datetime:
    first = dt.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
    if offset == 0:
        return first
    return first + relativedelta(months=offset)


def start_of_week(dt: datetime, offset: int, week_start: int) -> datetime:
    midnight = dt.replace(hour=0, minute=0, second=0, microsecond=0)
    days_since_start = (dt.weekday() - week_start) % 7
    week_begin = midnight - timedelta(days=days_since_start)
    if offset == 0:
        return week_begin
    return week_begin + timedelta(weeks=offset)


def start_of_year(dt: datetime, offset: int) -> datetime:
    jan1 = dt.replace(month=1, day=1, hour=0, minute=0, second=0, microsecond=0)
    if offset == 0:
        return jan1
    return jan1.replace(year=jan1.year + offset)
