from __future__ import annotations

import json
import sys
import threading
import urllib.request
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
for path in (ROOT, Path(__file__).resolve().parent):
    if str(path) not in sys.path:
        sys.path.insert(0, str(path))

from Analyze8780.analyze8780_repository import AnalyzeRepository
from Analyze8780.analyze8780_main import build_server


def request_json(url: str, *, method: str = "GET", payload: dict | None = None) -> dict:
    body = json.dumps(payload).encode("utf-8") if payload is not None else None
    req = urllib.request.Request(url, data=body, method=method)
    if body is not None:
        req.add_header("Content-Type", "application/json")
    with urllib.request.urlopen(req, timeout=5) as response:
        return json.loads(response.read().decode("utf-8"))


def test_repository_and_http_api(tmp_path: Path) -> None:
    st_root = tmp_path / "_St"
    st_root.mkdir()
    db_path = st_root / "Shared" / "data" / "sort_local.sqlite3"
    repo = AnalyzeRepository(st_root, db_path)
    a = repo.save_observation({
        "username": "alpha", "shortcode": "A1", "views": 100, "likes": 10,
        "observed_at": "2026-07-19T09:02:00Z",
    })
    repo.save_observation({
        "username": "alpha", "shortcode": "A1", "views": 160, "likes": 14,
        "observed_at": "2026-07-19T09:12:00Z",
    })
    assert repo.accounts()["total"] == 1
    assert repo.account_posts(a["account_id"], sort_by="views_delta")["items"][0]["views_delta"] == 60

    server = build_server(st_root, db_path, "127.0.0.1", 0)
    thread = threading.Thread(target=server.serve_forever, daemon=True)
    thread.start()
    host, port = server.server_address
    base = f"http://{host}:{port}"
    try:
        health = request_json(base + "/api/health")
        assert health["ok"] is True and health["service"] == "Analyze8780"
        accounts = request_json(base + "/api/accounts?page=1&page_size=50")
        assert accounts["total"] == 1
        posts = request_json(base + f"/api/accounts/{a['account_id']}/posts?sort_by=views_delta")
        assert posts["items"][0]["views_per_hour"] == 360
        deleted = request_json(base + f"/api/accounts/{a['account_id']}", method="DELETE")
        assert deleted["deleted"] is True
        tombstones = request_json(base + "/api/deleted/accounts")
        assert tombstones["items"][0]["username"] == "alpha"
    finally:
        server.shutdown()
        server.server_close()
        thread.join(timeout=5)
