"""BE-002: writable cross-org FKs on Meeting, MeetingInvitation,
MeetingMinutes and MeetingPresentation must be rejected, not merely
existence-checked. Mirrors the pattern already applied to
apps.hr.serializers.AttendanceSerializer / apps.finance.serializers."""
from datetime import timedelta

import pytest
from django.utils import timezone
from rest_framework.test import APIClient

from apps.companies.models import Organization, OrganizationMembership
from apps.contacts.models import Contact
from apps.core.models import User
from apps.meetings.models import Meeting, MeetingRoom


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@meetings.test", password="p", organization_role="director")
    OrganizationMembership.objects.create(organization=org_a, user=user)
    return user


@pytest.mark.django_db
class TestMeetingCrossTenantWrite:
    def test_create_rejects_cross_org_room(self, director_a, org_a, org_b):
        room_b = MeetingRoom.objects.create(organization=org_b, name="Room B")
        client = api(director_a)
        start = timezone.now() + timedelta(days=1)
        resp = client.post("/api/meetings/", {
            "title": "Standup", "room": str(room_b.id),
            "start_time": start.isoformat(), "end_time": (start + timedelta(hours=1)).isoformat(),
        }, format="json")
        assert resp.status_code == 403
        assert not Meeting.objects.filter(room=room_b).exists()

    def test_create_same_org_room_succeeds(self, director_a, org_a):
        room_a = MeetingRoom.objects.create(organization=org_a, name="Room A")
        client = api(director_a)
        start = timezone.now() + timedelta(days=1)
        resp = client.post("/api/meetings/", {
            "title": "Standup", "room": str(room_a.id),
            "start_time": start.isoformat(), "end_time": (start + timedelta(hours=1)).isoformat(),
        }, format="json")
        assert resp.status_code == 201, resp.content

    def test_update_rejects_reassignment_to_cross_org_room(self, director_a, org_a, org_b):
        room_a = MeetingRoom.objects.create(organization=org_a, name="Room A")
        room_b = MeetingRoom.objects.create(organization=org_b, name="Room B")
        start = timezone.now() + timedelta(days=1)
        meeting = Meeting.objects.create(
            organization=org_a, title="Standup", room=room_a,
            start_time=start, end_time=start + timedelta(hours=1),
        )
        client = api(director_a)
        resp = client.patch(f"/api/meetings/{meeting.id}/", {"room": str(room_b.id)}, format="json")
        assert resp.status_code == 403
        meeting.refresh_from_db()
        assert str(meeting.room_id).replace("-", "") == str(room_a.id).replace("-", "")


@pytest.mark.django_db
class TestMeetingInvitationCrossTenantWrite:
    def test_create_rejects_cross_org_contact(self, director_a, org_a, org_b):
        start = timezone.now() + timedelta(days=1)
        meeting = Meeting.objects.create(
            organization=org_a, title="Standup", start_time=start, end_time=start + timedelta(hours=1),
        )
        contact_b = Contact.objects.create(organization=org_b, name="Org B Contact", email="contact-b@x.com")
        client = api(director_a)
        resp = client.post(f"/api/meetings/{meeting.id}/invitations/", {
            "contact": str(contact_b.id), "email": "contact-b@x.com", "name": "Org B Contact",
        }, format="json")
        assert resp.status_code == 403


@pytest.mark.django_db
class TestMeetingMinutesCrossTenantWrite:
    """The `minutes` action always pins `meeting` to the URL's own (already
    tenant-scoped) meeting before validation, so this path isn't reachable
    through that action — but `MeetingMinutesSerializer` is reusable
    elsewhere, so its own field-level guard is tested directly."""

    def test_serializer_rejects_cross_org_meeting(self, director_a, org_a, org_b):
        from rest_framework.test import APIRequestFactory
        from apps.meetings.serializers import MeetingMinutesSerializer

        start = timezone.now() + timedelta(days=1)
        meeting_b = Meeting.objects.create(
            organization=org_b, title="Org B Standup", start_time=start, end_time=start + timedelta(hours=1),
        )
        request = APIRequestFactory().put("/irrelevant/")
        request.user = director_a
        request.session = {}
        ser = MeetingMinutesSerializer(
            None, data={"meeting": str(meeting_b.id), "body": "leak"}, partial=True,
            context={"request": request},
        )
        assert not ser.is_valid()
        assert ser.errors["meeting"][0].code == "does_not_exist"
