#!/usr/bin/env python3
"""Safe API Push verification — does not enable any live business for outbound push."""

from __future__ import annotations

import json
import os
import sys
import threading
from http.server import BaseHTTPRequestHandler, HTTPServer

from dotenv import load_dotenv

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, BASE_DIR)
load_dotenv(os.path.join(BASE_DIR, ".env"))

from api_push_service import ApiPushService  # noqa: E402
from config import Config  # noqa: E402
from db_handler import DatabaseHandler  # noqa: E402


class ConfigWrapper:
    def __init__(self, config):
        self._config = config

    def get(self, key, default=None):
        return getattr(self._config, key, default)

    def __getattr__(self, key):
        return getattr(self._config, key)


def main() -> int:
    db = DatabaseHandler(ConfigWrapper(Config()))
    db.ensure_api_push_tables()
    svc = ApiPushService(db)

    with db.get_connection() as conn:
        cur = conn.cursor()
        cur.execute(
            "SELECT bid, is_enabled, LEFT(IFNULL(endpoint_url,''), 80) AS url "
            "FROM business_api_push_config"
        )
        rows = list(cur.fetchall() or [])

    enabled = [r for r in rows if int(r.get("is_enabled") or 0) == 1]
    print(f"config_rows={len(rows)} enabled={len(enabled)}")
    for r in enabled:
        print(f"  ENABLED bid={r['bid']} url={r['url']}")

    # Live production BIDs must skip when not configured / disabled
    for bid in ("8837", "1001", "9999"):
        result = svc.push_call_update(bid, "__verify_skip__", force=False)
        assert result.get("skipped"), f"Expected skip for bid={bid}, got {result}"
        print(f"skip_ok bid={bid} message={result.get('message')}")

    # Local webhook e2e using in-memory config (no DB enable of live BID)
    received: list[dict] = []

    class Handler(BaseHTTPRequestHandler):
        def do_POST(self):  # noqa: N802
            length = int(self.headers.get("Content-Length") or 0)
            body = self.rfile.read(length)
            received.append(
                {
                    "path": self.path,
                    "body": json.loads(body.decode("utf-8") or "{}"),
                    "content_type": self.headers.get("Content-Type"),
                }
            )
            self.send_response(200)
            self.end_headers()
            self.wfile.write(b'{"ok":true}')

        def log_message(self, *_args):
            return

    server = HTTPServer(("127.0.0.1", 0), Handler)
    port = server.server_address[1]
    thread = threading.Thread(target=server.serve_forever, daemon=True)
    thread.start()

    fake_cfg = {
        **db._api_push_config_defaults(),
        "is_enabled": 1,
        "endpoint_url": f"http://127.0.0.1:{port}/hook",
        "mapping_key": "phone",
        "mapping_location": "body",
        "mapping_name": "phone_number",
        "selected_fields": ["phone_number", "call_id", "summary", "quality_score"],
        "field_mappings": {
            "phone_number": "phone_number",
            "call_id": "call_id",
            "summary": "summary",
            "quality_score": "quality_score",
        },
        "http_method": "POST",
        "auth_type": "none",
    }
    merged = {
        "bid": "selftest",
        "call_id": "selftest-call-1",
        "phone_number": "919876543210",
        "summary": "Verification summary",
        "quality_score": 88,
        "sentiment": "positive",
        "agentname": "Agent",
        "duration": 42,
        "call_starttime": "2026-08-27 12:00:00",
    }
    payload = svc._build_payload(fake_cfg, merged)
    url, headers = svc._build_request(fake_cfg, fake_cfg["endpoint_url"], "919876543210")
    if fake_cfg["mapping_location"] == "body":
        payload[fake_cfg["mapping_name"]] = "919876543210"

    import requests

    resp = requests.post(url, json=payload, headers=headers, timeout=5)
    server.shutdown()

    assert resp.status_code == 200, resp.text
    assert received, "Local webhook received nothing"
    body = received[0]["body"]
    assert body.get("phone_number") == "919876543210"
    assert body.get("summary") == "Verification summary"
    assert body.get("quality_score") == 88
    print(f"local_webhook_ok status={resp.status_code} payload_keys={sorted(body.keys())}")

    # Preview path for a real bid (no send)
    with db.get_connection() as conn:
        cur = conn.cursor()
        cur.execute(
            "SELECT callid FROM `8837_raw_calls` WHERE status = 3 ORDER BY call_starttime DESC LIMIT 1"
        )
        row = cur.fetchone()
    if row:
        callid = row["callid"]
        preview = svc.preview_call_update("8837", callid)
        print(
            f"dry_run_8837 success={preview.get('success')} "
            f"would_send={preview.get('would_send')} "
            f"enabled={preview.get('is_enabled')} "
            f"msg={preview.get('message')}"
        )
    else:
        print("dry_run_8837 skipped (no analyzed call found)")

    print("ALL_CHECKS_PASSED")
    return 0


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