"""对已启动的本地服务执行第一阶段非 AI 业务端到端验收。"""

import argparse
import json
import sys
import time

import httpx
from sqlalchemy import select

from zbt.core.config import Settings
from zbt.infrastructure.mysql.core_models import AsyncTaskRecord
from zbt.infrastructure.mysql.sessions import (
    DatabaseName,
    create_mysql_engine,
    create_session_factory,
)


def main() -> int:
    if hasattr(sys.stdout, "reconfigure"):
        sys.stdout.reconfigure(encoding="utf-8")
    parser = argparse.ArgumentParser()
    parser.add_argument("--base-url", default="http://127.0.0.1:8000/api/v1")
    parser.add_argument("--admin-password", default="zaq1XSW@")
    arguments = parser.parse_args()
    mobile = f"189{int(time.time()) % 100_000_000:08d}"
    with httpx.Client(base_url=arguments.base_url, timeout=30) as client:
        h5_login = client.post(
            "/h5/auth/login",
            json={
                "mobile": mobile,
                "code": "147258",
                "referral_code": "ZBT-SALES-A",
            },
        )
        h5_login.raise_for_status()
        h5_data = h5_login.json()["data"]
        assert h5_data["attribution"]["attributed"] is True
        headers = {
            "Authorization": f"Bearer {h5_data['tokens']['access_token']}",
        }
        products = client.get("/h5/products", headers=headers)
        products.raise_for_status()
        product = next(
            item
            for item in products.json()["data"]["items"]
            if item["product_code"] == "MED-SENIOR"
        )
        quote = client.post(
            "/h5/quotes",
            headers=headers,
            json={
                "product_id": product["product_id"],
                "plan_id": product["plans"][0]["id"],
                "insured": {
                    "age": 65,
                    "region_code": "510100",
                    "occupation_code": "GENERAL",
                },
                "relationship": "PARENT",
            },
        )
        quote.raise_for_status()
        draft = client.post(
            "/h5/enrollment-drafts",
            headers=headers,
            json={
                "quote_id": quote.json()["data"]["quote_id"],
                "applicant": {
                    "name": "端到端验收用户",
                    "id_no": "510104199001011234",
                },
                "insured": {
                    "name": "端到端验收父亲",
                    "id_no": "510104196101011234",
                },
                "contact": {"mobile": mobile},
            },
        )
        draft.raise_for_status()
        draft_id = draft.json()["data"]["draft_id"]
        confirmation = client.post(
            f"/h5/enrollment-drafts/{draft_id}/confirmation",
            headers=headers,
        )
        confirmation.raise_for_status()
        order = client.post(
            "/h5/orders",
            headers={**headers, "Idempotency-Key": f"e2e-order-{mobile}"},
            json={
                "draft_id": draft_id,
                "confirmation_token": confirmation.json()["data"]["confirmation_token"],
            },
        )
        order.raise_for_status()
        order_data = order.json()["data"]
        payment = client.post(
            f"/h5/orders/{order_data['order_id']}/payments",
            headers={**headers, "Idempotency-Key": f"e2e-payment-{mobile}"},
        )
        payment.raise_for_status()
        completed = client.post(
            f"/dev/mock-payments/{payment.json()['data']['payment_id']}/complete",
            headers=headers,
        )
        completed.raise_for_status()
        completion = completed.json()["data"]
        policies = client.get("/h5/policies", headers=headers)
        policies.raise_for_status()

        admin_login = client.post(
            "/admin/auth/login",
            json={"username": "admin", "password": arguments.admin_password},
        )
        admin_login.raise_for_status()
        admin_headers = {
            "Authorization": (f"Bearer {admin_login.json()['data']['tokens']['access_token']}")
        }
        admin_order = client.get(
            f"/admin/orders/{order_data['order_id']}",
            headers=admin_headers,
        )
        attribution = client.get(
            "/admin/attribution/overview",
            headers=admin_headers,
        )
        managed_products = client.get("/admin/products", headers=admin_headers)
        roles = client.get("/admin/roles", headers=admin_headers)
        users = client.get("/admin/users", headers=admin_headers)
        for response in (admin_order, attribution, managed_products, roles, users):
            response.raise_for_status()
        managed_product = managed_products.json()["data"]["items"][0]
        original_status = managed_product["status"]
        changed_status = "INACTIVE" if original_status == "ACTIVE" else "ACTIVE"
        changed_product = client.put(
            f"/admin/products/{managed_product['product_id']}/status",
            headers=admin_headers,
            json={"status": changed_status},
        )
        changed_product.raise_for_status()
        restored_product = client.put(
            f"/admin/products/{managed_product['product_id']}/status",
            headers=admin_headers,
            json={"status": original_status},
        )
        restored_product.raise_for_status()

        salesperson_login = client.post(
            "/admin/auth/login",
            json={"username": "sales_a", "password": arguments.admin_password},
        )
        salesperson_login.raise_for_status()
        salesperson_headers = {
            "Authorization": (
                f"Bearer {salesperson_login.json()['data']['tokens']['access_token']}"
            )
        }
        scoped_orders = client.get("/admin/orders", headers=salesperson_headers)
        scoped_orders.raise_for_status()
        scoped_items = scoped_orders.json()["data"]["items"]
        scoped_order = next(
            item for item in scoped_items if item["order_id"] == order_data["order_id"]
        )
        assert "*" in scoped_order["applicant"]["id_no"]

    settings = Settings()
    engine = create_mysql_engine(settings, DatabaseName.CORE)
    session_factory = create_session_factory(engine)
    with session_factory() as session:
        task = session.scalar(
            select(AsyncTaskRecord).where(
                AsyncTaskRecord.idempotency_key == f"policy.issue:{order_data['order_id']}"
            )
        )
    engine.dispose()
    assert task is not None
    assert task.status == "SUCCEEDED"
    assert task.attempt_count == 1
    assert completion["order_status"] == "ISSUED"
    assert policies.json()["data"]["total"] == 1
    summary = {
        "mobile": mobile,
        "order_no": order_data["order_no"],
        "policy_no": completion["policy"]["policy_no"],
        "task_status": task.status,
        "task_attempt_count": task.attempt_count,
        "attribution_orders": attribution.json()["data"]["order_count"],
        "managed_products": managed_products.json()["data"]["total"],
        "admin_order_visible": (admin_order.json()["data"]["order_id"] == order_data["order_id"]),
        "product_status_restored": (restored_product.json()["data"]["status"] == original_status),
        "role_count": len(roles.json()["data"]["items"]),
        "admin_user_count": len(users.json()["data"]["admin_users"]),
        "salesperson_scoped_orders": len(scoped_items),
        "salesperson_data_masked": "*" in scoped_order["applicant"]["id_no"],
    }
    print(json.dumps(summary, ensure_ascii=False, indent=2))
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
