"""Firm-managed client creation provisions a Client Portal login."""

from __future__ import annotations

from fastapi.testclient import TestClient

from app.db import SessionLocal, UserRow
from app.main import app
from app.services import users as user_service
from app.store import store
from sqlalchemy import select

client = TestClient(app)


def _firm_email(prefix: str) -> str:
    email = f"firm-create-{prefix}@test.com"
    user_service.ensure_user(platform="firm", email=email, name="Firm User")
    return email


def _create_payload(**overrides):
    body = {
        "name": "Jane Doe",
        "company_name": "Doe Administratie",
        "email": "jane.doe.create@test.com",
        "password": "TempPass12",
        "kvk": "12345678",
    }
    body.update(overrides)
    return body


def test_firm_creates_client_and_portal_login():
    firm_email = _firm_email("ok")
    portal_email = "new-portal-login@test.com"
    password = "TempPass12"
    res = client.post(
        f"/api/v1/clients?platform=firm&email={firm_email}",
        json=_create_payload(email=portal_email, password=password),
    )
    assert res.status_code == 200, res.text
    body = res.json()
    assert body["email"] == portal_email
    assert body["name"] == "Doe Administratie"
    assert body["snelstart"] is False
    assert body.get("snelstartStatus") in {None, "not_connected"}
    assert "password" not in body
    assert "password_hash" not in body
    assert body["portal"]["email"] == portal_email
    assert body["portal"]["name"] == "Jane Doe"
    assert body["portal"]["status"] == "ready"

    with SessionLocal() as session:
        row = session.scalar(
            select(UserRow).where(UserRow.platform == "client", UserRow.email == portal_email)
        )
        assert row is not None
        assert row.client_id == body["id"]
        assert row.password_hash != password
        assert "$" in row.password_hash

    login = client.post(
        "/api/auth/login",
        json={"platform": "client", "email": portal_email, "password": password},
    )
    assert login.status_code == 200, login.text
    assert login.json()["client_id"] == body["id"]
    assert "password" not in login.json()

    overview = client.get(f"/api/v1/clients/{body['id']}?platform=firm&email={firm_email}")
    assert overview.status_code == 200
    data = overview.json()
    assert data["kpis"]["documents"] == 0
    assert data["documents"] == []
    assert data["queries"] == []
    assert data["bank"]["total"] == 0


def test_duplicate_email_is_rejected():
    firm_email = _firm_email("dup")
    portal_email = "dup-portal@test.com"
    first = client.post(
        f"/api/v1/clients?platform=firm&email={firm_email}",
        json=_create_payload(email=portal_email),
    )
    assert first.status_code == 200, first.text
    second = client.post(
        f"/api/v1/clients?platform=firm&email={firm_email}",
        json=_create_payload(email=portal_email, name="Other Person"),
    )
    assert second.status_code == 400
    assert "already exists" in second.json()["detail"].lower()


def test_invalid_email_is_rejected():
    firm_email = _firm_email("email")
    res = client.post(
        f"/api/v1/clients?platform=firm&email={firm_email}",
        json=_create_payload(email="not-an-email"),
    )
    assert res.status_code == 422


def test_short_password_is_rejected():
    firm_email = _firm_email("pwd")
    res = client.post(
        f"/api/v1/clients?platform=firm&email={firm_email}",
        json=_create_payload(email="short-pass@test.com", password="short"),
    )
    assert res.status_code == 422


def test_client_portal_cannot_create_clients():
    portal_email = "cannot-create@test.com"
    created = store.create_client("Blocked Portal", email=portal_email)
    user_service.ensure_user(
        platform="client",
        email=portal_email,
        name="Portal User",
        client_id=created.id,
    )
    res = client.post(
        f"/api/v1/clients?platform=client&email={portal_email}",
        json=_create_payload(email="someone-else@test.com"),
    )
    assert res.status_code == 403


def test_unauthenticated_firm_create_is_rejected():
    res = client.post(
        "/api/v1/clients?platform=firm&email=missing-create@test.com",
        json=_create_payload(email="ghost@test.com"),
    )
    assert res.status_code == 403
