#!/usr/bin/env python3
"""订阅厂商过滤测试"""

import unittest
from datetime import datetime
from pathlib import Path
from unittest.mock import patch
import sys

sys.path.insert(0, str(Path(__file__).resolve().parents[1]))

import scheduler
import server


class FakeDatetime(datetime):
    @classmethod
    def now(cls):
        return cls(2026, 6, 26, 10, 0, 0)


class TestSubscriptionVendor(unittest.TestCase):
    def test_subscribe_persists_selected_vendor(self):
        with patch.object(server, "ensure_db", return_value=True), \
             patch.object(server.SubscriptionDB, "get_is_priority", return_value=0), \
             patch.object(server.SubscriptionDB, "add", return_value={
                 "success": True,
                 "message": "订阅成功",
                 "queue_position": 1,
             }) as add_subscription:
            response = server.app.test_client().post("/api/subscribe", json={
                "email": "test@example.com",
                "feishu_name": "测试用户",
                "vendor": "gongniu",
            })

        self.assertEqual(response.status_code, 200)
        add_subscription.assert_called_once_with(
            "test@example.com",
            "测试用户",
            "all",
            0,
            vendor="gongniu",
        )

    def test_notifies_matching_vendor_without_blocking_behind_nonmatch(self):
        connectors = [
            {
                "connector_id": "AC-02",
                "connector_name": "2号桩",
                "type": "AC",
                "vendor": "nio",
                "power": 7,
                "state": {"type": "free"},
                "idle_seconds": 120,
            }
        ]
        queue = [
            {"email": "gongniu@example.com", "charger_type": "all", "vendor": "gongniu"},
            {"email": "nio@example.com", "charger_type": "all", "vendor": "nio"},
            {"email": "all@example.com", "charger_type": "all", "vendor": "all"},
        ]

        with patch.object(scheduler, "is_workday", return_value=True), \
             patch.object(scheduler, "datetime", FakeDatetime), \
             patch("db.SubscriptionDB.get_recent_notified", return_value=[]), \
             patch("db.SubscriptionDB.get_unnotified_queue", return_value=queue), \
             patch("db.SubscriptionDB.mark_notified") as mark_notified, \
             patch.object(scheduler, "send_notification_email", return_value=True) as send_email:
            scheduler.check_and_notify_subscribers(connectors)

        send_email.assert_called_once()
        args = send_email.call_args.args
        self.assertEqual(args[0], "nio@example.com")
        self.assertEqual(args[1], "all")
        self.assertEqual(args[6], "nio")
        mark_notified.assert_called_once_with("nio@example.com")

    def test_subscription_requires_charger_type_and_vendor_to_match(self):
        connectors = [
            {
                "connector_id": "AC-JSF01",
                "connector_name": "Giant内部充电桩（JSF-01）01",
                "type": "AC",
                "vendor": "gongniu",
                "power": 7,
                "state": {"type": "free"},
                "idle_seconds": 120,
            },
            {
                "connector_id": "DC-17",
                "connector_name": "17号枪",
                "type": "DC",
                "vendor": "nio",
                "power": 20,
                "state": {"type": "free"},
                "idle_seconds": 120,
            },
        ]
        queue = [
            {"email": "gongniu-dc@example.com", "charger_type": "DC", "vendor": "gongniu"},
            {"email": "gongniu-ac@example.com", "charger_type": "AC", "vendor": "gongniu"},
            {"email": "nio-dc@example.com", "charger_type": "DC", "vendor": "nio"},
        ]

        with patch.object(scheduler, "is_workday", return_value=True), \
             patch.object(scheduler, "datetime", FakeDatetime), \
             patch("db.SubscriptionDB.get_recent_notified", return_value=[]), \
             patch("db.SubscriptionDB.get_unnotified_queue", return_value=queue), \
             patch("db.SubscriptionDB.mark_notified") as mark_notified, \
             patch.object(scheduler, "send_notification_email", return_value=True) as send_email:
            scheduler.check_and_notify_subscribers(connectors)

        notified_emails = [call.args[0] for call in send_email.call_args_list]
        self.assertEqual(notified_emails, ["gongniu-ac@example.com", "nio-dc@example.com"])
        mark_notified.assert_any_call("gongniu-ac@example.com")
        mark_notified.assert_any_call("nio-dc@example.com")


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