import unittest
from datetime import date

import parsers


DAILY_SERIES = """# Apple Health — дневной ряд

> Файл генерируется скриптом **health-sync**

Обновлено: 2026-07-31 17:00 · последний день с данными: 2026-07-31

| Дата | Вес | Жир % | Lean | Шаги | Exer | HRV | Пульс | Сон | Проснулась | Актив. | ДЦ | Преп. |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2026-07-26 | 63.2 | 34.7 | 41.3 | 3120 | 0 | 44.0 | 65 | 5.9 | 1.2 | 1180 | 7 | — |
| 2026-07-29 | — | — | — | 5419 | 35 | 41.6 | 66 | 6.2 | 1.0 | 1604 | 10 | Fe, D, I |
| 2026-07-30 | — | — | — | 8081 | 14 | 43.1 | 67 | 6.4 | 2.1 | 1422 | 11 | Fe, D, I |

## Средние по месяцам

| Месяц | Вес | Шаги | Exer | HRV | Пульс | Сон | Дней |
|---|---|---|---|---|---|---|---|
| 2026-07 | 63.2 | 6104 | 11 | 43.7 | 66 | 6.1 | 31 |
"""


class ParseDailySeriesTest(unittest.TestCase):
    def test_reads_numeric_row(self):
        days = parsers.parse_daily_series(DAILY_SERIES)

        day = days[date(2026, 7, 30)]
        self.assertEqual(day.steps, 8081)
        self.assertEqual(day.exercise_min, 14)
        self.assertEqual(day.sleep_h, 6.4)
        self.assertEqual(day.hrv, 43.1)
        self.assertEqual(day.resting_hr, 67)
        self.assertEqual(day.meds, "Fe, D, I")

    def test_dash_becomes_none(self):
        days = parsers.parse_daily_series(DAILY_SERIES)

        self.assertIsNone(days[date(2026, 7, 30)].weight)
        self.assertIsNone(days[date(2026, 7, 26)].meds)

    def test_monthly_averages_table_is_not_parsed_as_days(self):
        days = parsers.parse_daily_series(DAILY_SERIES)

        self.assertEqual(sorted(days), [date(2026, 7, 26), date(2026, 7, 29), date(2026, 7, 30)])


class FreshnessTest(unittest.TestCase):
    def test_reads_last_day_with_data(self):
        self.assertEqual(parsers.parse_freshness(DAILY_SERIES), date(2026, 7, 31))

    def test_missing_header_returns_none(self):
        self.assertIsNone(parsers.parse_freshness("# Пустой файл\n"))


WORKOUTS = """# Apple Health — тренировки

Обновлено: 2026-07-31 17:00 · последний день с данными: 2026-07-29

| Дата | Тип | Мин | ЧСС ср |
|---|---|---|---|
| 2026-07-25 | Функциональный силовой тренинг | 19 | 105 |
| 2026-07-27 | Функциональный силовой тренинг | 19 | 118 |
| 2026-07-27 | На улице Ходьба | 51 | 104 |
| 2026-07-29 | Классическая силовая тренировка | 28 | 122 |
"""


class ParseWorkoutsTest(unittest.TestCase):
    def test_reads_rows(self):
        workouts = parsers.parse_workouts(WORKOUTS)

        self.assertEqual(len(workouts), 4)
        self.assertEqual(workouts[0].day, date(2026, 7, 25))
        self.assertEqual(workouts[0].minutes, 19)
        self.assertEqual(workouts[0].kind, "Функциональный силовой тренинг")

    def test_strength_flag_covers_both_wordings(self):
        by_day = {w.kind: w for w in parsers.parse_workouts(WORKOUTS)}

        self.assertTrue(by_day["Функциональный силовой тренинг"].is_strength)
        self.assertTrue(by_day["Классическая силовая тренировка"].is_strength)
        self.assertFalse(by_day["На улице Ходьба"].is_strength)


if __name__ == "__main__":
    unittest.main()
