#!/usr/bin/env python3
from __future__ import annotations

import sys
import unittest
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent))

import generate_manager_brief as gmb


class ManagerBriefTests(unittest.TestCase):
    def setUp(self) -> None:
        self.context = {
            "portfolio_summary": {
                "companies_total": 41,
                "critical_total": 10,
                "high_total": 20,
                "medium_total": 5,
                "low_total": 3,
                "none_total": 3,
                "direct_total": 33,
                "alias_total": 5,
                "manual_total": 3,
                "unmatched_total": 0,
                "stale_7d_total": 4,
                "stale_14d_total": 2,
                "busy_total": 7,
                "activity_30d_total": 12345.0,
                "activity_forecast_30d_total": 54321.0,
                "open_cases_total": 12,
                "detections_total": 20,
            },
            "freshness": [
                {"source": "documents_ts", "stale": False},
                {"source": "signals_ts", "stale": True},
            ],
            "top_risks": [
                {
                    "counterparty": "ФЕЛИЦТ ГРУПП 2026",
                    "signal_severity": "critical",
                    "top_signal": "Есть открытые кейсы",
                    "open_cases_total": 2,
                    "detections_total": 5,
                    "active_locks": 3,
                    "amount_30d": 100.0,
                    "amount_forecast_30d": 300.0,
                }
            ],
            "top_forecasts": [
                {
                    "counterparty": "АВКО 2026",
                    "amount_30d": 1000.0,
                    "amount_forecast_30d": 3000.0,
                    "registry_match_mode": "direct",
                    "signal_severity": "high",
                }
            ],
            "watchlist": [{"counterparty": "АВКО 2026"}],
        }

    def test_deterministic_payload_shape(self) -> None:
        payload = gmb.render_deterministic_payload(self.context)
        self.assertIn("headline", payload)
        self.assertGreaterEqual(len(payload["summary"]), 3)
        self.assertGreaterEqual(len(payload["manager_questions"]), 4)
        self.assertGreaterEqual(len(payload["management_plan"]), 3)
        self.assertEqual(payload["manager_questions"][0]["question"], "Что происходит сейчас?")
        self.assertEqual(payload["management_plan"][0]["horizon"], "today")
        self.assertEqual(payload["top_risks"][0]["company"], "ФЕЛИЦТ ГРУПП 2026")
        self.assertIn("manual", " ".join(payload["caveats"]).lower())
        self.assertTrue(any("прибыл" in item.lower() for item in payload["caveats"]))

    def test_markdown_render(self) -> None:
        payload = gmb.render_deterministic_payload(self.context)
        md = gmb.render_markdown(payload, "2026-05-22T12:00:00+00:00")
        self.assertIn("# Executive Brief 1C", md)
        self.assertIn("## Простые ответы для руководителя", md)
        self.assertIn("## План действий руководителя", md)
        self.assertIn("## Компании риска", md)
        self.assertIn("Есть ли риск падения прибыли в ближайшие 30 дней?", md)
        self.assertIn("Что делать сегодня?", md)
        self.assertIn("ФЕЛИЦТ ГРУПП 2026", md)

    def test_normalize_brief_payload_adds_profit_question_and_plan(self) -> None:
        payload = {
            "headline": "Тест",
            "summary": ["a", "b", "c"],
            "manager_questions": [
                {
                    "question": "Что происходит сейчас?",
                    "answer": "Есть нагрузка.",
                    "recommended_action": "Сфокусироваться на top-компаниях.",
                }
            ],
            "management_plan": [
                {
                    "horizon": "today",
                    "focus": "Снять острый риск.",
                    "action": "Разобрать top-5.",
                    "expected_effect": "Остановить рост проблем.",
                    "metric": "open_cases_total",
                }
            ],
            "top_risks": [],
            "top_forecasts": [],
            "actions": ["Разобрать top-5."],
            "caveats": ["Operational severity не равна финансам."],
        }
        normalized = gmb.normalize_brief_payload(payload, self.context)
        self.assertTrue(any("прибыл" in item["question"].lower() for item in normalized["manager_questions"]))
        self.assertEqual([item["horizon"] for item in normalized["management_plan"]], ["today", "week", "30d"])
        self.assertTrue(any("прибыл" in item.lower() for item in normalized["caveats"]))

    def test_compute_delta_context(self) -> None:
        previous_artifact = {
            "generated_at": "2026-05-22T09:00:00+00:00",
            "context": {
                "generated_at": "2026-05-22T09:00:00+00:00",
                "portfolio_summary": {
                    "companies_total": 40,
                    "critical_total": 8,
                    "high_total": 18,
                    "busy_total": 6,
                    "open_cases_total": 10,
                    "detections_total": 18,
                    "activity_30d_total": 12000.0,
                    "activity_forecast_30d_total": 50000.0,
                },
                "watchlist": [{"infobase": "ИБ1", "counterparty": "СТАРАЯ КОМПАНИЯ"}],
                "portfolio_snapshot": [
                    {
                        "infobase": "ИБ1",
                        "counterparty": "ФЕЛИЦТ ГРУПП 2026",
                        "normalized_counterparty": "ФЕЛИЦТ ГРУПП",
                        "registry_match_mode": "manual",
                        "signal_severity": "high",
                        "signal_score": 70,
                        "current_status": "idle",
                        "active_locks": 1,
                        "days_since_last_activity": 0,
                        "amount_30d": 100.0,
                        "amount_forecast_30d": 200.0,
                        "open_cases_total": 1,
                        "detections_total": 2,
                    }
                ],
            },
        }
        current = dict(self.context)
        current["generated_at"] = "2026-05-22T12:00:00+00:00"
        current["portfolio_snapshot"] = [
            {
                "infobase": "ИБ1",
                "counterparty": "ФЕЛИЦТ ГРУПП 2026",
                "normalized_counterparty": "ФЕЛИЦТ ГРУПП",
                "registry_match_mode": "manual",
                "signal_severity": "critical",
                "signal_score": 95,
                "current_status": "busy",
                "active_locks": 3,
                "days_since_last_activity": 0,
                "amount_30d": 100.0,
                "amount_forecast_30d": 150.0,
                "open_cases_total": 4,
                "detections_total": 5,
            }
        ]
        delta = gmb.compute_delta_context(current, previous_artifact)
        self.assertTrue(delta["available"])
        self.assertEqual(delta["summary"]["critical_total_delta"], 2)
        self.assertIn("ФЕЛИЦТ ГРУПП 2026", delta["new_critical"])
        self.assertEqual(delta["top_changes"][0]["change_type"], "severity_up")
        self.assertIn("priority_score", delta["top_changes"][0])
        self.assertIn("priority_tier", delta["top_changes"][0])


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