"""BE-002: writable cross-org `event`/`form` FKs on the standalone events
ViewSets (EventInvitation, EventTeam, EventSpeaker, EventScheduleItem,
EventRegistration, EventMedia, EventDocument, EventLog, EventBlocklist,
RegistrationFormField, RegistrationFormSubmission) must be rejected, not
merely existence-checked. The nested actions under /api/events/<id>/... are
not reachable through this bug because they always pin `event`/`form` to
the URL's own (already tenant-scoped) object before validation — this file
covers the standalone endpoints where the FK is genuinely attacker-controlled."""
from datetime import datetime, timedelta

import pytest
from rest_framework.test import APIClient

from apps.companies.models import Organization, OrganizationMembership
from apps.core.models import User
from apps.events.models import Event, RegistrationForm


def api(user):
    client = APIClient()
    client.force_authenticate(user)
    return client


@pytest.fixture
def org_a(db):
    return Organization.objects.create(name="Org A")


@pytest.fixture
def org_b(db):
    return Organization.objects.create(name="Org B")


@pytest.fixture
def director_a(org_a):
    user = User.objects.create_user(email="director-a@events.test", password="p", organization_role="director")
    OrganizationMembership.objects.create(organization=org_a, user=user)
    return user


@pytest.fixture
def event_a(org_a, director_a):
    return Event.objects.create(
        organization=org_a, name="Org A Event", event_type="conference",
        start_date=datetime.now(), end_date=datetime.now() + timedelta(hours=2),
        organizer=director_a,
    )


@pytest.fixture
def event_b(org_b, director_a):
    other = User.objects.create_user(email="organizer-b@events.test", password="p")
    OrganizationMembership.objects.create(organization=org_b, user=other)
    return Event.objects.create(
        organization=org_b, name="Org B Event", event_type="conference",
        start_date=datetime.now(), end_date=datetime.now() + timedelta(hours=2),
        organizer=other,
    )


@pytest.mark.django_db
class TestEventInvitationCrossTenantWrite:
    def test_create_rejects_cross_org_event(self, director_a, event_b):
        client = api(director_a)
        resp = client.post("/api/event-invitations/", {
            "event": str(event_b.id), "email": "x@x.com", "name": "X",
        }, format="json")
        assert resp.status_code == 403

    def test_create_same_org_event_succeeds(self, director_a, event_a):
        client = api(director_a)
        resp = client.post("/api/event-invitations/", {
            "event": str(event_a.id), "email": "x@x.com", "name": "X",
        }, format="json")
        assert resp.status_code == 201, resp.content


@pytest.mark.django_db
class TestEventTeamCrossTenantWrite:
    def test_create_rejects_cross_org_event(self, director_a, event_b):
        client = api(director_a)
        resp = client.post("/api/event-teams/", {
            "event": str(event_b.id), "name": "teammate@x.com",
        }, format="json")
        assert resp.status_code == 400
        assert resp.data["event"][0].code == "does_not_exist"


@pytest.mark.django_db
class TestEventSpeakerCrossTenantWrite:
    def test_create_rejects_cross_org_event(self, director_a, event_b):
        client = api(director_a)
        resp = client.post("/api/event-speakers/", {
            "event": str(event_b.id), "name": "Speaker",
        }, format="json")
        assert resp.status_code == 400
        assert resp.data["event"][0].code == "does_not_exist"


@pytest.mark.django_db
class TestEventScheduleItemCrossTenantWrite:
    def test_create_rejects_cross_org_event(self, director_a, event_b):
        client = api(director_a)
        resp = client.post("/api/event-schedule-items/", {
            "event": str(event_b.id), "title": "Session",
            "start_time": "09:00", "end_time": "10:00",
        }, format="json")
        assert resp.status_code == 400
        assert resp.data["event"][0].code == "does_not_exist"


@pytest.mark.django_db
class TestEventRegistrationCrossTenantWrite:
    def test_create_rejects_cross_org_event(self, director_a, event_b):
        client = api(director_a)
        resp = client.post("/api/event-registrations/", {
            "event": str(event_b.id), "name": "Attendee", "email": "attendee@x.com",
        }, format="json")
        assert resp.status_code == 400
        assert resp.data["event"][0].code == "does_not_exist"


@pytest.mark.django_db
class TestEventLogCrossTenantWrite:
    def test_create_rejects_cross_org_event(self, director_a, event_b):
        client = api(director_a)
        resp = client.post("/api/event-logs/", {
            "event": str(event_b.id), "action": "probe",
        }, format="json")
        assert resp.status_code == 400
        assert resp.data["event"][0].code == "does_not_exist"


@pytest.mark.django_db
class TestEventBlocklistCrossTenantWrite:
    def test_create_rejects_cross_org_event(self, director_a, event_b):
        client = api(director_a)
        resp = client.post("/api/event-blocklist/", {
            "event": str(event_b.id), "email": "blocked@x.com",
        }, format="json")
        assert resp.status_code == 400
        assert resp.data["event"][0].code == "does_not_exist"


@pytest.mark.django_db
class TestRegistrationFormFieldCrossTenantWrite:
    def test_create_rejects_cross_org_form(self, director_a, org_a, org_b):
        form_b = RegistrationForm.objects.create(organization=org_b, name="Org B Form")
        client = api(director_a)
        resp = client.post("/api/registration-form-fields/", {
            "form": str(form_b.id), "type": "text", "label": "Name",
        }, format="json")
        assert resp.status_code == 400
        assert resp.data["form"][0].code == "does_not_exist"


@pytest.mark.django_db
class TestRegistrationFormSubmissionCrossTenantWrite:
    def test_create_rejects_cross_org_form(self, director_a, org_a, org_b):
        form_b = RegistrationForm.objects.create(organization=org_b, name="Org B Form")
        client = api(director_a)
        resp = client.post("/api/registration-form-submissions/", {
            "form": str(form_b.id), "submitter_name": "X", "submitter_email": "x@x.com",
        }, format="json")
        assert resp.status_code == 400
        assert resp.data["form"][0].code == "does_not_exist"

    def test_public_submit_is_unaffected(self, org_a):
        from apps.events.models import RegistrationForm as RF
        form_a = RF.objects.create(organization=org_a, name="Public Form", status="published")
        client = APIClient()
        resp = client.post(f"/api/public/registration-forms/{form_a.id}/submit/", {
            "submitter_name": "Public User", "submitter_email": "public@x.com", "answers": {},
        }, format="json")
        assert resp.status_code == 201, resp.content
