"""Phase 1.1 — mandatory-field enforcement on the submit wizard.

A submission must carry its full mandatory metadata set (FRREP-DCI010 / MCL010):
title, abstract, document_type, collection, license_type, and at least one
author. The form mirrors the QA pre-check so junk/empty submissions fail at the
form — before ``ingest_document`` — and create no Document.
"""
from __future__ import annotations

import pytest
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import Client
from django.urls import reverse

from apps.repository.documents.forms import DocumentSubmitForm
from apps.repository.documents.models import Document

PDF_BYTES = (
    b"%PDF-1.4\n%\xe2\xe3\xcf\xd3\n1 0 obj<</Type/Catalog>>endobj\n"
    b"trailer<<>>\n%%EOF\n"
)


def _base_data(collection_pk):
    return {
        "title": "Maize yields under drought",
        "abstract": "A study of drought-tolerant maize across East Africa.",
        "document_type": Document.DocumentType.THESIS,
        "license_type": Document.License.CC_BY,
        "language": "en",
        "year": 2026,
        "collection": collection_pk,
        "authors_text": "Kato, Amina",
    }


# ── Form-level ────────────────────────────────────────────────────────────


@pytest.mark.django_db
def test_form_valid_when_all_mandatory_present(public_collection):
    data = _base_data(public_collection.pk)
    data["staged_token"] = "tok"  # satisfies the file requirement
    form = DocumentSubmitForm(data=data)
    assert form.is_valid(), form.errors


@pytest.mark.django_db
@pytest.mark.parametrize(
    "missing_field",
    ["title", "abstract", "document_type", "license_type", "collection"],
)
def test_form_invalid_when_mandatory_field_missing(public_collection, missing_field):
    data = _base_data(public_collection.pk)
    data["staged_token"] = "tok"
    data[missing_field] = ""
    form = DocumentSubmitForm(data=data)
    assert not form.is_valid()
    assert missing_field in form.errors


@pytest.mark.django_db
def test_form_invalid_when_no_parseable_author(public_collection):
    data = _base_data(public_collection.pk)
    data["staged_token"] = "tok"
    # Neither the registry picker (authors_json) nor the text fallback names an
    # author. The ≥1-author rule now reports on authors_json (Phase 2.1).
    data["authors_text"] = " |  | "
    data["authors_json"] = ""
    form = DocumentSubmitForm(data=data)
    assert not form.is_valid()
    assert "authors_json" in form.errors


@pytest.mark.django_db
def test_form_valid_with_registry_author_payload(public_collection):
    """The registry-first picker satisfies the ≥1-author rule via authors_json,
    with no free-text authors block (Phase 2.1)."""
    from apps.repository.documents import services

    author = services.register_author(name="Amina Kato")
    data = _base_data(public_collection.pk)
    data["staged_token"] = "tok"
    data["authors_text"] = ""
    data["authors_json"] = f'[{{"id": {author.pk}}}]'
    form = DocumentSubmitForm(data=data)
    assert form.is_valid(), form.errors


@pytest.mark.django_db
def test_form_required_set_follows_collection_schema(public_collection):
    """When the collection's MetadataSchema lists extra mandatory fields, the
    form enforces them too (single source of truth shared with the pre-check)."""
    from apps.repository.documents.models import MetadataSchema

    schema = MetadataSchema.objects.create(
        name="Year-required",
        mandatory_fields=["title", "abstract", "license_type", "year"],
    )
    public_collection.metadata_schema = schema
    public_collection.save(update_fields=["metadata_schema"])

    data = _base_data(public_collection.pk)
    data["staged_token"] = "tok"
    data["year"] = ""  # now mandatory via the schema
    form = DocumentSubmitForm(data=data)
    assert not form.is_valid()
    assert "year" in form.errors


# ── View-level: re-renders 200, creates no Document ───────────────────────


@pytest.mark.django_db
@pytest.mark.parametrize(
    "missing_field",
    ["title", "abstract", "document_type", "license_type", "collection", "authors_text"],
)
def test_submit_missing_field_creates_no_document(
    public_collection, submitter_user, missing_field
):
    client = Client()
    client.force_login(submitter_user)
    data = _base_data(public_collection.pk)
    data[missing_field] = ""
    data["file"] = SimpleUploadedFile("t.pdf", PDF_BYTES, content_type="application/pdf")

    resp = client.post(reverse("repo_documents:submit"), data=data)
    assert resp.status_code == 200  # re-renders the wizard, not a redirect
    assert Document.objects.count() == 0


@pytest.mark.django_db
def test_submit_complete_metadata_succeeds(public_collection, submitter_user):
    client = Client()
    client.force_login(submitter_user)
    data = _base_data(public_collection.pk)
    data["file"] = SimpleUploadedFile("t.pdf", PDF_BYTES, content_type="application/pdf")

    resp = client.post(reverse("repo_documents:submit"), data=data)
    assert resp.status_code == 302
    assert Document.objects.count() == 1
    doc = Document.objects.get()
    assert doc.title == "Maize yields under drought"
    assert doc.authors.count() == 1
