"""DELETE /api/v1/translations/{job_id} — retrait d'un travail de l'historique.

Contexte : un travail échoué ou oublié par le serveur (rétention 24 h en
mémoire) restait affiché dans « Traductions récentes » sans aucun moyen de
le retirer, et sa page de relecture était vide. La route supprime le
travail de la mémoire, sa clé Redis et ses segments de relecture.
"""

import pytest
from fastapi.testclient import TestClient
from unittest.mock import patch

from main import app
from routes.translate_routes import get_authenticated_user, _translation_jobs


@pytest.fixture()
def client(monkeypatch):
    from middleware.rate_limiting import RateLimitMiddleware

    async def _dispatch(self, request, call_next):
        return await call_next(request)

    monkeypatch.setattr(RateLimitMiddleware, "dispatch", _dispatch)
    return TestClient(app)


class MockUser:
    def __init__(self, user_id="user_123"):
        self.id = user_id
        self.plan = "free"
        self.docs_translated_this_month = 0
        self.pages_translated_this_month = 0
        self.extra_credits = 0


def _make_job(job_id="tr_del1", user_id="user_123", status="completed"):
    return {
        "id": job_id,
        "user_id": user_id,
        "status": status,
        "file_name": "doc.docx",
        "created_at": "2026-09-01T10:00:00",
        "progress_percent": 100,
    }


@pytest.fixture(autouse=True)
def _clean_jobs():
    saved = dict(_translation_jobs)
    _translation_jobs.clear()
    yield
    _translation_jobs.clear()
    _translation_jobs.update(saved)


def _seed_segments(job_id, user_id="user_123", count=2):
    from database.models import Base, TranslationSegment
    from database.connection import sync_engine, get_sync_session

    Base.metadata.create_all(bind=sync_engine)
    with get_sync_session() as session:
        for i in range(count):
            session.add(
                TranslationSegment(
                    job_id=job_id,
                    user_id=user_id,
                    segment_index=i,
                    source_text=f"Hello {i}",
                    translated_text=f"Bonjour {i}",
                    status="pending",
                )
            )
        session.commit()


class TestDeleteTranslationHistory:
    def test_owner_deletes_completed_job(self, client):
        app.dependency_overrides[get_authenticated_user] = _async_user(MockUser())
        _translation_jobs["tr_del1"] = _make_job()
        _seed_segments("tr_del1")

        res = client.delete("/api/v1/translations/tr_del1")
        assert res.status_code == 200
        body = res.json()["data"]
        assert body["deleted"] is True
        assert body["segments_removed"] == 2
        assert "tr_del1" not in _translation_jobs

        from database.connection import get_sync_session
        from database.models import TranslationSegment

        with get_sync_session() as session:
            remaining = (
                session.query(TranslationSegment)
                .filter(TranslationSegment.job_id == "tr_del1")
                .count()
            )
        assert remaining == 0
        app.dependency_overrides.clear()

    def test_delete_is_idempotent_when_job_already_gone(self, client):
        app.dependency_overrides[get_authenticated_user] = _async_user(MockUser())
        # Le serveur a oublié le travail (rétention expirée / redémarrage) :
        # le client veut quand même nettoyer sa liste locale.
        res = client.delete("/api/v1/translations/tr_unknown")
        assert res.status_code == 200
        assert res.json()["data"]["deleted"] is True
        app.dependency_overrides.clear()

    def test_other_users_job_is_404(self, client):
        app.dependency_overrides[get_authenticated_user] = _async_user(MockUser())
        _translation_jobs["tr_someone"] = _make_job("tr_someone", user_id="user_999")
        res = client.delete("/api/v1/translations/tr_someone")
        assert res.status_code == 404
        # Le travail reste intact
        assert "tr_someone" in _translation_jobs
        app.dependency_overrides.clear()

    def test_running_job_requires_cancel_first(self, client):
        app.dependency_overrides[get_authenticated_user] = _async_user(MockUser())
        _translation_jobs["tr_run"] = _make_job("tr_run", status="processing")
        res = client.delete("/api/v1/translations/tr_run")
        assert res.status_code == 409
        assert res.json()["error"] == "JOB_IN_PROGRESS"
        assert "tr_run" in _translation_jobs
        app.dependency_overrides.clear()

    def test_unauthenticated_is_401(self, client):
        async def _anonymous():
            return None

        app.dependency_overrides[get_authenticated_user] = _anonymous
        _translation_jobs["tr_anon"] = _make_job()
        res = client.delete("/api/v1/translations/tr_anon")
        assert res.status_code == 401
        app.dependency_overrides.clear()


def _async_user(user):
    async def _auth():
        return user

    return _auth
