from __future__ import annotations

import unittest

from heaven_engine import build_five_phase_field


class FivePhaseFrameworkTests(unittest.TestCase):
    def test_public_field_uses_year_current_qi_day_contract(self):
        field = build_five_phase_field("2026-06-15")

        self.assertEqual(
            field["framework"]["weights"],
            {
                "year_movement": 30,
                "sitian_zaiquan": 20,
                "sitian": 15,
                "zaiquan": 5,
                "host_qi": 20,
                "guest_qi": 25,
                "day": 5,
            },
        )
        self.assertEqual(
            [(layer["id"], layer["weight"]) for layer in field["framework"]["layers"]],
            [("year", 50), ("current", 45), ("day", 5)],
        )
        self.assertEqual(sum(item["score"] for item in field["balance"]), 100)

    def test_sitian_and_zaiquan_follow_half_year_dominance(self):
        first_half = build_five_phase_field("2026-06-15")
        second_half = build_five_phase_field("2026-08-20")

        self.assertEqual(first_half["framework"]["weights"]["sitian"], 15)
        self.assertEqual(first_half["framework"]["weights"]["zaiquan"], 5)
        self.assertEqual(first_half["six_qi"]["ruling"], "司天")
        self.assertEqual(second_half["framework"]["weights"]["sitian"], 5)
        self.assertEqual(second_half["framework"]["weights"]["zaiquan"], 15)
        self.assertEqual(second_half["six_qi"]["ruling"], "在泉")

    def test_guest_host_relation_and_anchor_alignment_are_explicit(self):
        third_qi = build_five_phase_field("2026-06-15")
        final_qi = build_five_phase_field("2026-12-10")
        controlled = build_five_phase_field("2025-02-10")

        self.assertEqual(third_qi["framework"]["relations"]["guest_host"]["label"], "客主同气")
        self.assertEqual(third_qi["six_qi"]["alignment"], "司天同位")
        self.assertEqual(final_qi["framework"]["relations"]["guest_host"]["label"], "客生主")
        self.assertEqual(final_qi["six_qi"]["alignment"], "在泉同位")
        self.assertEqual(controlled["framework"]["relations"]["guest_host"]["order"], "客胜为从")

    def test_tianfu_and_suihui_use_traditional_year_positions(self):
        taiyi = build_five_phase_field("2038-06-15")
        non_suihui = build_five_phase_field("2022-06-15")

        self.assertEqual(
            taiyi["framework"]["relations"]["annual_pattern"]["primary"],
            "太乙天符",
        )
        self.assertFalse(
            non_suihui["framework"]["relations"]["annual_pattern"]["is_suihui"]
        )

    def test_public_field_has_no_observation_hour(self):
        field = build_five_phase_field("2026-07-18")

        self.assertNotIn("time", field["pillars"])
        self.assertNotIn("observation_time", field)

    def test_sector_catalog_lists_all_rules_and_applies_manual_overrides(self):
        field = build_five_phase_field(
            "2026-07-18",
            {"电力": "水", "低空经济": "木"},
        )
        groups = {item["element"]: item["industries"] for item in field["sector_catalog"]}
        names = {
            element: {item["name"]: item["classification_source"] for item in items}
            for element, items in groups.items()
        }

        self.assertEqual(set(groups), {"木", "火", "土", "金", "水"})
        self.assertNotIn("电力", names["火"])
        self.assertEqual(names["水"]["电力"], "manual")
        self.assertEqual(names["木"]["低空经济"], "manual")
        self.assertEqual(sum(len(items) for items in groups.values()), 144)


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