"""Phase 8 — revoke_dashboard_share_view smoke tests."""
from __future__ import annotations

import pytest
from django.contrib.auth import get_user_model
from django.urls import reverse

from apps.core.permissions.roles import UserRole
from apps.smehub.investment import services
from apps.smehub.investment.models import DashboardAccessLog, Investor
from apps.smehub.onboarding.models import (
    Business,
    BusinessStage,
    EntrepreneurProfile,
)

User = get_user_model()
pytestmark = pytest.mark.django_db


@pytest.fixture
def admin():
    return User.objects.create_user(
        email="adm-p8s@example.com", password="x",
        is_staff=True, is_superuser=True, role=UserRole.SYSTEM_ADMIN,
    )


@pytest.fixture
def entrepreneur(admin):
    user = User.objects.create_user(
        email="ent-p8s@example.com", password="x", role=UserRole.ENTREPRENEUR,
    )
    profile = EntrepreneurProfile.objects.create(user=user, country="KE")
    profile.verify(by_user=admin)
    profile.save()
    Business.objects.create(
        entrepreneur=profile, name="P8s Biz",
        sector="Agriculture", business_stage=BusinessStage.MVP, country="KE",
    ).verify(by_user=admin)
    return profile


@pytest.fixture
def investor(admin):
    inv_user = User.objects.create_user(
        email="inv-p8s@example.com", password="x", role=UserRole.INVESTOR,
    )
    inv = services.create_investor(
        by_user=admin, org_name="P8s Capital", type=Investor.Type.VC,
        investment_focus=["Agriculture"], geographic_preference=["KE"],
        contact_user=inv_user, auto_verify=True,
    )
    return Investor.objects.get(pk=inv.pk)


@pytest.fixture
def share_log(entrepreneur, investor):
    return services.share_dashboard_with_investor(
        entrepreneur=entrepreneur, investor=investor, scope="full", note="t",
    )


def test_revoke_sets_revoked_at(client, entrepreneur, share_log):
    assert share_log.revoked_at is None
    client.force_login(entrepreneur.user)
    resp = client.post(
        reverse("smehub_investment:revoke_dashboard_share", kwargs={"pk": share_log.pk}),
    )
    assert resp.status_code == 302
    fresh = DashboardAccessLog.objects.get(pk=share_log.pk)
    assert fresh.revoked_at is not None
    assert fresh.is_active is False


def test_revoke_blocks_other_entrepreneur(client, admin, share_log):
    other_user = User.objects.create_user(
        email="other-p8s@example.com", password="x", role=UserRole.ENTREPRENEUR,
    )
    other = EntrepreneurProfile.objects.create(user=other_user, country="UG")
    other.verify(by_user=admin)
    other.save()
    client.force_login(other_user)
    resp = client.post(
        reverse("smehub_investment:revoke_dashboard_share", kwargs={"pk": share_log.pk}),
    )
    assert resp.status_code == 403
    fresh = DashboardAccessLog.objects.get(pk=share_log.pk)
    assert fresh.revoked_at is None


def test_revoke_is_idempotent(client, entrepreneur, share_log):
    client.force_login(entrepreneur.user)
    client.post(reverse("smehub_investment:revoke_dashboard_share", kwargs={"pk": share_log.pk}))
    first = DashboardAccessLog.objects.get(pk=share_log.pk).revoked_at
    # Second POST should not change revoked_at
    client.post(reverse("smehub_investment:revoke_dashboard_share", kwargs={"pk": share_log.pk}))
    second = DashboardAccessLog.objects.get(pk=share_log.pk).revoked_at
    assert first == second
