from __future__ import annotations

import pytest
from fastapi.testclient import TestClient

from app.core.crypto import hash_opaque_token
from app.modules.sync import repository as repo


from uuid import uuid4


@pytest.fixture()
def enterprise(client: TestClient):
    slug = f"test-farm-{uuid4().hex[:8]}"
    ent = repo.create_enterprise("Test Farm Co", slug)
    admin = repo.get_member.__module__  # noqa: ensure import path
    from app.modules.users.repository import get_user_by_email

    user = get_user_by_email("admin@compton.example")
    assert user
    repo.add_member(user.id, ent.id, "admin")
    return ent


def test_sync_capabilities(client: TestClient):
    resp = client.get("/api/v1/sync/capabilities")
    assert resp.status_code == 200
    data = resp.json()
    assert data["protocol_version"] == "1.0"
    assert "global" in data["domains"]


def test_pairing_flow(client: TestClient, enterprise):
    login = client.post("/api/v1/auth/login", json={"email": "admin@compton.example", "password": "Admin1234"})
    token = login.json()["access_token"]
    start = client.post(
        "/api/v1/enterprise/pair/start",
        headers={"Authorization": f"Bearer {token}"},
        json={"enterprise_id": enterprise.id, "farm_name": "Farm A"},
    )
    assert start.status_code == 200
    code = start.json()["code"]
    confirm = client.post(
        "/api/v1/enterprise/pair/confirm",
        json={"code": code, "hub_site_id": "hub-site-001", "hub_name": "Farm A Hub"},
    )
    assert confirm.status_code == 200
    body = confirm.json()
    assert body["hub_site_id"] == "hub-site-001"
    assert body["api_key"]


def test_hub_push_idempotent(client: TestClient, enterprise):
    login = client.post("/api/v1/auth/login", json={"email": "admin@compton.example", "password": "Admin1234"})
    token = login.json()["access_token"]
    start = client.post(
        "/api/v1/enterprise/pair/start",
        headers={"Authorization": f"Bearer {token}"},
        json={"enterprise_id": enterprise.id, "farm_name": "Farm B"},
    )
    code = start.json()["code"]
    confirm = client.post(
        "/api/v1/enterprise/pair/confirm",
        json={"code": code, "hub_site_id": "hub-site-002", "hub_name": "Farm B Hub"},
    )
    api_key = confirm.json()["api_key"]
    hub_auth = f"Hub hub-site-002:{api_key}"
    from datetime import UTC, datetime

    event = {
        "event_id": "evt-001",
        "seq": 1,
        "domain": "global",
        "table": "component",
        "record_id": "comp-001",
        "action": "upsert",
        "version": 1,
        "content_hash": "hash1",
        "payload": {"name": "Corn", "type": "grain", "dry_matter": 88.0},
        "emitted_at": datetime.now(UTC).isoformat(),
        "origin_site_id": "hub-site-002",
    }
    push1 = client.post(
        "/api/v1/sync/changes/push",
        headers={"Authorization": hub_auth},
        json={"events": [event]},
    )
    assert push1.status_code == 200
    assert "evt-001" in push1.json()["applied_event_ids"]
    push2 = client.post(
        "/api/v1/sync/changes/push",
        headers={"Authorization": hub_auth},
        json={"events": [event]},
    )
    assert push2.status_code == 200
    assert "evt-001" in push2.json()["applied_event_ids"]
