"""Tests for PDF editor route — /api/pdf-editor/edit."""
import io
import json
import os
import tempfile
from unittest.mock import MagicMock

from tests.conftest import make_pdf_bytes


# =========================================================================
# Feature flag enforcement
# =========================================================================
class TestPdfEditorFeatureFlag:
    def test_pdf_editor_disabled_by_default(self, client):
        """Should return 403 when FEATURE_EDITOR is off."""
        data = {
            "file": (io.BytesIO(make_pdf_bytes()), "doc.pdf"),
            "edits": json.dumps([{"type": "text", "page": 1, "x": 100, "y": 200, "content": "Hello"}]),
        }
        response = client.post(
            "/api/pdf-editor/edit",
            data=data,
            content_type="multipart/form-data",
        )
        assert response.status_code == 403
        assert "not enabled" in response.get_json()["error"]


# =========================================================================
# Validation
# =========================================================================
class TestPdfEditorValidation:
    def test_pdf_editor_no_file(self, client, app):
        """Should return 400 when no file provided."""
        app.config["FEATURE_EDITOR"] = True
        response = client.post("/api/pdf-editor/edit")
        assert response.status_code == 400
        assert "No file" in response.get_json()["error"]

    def test_pdf_editor_invalid_json(self, client, app):
        """Should return 400 when edits is invalid JSON."""
        app.config["FEATURE_EDITOR"] = True
        data = {
            "file": (io.BytesIO(make_pdf_bytes()), "doc.pdf"),
            "edits": "not valid json{",
        }
        response = client.post(
            "/api/pdf-editor/edit",
            data=data,
            content_type="multipart/form-data",
        )
        assert response.status_code == 400
        assert "Invalid JSON" in response.get_json()["error"]

    def test_pdf_editor_edits_not_array(self, client, app):
        """Should return 400 when edits is not an array."""
        app.config["FEATURE_EDITOR"] = True
        data = {
            "file": (io.BytesIO(make_pdf_bytes()), "doc.pdf"),
            "edits": json.dumps({"type": "text"}),
        }
        response = client.post(
            "/api/pdf-editor/edit",
            data=data,
            content_type="multipart/form-data",
        )
        assert response.status_code == 400
        assert "JSON array" in response.get_json()["error"]

    def test_pdf_editor_empty_edits(self, client, app):
        """Should return 400 when edits array is empty."""
        app.config["FEATURE_EDITOR"] = True
        data = {
            "file": (io.BytesIO(make_pdf_bytes()), "doc.pdf"),
            "edits": json.dumps([]),
        }
        response = client.post(
            "/api/pdf-editor/edit",
            data=data,
            content_type="multipart/form-data",
        )
        assert response.status_code == 400
        assert "At least one edit" in response.get_json()["error"]

    def test_pdf_editor_too_many_edits(self, client, app):
        """Should return 400 when more than 500 edits."""
        app.config["FEATURE_EDITOR"] = True
        edits = [{"type": "text", "page": 1, "x": 10, "y": 10, "content": "x"}] * 501
        data = {
            "file": (io.BytesIO(make_pdf_bytes()), "doc.pdf"),
            "edits": json.dumps(edits),
        }
        response = client.post(
            "/api/pdf-editor/edit",
            data=data,
            content_type="multipart/form-data",
        )
        assert response.status_code == 400
        assert "500" in response.get_json()["error"]


# =========================================================================
# Success paths
# =========================================================================
class TestPdfEditorSuccess:
    def test_pdf_editor_success(self, client, app, monkeypatch):
        """Should return 202 with task_id when valid request provided."""
        app.config["FEATURE_EDITOR"] = True
        mock_task = MagicMock()
        mock_task.id = "edit-task-1"

        tmp_dir = tempfile.mkdtemp()
        save_path = os.path.join(tmp_dir, "mock.pdf")

        monkeypatch.setattr(
            "app.routes.pdf_editor.validate_actor_file",
            lambda f, allowed_types, actor: ("doc.pdf", "pdf"),
        )
        monkeypatch.setattr(
            "app.routes.pdf_editor.generate_safe_path",
            lambda ext, folder_type: ("mock-id", save_path),
        )
        monkeypatch.setattr(
            "app.routes.pdf_editor.edit_pdf_task.delay",
            MagicMock(return_value=mock_task),
        )

        edits = [
            {"type": "text", "page": 1, "x": 100, "y": 200, "content": "Hello World", "fontSize": 14},
        ]
        data = {
            "file": (io.BytesIO(make_pdf_bytes()), "doc.pdf"),
            "edits": json.dumps(edits),
        }
        response = client.post(
            "/api/pdf-editor/edit",
            data=data,
            content_type="multipart/form-data",
        )
        assert response.status_code == 202
        body = response.get_json()
        assert body["task_id"] == "edit-task-1"
        assert "PDF editing started" in body["message"]
