from datetime import date

import pytest

from app.calculator.core import calculate_saju
from app.calculator.analysis import perform_full_analysis
from app.calculator.lucky import calculate_lucky


def _saju_for(year, month, day, hour, gender):
    saju = calculate_saju(year, month, day, hour, gender)
    analysis = perform_full_analysis(saju, 2026)
    return saju, analysis


def test_lucky_keys():
    saju, analysis = _saju_for(1990, 5, 15, 14, "male")
    r = calculate_lucky(saju, analysis, date(2026, 5, 26))
    for k in ("color", "number", "direction", "good_signs", "warnings"):
        assert k in r, f"missing {k}"


def test_lucky_number_range():
    saju, analysis = _saju_for(1990, 5, 15, 14, "male")
    r = calculate_lucky(saju, analysis, date(2026, 5, 26))
    assert 1 <= r["number"] <= 9


def test_lucky_color_from_yongshin():
    saju, analysis = _saju_for(1990, 5, 15, 14, "male")
    r = calculate_lucky(saju, analysis, date(2026, 5, 26))
    assert isinstance(r["color"], list)
    assert len(r["color"]) >= 1
    yongshin = analysis["yong_shin"]["yong_shin"]
    valid_colors_by_element = {
        "木": {"청록", "녹색"},
        "火": {"빨강", "주황"},
        "土": {"황색", "베이지"},
        "金": {"흰색", "은색"},
        "水": {"파랑", "검정"},
    }
    expected_set = valid_colors_by_element[yongshin]
    assert all(c in expected_set for c in r["color"])


def test_lucky_direction_from_yongshin():
    saju, analysis = _saju_for(1990, 5, 15, 14, "male")
    r = calculate_lucky(saju, analysis, date(2026, 5, 26))
    valid_dirs = {"동쪽", "남쪽", "중앙", "서쪽", "북쪽"}
    assert r["direction"] in valid_dirs


def test_good_signs_and_warnings_are_lists():
    saju, analysis = _saju_for(1990, 5, 15, 14, "male")
    r = calculate_lucky(saju, analysis, date(2026, 5, 26))
    assert isinstance(r["good_signs"], list)
    assert isinstance(r["warnings"], list)


def test_handles_missing_hour():
    saju, analysis = _saju_for(1990, 5, 15, None, "male")
    r = calculate_lucky(saju, analysis, date(2026, 5, 26))
    assert 1 <= r["number"] <= 9
