import os

os.environ.setdefault("WEB_SENTINEL_POSTGRES_URL", "sqlite:///./test_admin_notifications.db")
os.environ.setdefault("WEB_SENTINEL_ADMIN_JWT_SECRET", "test-secret")

from typing import Generator

from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from admin.backend.app.main import create_app
from admin.backend.app.database import get_session
from admin.backend.app.models import Base, AdminConfig
from admin.backend.app.models.admin_user import AdminUser
from admin.backend.app.security import hash_password

en = create_engine(os.environ["WEB_SENTINEL_POSTGRES_URL"], future=True)
Session = sessionmaker(bind=en, autoflush=False, autocommit=False, future=True)

Base.metadata.create_all(bind=en)


def override_session() -> Generator:
    db = Session()
    try:
        yield db
    finally:
        db.close()


app = create_app()
app.dependency_overrides[get_session] = override_session
client = TestClient(app)


def setup_module() -> None:
    Base.metadata.create_all(bind=en)
    with Session() as session:
        session.query(AdminUser).delete()
        session.query(AdminConfig).delete()
        session.add(AdminUser(email="sysop@web-sentinel.com", hashed_password=hash_password("secret"), role="super-admin"))
        session.commit()


def teardown_module() -> None:
    Base.metadata.drop_all(bind=en)


def _login() -> str:
    resp = client.post(
        "/api/v1/auth/login",
        data={"username": "sysop@web-sentinel.com", "password": "secret"},
        headers={"Content-Type": "application/x-www-form-urlencoded"},
    )
    assert resp.status_code == 200
    return resp.json()["access_token"]


def test_templates_cycle():
    token = _login()
    put = client.put(
        "/api/v1/notifications/templates/welcome",
        json={"subject": "Hello", "body": "Welcome"},
        headers={"Authorization": f"Bearer {token}"},
    )
    assert put.status_code == 200
    listing = client.get(
        "/api/v1/notifications/templates",
        headers={"Authorization": f"Bearer {token}"},
    )
    assert listing.status_code == 200
    assert listing.json()["welcome"]["subject"] == "Hello"


def test_slack_webhook_configuration_and_test():
    token = _login()
    payload = {
        "webhook_url": "https://hooks.slack.com/services/T000/B000/TEST",
        "channel": "#critical-alerts",
        "is_enabled": True,
        "severity_threshold": "critical",
        "username": "WebSentinelBot",
    }
    configure = client.put(
        "/api/v1/notifications/webhooks/slack",
        json=payload,
        headers={"Authorization": f"Bearer {token}"},
    )
    assert configure.status_code == 200
    body = configure.json()
    assert body["webhook_url"] == payload["webhook_url"]
    assert body["channel"] == payload["channel"]
    assert body["last_test_at"] is None

    fetched = client.get(
        "/api/v1/notifications/webhooks/slack",
        headers={"Authorization": f"Bearer {token}"},
    )
    assert fetched.status_code == 200

    test_resp = client.post(
        "/api/v1/notifications/webhooks/slack/test",
        json={"message": "Ping critique", "severity": "critical"},
        headers={"Authorization": f"Bearer {token}"},
    )
    assert test_resp.status_code == 200
    test_payload = test_resp.json()
    assert test_payload["status"] == "simulated"
    assert test_payload["preview"] == "Ping critique"

    final_state = client.get(
        "/api/v1/notifications/webhooks/slack",
        headers={"Authorization": f"Bearer {token}"},
    )
    assert final_state.status_code == 200
    final = final_state.json()
    assert final["last_test_status"] == "simulated"
    assert final["last_test_message"] == "Ping critique"
    assert final["last_test_at"] is not None


def test_slack_webhook_disabled_blocks_test():
    token = _login()
    client.put(
        "/api/v1/notifications/webhooks/slack",
        json={
            "webhook_url": "https://hooks.slack.com/services/T000/B000/DISABLED",
            "channel": "#critical-alerts",
            "is_enabled": False,
            "severity_threshold": "warning",
        },
        headers={"Authorization": f"Bearer {token}"},
    )
    test_resp = client.post(
        "/api/v1/notifications/webhooks/slack/test",
        json={"message": "Devrait échouer", "severity": "warning"},
        headers={"Authorization": f"Bearer {token}"},
    )
    assert test_resp.status_code == 400
