import json
from pathlib import Path
import pytest

from app.calculator.core import calculate_saju
from app.calculator.analysis import perform_full_analysis
from app.calculator.fortune_scores import calculate_fortune_scores


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_scores_in_valid_range():
    saju, analysis = _saju_for(1990, 5, 15, 14, "male")
    result = calculate_fortune_scores(saju, analysis, 2026)
    for key in ("wealth", "romance", "social", "career", "overall"):
        assert key in result, f"missing key: {key}"
        assert 0 <= result[key] <= 100, f"{key}={result[key]} out of range"


def test_overall_weighted_average():
    saju, analysis = _saju_for(1990, 5, 15, 14, "male")
    r = calculate_fortune_scores(saju, analysis, 2026)
    expected = round(
        r["wealth"] * 0.3 + r["career"] * 0.3 + r["romance"] * 0.2 + r["social"] * 0.2
    )
    assert abs(r["overall"] - expected) <= 1, f"overall mismatch: {r['overall']} vs {expected}"


def test_clamping_lower_bound():
    saju, analysis = _saju_for(2000, 2, 29, 12, "male")
    r = calculate_fortune_scores(saju, analysis, 2026)
    assert all(v >= 0 for v in r.values())


def test_clamping_upper_bound():
    saju, analysis = _saju_for(1985, 1, 1, 0, "female")
    r = calculate_fortune_scores(saju, analysis, 2026)
    assert all(v <= 100 for v in r.values())


def test_different_inputs_different_scores():
    s1, a1 = _saju_for(1990, 5, 15, 14, "male")
    s2, a2 = _saju_for(1985, 1, 1, 0, "female")
    r1 = calculate_fortune_scores(s1, a1, 2026)
    r2 = calculate_fortune_scores(s2, a2, 2026)
    assert r1 != r2, "scores should differ for different sajus"


def test_handles_missing_hour():
    saju, analysis = _saju_for(1990, 5, 15, None, "male")
    r = calculate_fortune_scores(saju, analysis, 2026)
    assert all(0 <= v <= 100 for v in r.values())
