from datetime import UTC, datetime

from app.agents.tools.time_reasoning import (
    extract_reference_datetime,
    normalize_tool_time_arguments,
    resolve_time_expression_data,
)


def test_extract_reference_datetime_from_current_time_context():
    context = '【当前时间】\n- current_time_utc: 2026-03-28T12:00:00+00:00\n- current_date_utc: 2026-03-28\n说明：解析相对时间时请以 current_time_utc 为准。'

    result = extract_reference_datetime(context)

    assert result == datetime(2026, 3, 28, 12, 0, tzinfo=UTC)


def test_resolve_time_expression_data_normalizes_relative_datetime():
    payload = resolve_time_expression_data(
        '明天早上9点',
        current_datetime_context='CURRENT_TIME: 2026-03-28T12:00:00+00:00',
        prefer='datetime',
    )

    assert payload['grain'] == 'datetime'
    assert payload['resolved_date'] == '2026-03-29'
    assert payload['resolved_datetime'] == '2026-03-29T09:00:00'
    assert payload['assumed_time'] is False


def test_resolve_time_expression_data_normalizes_relative_date_window():
    payload = resolve_time_expression_data(
        '下周一下午',
        current_datetime_context='CURRENT_TIME: 2026-03-28T12:00:00+00:00',
        prefer='datetime',
    )

    assert payload['resolved_date'] == '2026-03-30'
    assert payload['resolved_datetime'] == '2026-03-30T15:00:00'
    assert payload['assumed_time'] is True
    assert 'assumed_time' in payload['reason']


def test_normalize_tool_time_arguments_converts_reminder_time_aliases():
    normalized = normalize_tool_time_arguments(
        'create_reminder',
        {'title': '开会', 'reminder_at': '明天 09:00'},
        'CURRENT_TIME: 2026-03-28T12:00:00+00:00',
    )

    assert normalized['reminder_at'] == '2026-03-29T09:00:00'


def test_normalize_tool_time_arguments_converts_date_only_tools():
    normalized = normalize_tool_time_arguments(
        'create_goal',
        {'title': '交付节点', 'goal_date': '明天'},
        'CURRENT_TIME: 2026-03-28T12:00:00+00:00',
    )

    assert normalized['goal_date'] == '2026-03-29'


def test_resolve_time_expression_data_preserves_explicit_datetime_offset():
    payload = resolve_time_expression_data(
        '2026-03-29T09:00:00+08:00',
        current_datetime_context='CURRENT_TIME: 2026-03-28T12:00:00+00:00',
        prefer='datetime',
    )

    assert payload['resolved_datetime'] == '2026-03-29T09:00:00+08:00'


def test_normalize_tool_time_arguments_keeps_create_task_date_without_explicit_time():
    normalized = normalize_tool_time_arguments(
        'create_task',
        {'title': '写周报', 'due_date': '明天'},
        'CURRENT_TIME: 2026-03-28T12:00:00+00:00',
    )

    assert normalized['due_date'] == '2026-03-29'


def test_normalize_tool_time_arguments_raises_for_invalid_time_text():
    try:
        normalize_tool_time_arguments(
            'create_reminder',
            {'title': '开会', 'reminder_at': '明天25点'},
            'CURRENT_TIME: 2026-03-28T12:00:00+00:00',
        )
    except ValueError as exc:
        assert 'hour must be in 0..23' in str(exc)
    else:
        raise AssertionError('expected ValueError for invalid time text')
