from __future__ import annotations

import json
import tempfile
import unittest
from datetime import date
from pathlib import Path
from unittest.mock import patch

from daily_report import scheduled


class ScheduledTest(unittest.TestCase):
    def test_send_summary_builds_today_summary_payload(self) -> None:
        with tempfile.TemporaryDirectory(prefix="daily-report-scheduled-") as temp:
            root = Path(temp)
            seed_path = root / "employees.json"
            seed_path.write_text(
                json.dumps(
                    [
                        {"feishu_user_id": "u_1", "name": "Lin", "active": True},
                        {"feishu_user_id": "u_2", "name": "Chen", "active": True},
                    ],
                    ensure_ascii=False,
                ),
                encoding="utf-8",
            )
            fake_file = root / "daily_report" / "config.py"
            fake_file.parent.mkdir()
            fake_file.write_text("", encoding="utf-8")
            env = {
                "DATABASE_PATH": "test.sqlite",
                "EMPLOYEE_SEED_PATH": "employees.json",
                "BASE_URL": "http://localhost:8787",
                "FEISHU_WEBHOOK_URL": "https://example.test/webhook",
            }

            captured = {}

            def fake_send(webhook_url: str, payload: dict, secret: str = "") -> dict:
                captured["webhook_url"] = webhook_url
                captured["payload"] = payload
                captured["secret"] = secret
                return {"ok": True}

            with patch("daily_report.config.__file__", str(fake_file)), patch.dict("os.environ", env, clear=True), patch(
                "daily_report.scheduled.send_webhook", fake_send
            ):
                result = scheduled.send_summary("2026-05-07")

        self.assertEqual(result, {"ok": True})
        self.assertEqual(captured["webhook_url"], "https://example.test/webhook")
        self.assertEqual(captured["secret"], "")
        text = json.dumps(captured["payload"], ensure_ascii=False)
        self.assertIn("2026-05-07 日报提交汇总", text)
        self.assertIn("0/2", text)
        self.assertIn("Chen、Lin", text)

    def test_send_reminder_private_messages_missing_employees_only(self) -> None:
        with tempfile.TemporaryDirectory(prefix="daily-report-scheduled-") as temp:
            root = Path(temp)
            seed_path = root / "employees.json"
            seed_path.write_text(
                json.dumps(
                    [
                        {"feishu_user_id": "ou_1", "name": "Lin", "active": True},
                        {"feishu_user_id": "ou_2", "name": "Chen", "active": True},
                    ],
                    ensure_ascii=False,
                ),
                encoding="utf-8",
            )
            fake_file = root / "daily_report" / "config.py"
            fake_file.parent.mkdir()
            fake_file.write_text("", encoding="utf-8")
            env = {
                "DATABASE_PATH": "test.sqlite",
                "EMPLOYEE_SEED_PATH": "employees.json",
                "BASE_URL": "http://localhost:8787",
                "FEISHU_APP_ID": "cli_test",
                "FEISHU_APP_SECRET": "secret",
            }
            sent = []

            def fake_send(token: str, receive_id: str, payload: dict) -> dict:
                sent.append((token, receive_id, payload))
                return {"ok": True}

            with patch("daily_report.config.__file__", str(fake_file)), patch.dict("os.environ", env, clear=True), patch(
                "daily_report.scheduled.get_tenant_access_token", lambda app_id, app_secret: "tenant-token"
            ), patch("daily_report.scheduled.send_bot_interactive_message", fake_send), patch("daily_report.scheduled.date") as fake_date:
                fake_date.today.return_value = date(2026, 5, 7)
                result = scheduled.send_reminder()

        self.assertEqual(result["mode"], "bot_private")
        self.assertEqual([item[1] for item in sent], ["ou_2", "ou_1"])

    def test_send_reminder_skips_admins(self) -> None:
        with tempfile.TemporaryDirectory(prefix="daily-report-scheduled-") as temp:
            root = Path(temp)
            seed_path = root / "employees.json"
            seed_path.write_text(
                json.dumps(
                    [
                        {"feishu_user_id": "ou_admin", "name": "Admin", "active": True, "role": "admin"},
                        {"feishu_user_id": "ou_staff", "name": "Staff", "active": True, "role": "staff"},
                    ],
                    ensure_ascii=False,
                ),
                encoding="utf-8",
            )
            fake_file = root / "daily_report" / "config.py"
            fake_file.parent.mkdir()
            fake_file.write_text("", encoding="utf-8")
            env = {
                "DATABASE_PATH": "test.sqlite",
                "EMPLOYEE_SEED_PATH": "employees.json",
                "BASE_URL": "http://localhost:8787",
                "FEISHU_APP_ID": "cli_test",
                "FEISHU_APP_SECRET": "secret",
            }
            sent = []

            with patch("daily_report.config.__file__", str(fake_file)), patch.dict("os.environ", env, clear=True), patch(
                "daily_report.scheduled.get_tenant_access_token", lambda app_id, app_secret: "tenant-token"
            ), patch(
                "daily_report.scheduled.send_bot_interactive_message",
                lambda token, receive_id, payload: sent.append(receive_id) or {"ok": True},
            ), patch("daily_report.scheduled.date") as fake_date:
                fake_date.today.return_value = date(2026, 5, 7)
                result = scheduled.send_reminder()

        self.assertEqual(result["mode"], "bot_private")
        self.assertEqual(sent, ["ou_staff"])

    def test_send_summary_private_messages_admins_only(self) -> None:
        with tempfile.TemporaryDirectory(prefix="daily-report-scheduled-") as temp:
            root = Path(temp)
            seed_path = root / "employees.json"
            seed_path.write_text(
                json.dumps(
                    [
                        {"feishu_user_id": "ou_admin", "name": "Admin", "active": True, "role": "admin"},
                        {"feishu_user_id": "ou_staff", "name": "Staff", "active": True, "role": "staff"},
                    ],
                    ensure_ascii=False,
                ),
                encoding="utf-8",
            )
            fake_file = root / "daily_report" / "config.py"
            fake_file.parent.mkdir()
            fake_file.write_text("", encoding="utf-8")
            env = {
                "DATABASE_PATH": "test.sqlite",
                "EMPLOYEE_SEED_PATH": "employees.json",
                "BASE_URL": "http://localhost:8787",
                "FEISHU_APP_ID": "cli_test",
                "FEISHU_APP_SECRET": "secret",
            }
            sent = []

            with patch("daily_report.config.__file__", str(fake_file)), patch.dict("os.environ", env, clear=True), patch(
                "daily_report.scheduled.get_tenant_access_token", lambda app_id, app_secret: "tenant-token"
            ), patch(
                "daily_report.scheduled.send_bot_interactive_message",
                lambda token, receive_id, payload: sent.append(receive_id) or {"ok": True},
            ):
                result = scheduled.send_summary("2026-05-07")

        self.assertEqual(result["mode"], "bot_private")
        self.assertEqual(sent, ["ou_admin"])


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