import ast
import unittest
from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]


def source(path: str) -> str:
    return (ROOT / path).read_text(encoding="utf-8")


def class_names(path: str) -> set[str]:
    parsed = ast.parse(source(path))
    return {node.name for node in ast.walk(parsed) if isinstance(node, ast.ClassDef)}


class CustomerCompanyContactsTests(unittest.TestCase):
    def test_models_define_customer_contact_child_table(self) -> None:
        models = source("app/core/models.py")
        names = class_names("app/core/models.py")

        self.assertIn("CustomerContact", names)
        self.assertIn('company_name = Column(String(200))', models)
        self.assertIn('website = Column(String(300))', models)
        self.assertIn('mobile = Column(String(50))', models)
        self.assertIn('customer_id = Column(Integer, ForeignKey("customers.id")', models)
        self.assertIn('contacts = relationship("CustomerContact"', models)

    def test_init_sql_creates_contacts_table(self) -> None:
        sql = source("init_db.sql")

        self.assertIn("company_name VARCHAR(200)", sql)
        self.assertIn("website VARCHAR(300)", sql)
        self.assertIn("mobile VARCHAR(50)", sql)
        self.assertIn("CREATE TABLE IF NOT EXISTS customer_contacts", sql)
        self.assertIn("customer_id INT NOT NULL", sql)
        self.assertIn("is_primary BOOLEAN DEFAULT FALSE", sql)

    def test_customer_api_accepts_and_returns_contacts(self) -> None:
        api = source("app/api/customers.py")
        names = class_names("app/api/customers.py")

        self.assertIn("CustomerContactInput", names)
        self.assertIn("CustomerContactResponse", names)
        self.assertIn("contacts: list[CustomerContactInput]", api)
        self.assertIn("contacts: list[CustomerContactResponse]", api)
        self.assertIn("mobile: str | None = None", api)
        self.assertIn("email: str | None = None", api)
        self.assertIn("_sync_contacts", api)

    def test_frontend_exposes_company_primary_email_field(self) -> None:
        page = source("../frontend/src/pages/CustomersPage.vue")

        self.assertIn("公司主邮箱", page)
        self.assertIn("form.email", page)
        self.assertIn("email: row.email || ''", page)
        self.assertIn("email: form.value.email.trim() || null", page)


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