# -*- coding: utf-8 -*-
# Copyright (c) 2025 ContextForge Contributors.
# SPDX-License-Identifier: Apache-2.0

"""Location: ./tests/playwright/teams/test_team_join_requests.py
Copyright 2026
SPDX-License-Identifier: Apache-2.0
Authors: Mihai Criveti

Team Join Request E2E Tests.

Tests the join request workflow: request, list, approve, reject.
Join requests only work for public-visibility teams.
"""

# Future
from __future__ import annotations

# Standard
import logging
import uuid

# Third-Party
from playwright.sync_api import APIRequestContext, Playwright

# Local
from .conftest import _make_jwt, BASE_URL, create_test_user, delete_test_user

logger = logging.getLogger(__name__)


class TestTeamJoinRequests:
    """Test team join request workflow."""

    def _make_join_request(self, playwright: Playwright, team_id: str, email: str) -> dict:
        """Submit a join request as the given user. Returns the request data."""
        user_jwt = _make_jwt(email, is_admin=False)
        user_ctx = playwright.request.new_context(
            base_url=BASE_URL,
            extra_http_headers={"Authorization": f"Bearer {user_jwt}", "Accept": "application/json"},
        )
        resp = user_ctx.post(f"/teams/{team_id}/join", data={"message": "Please let me join"})
        status = resp.status
        data = resp.json()
        user_ctx.dispose()
        assert status == 200, f"Join request failed: {status}"
        return data

    def test_request_to_join_public_team(self, admin_api: APIRequestContext, public_team: dict, playwright: Playwright):
        """User can request to join a public team."""
        email = f"join-req-{uuid.uuid4().hex[:8]}@example.com"
        create_test_user(admin_api, email)

        req_data = self._make_join_request(playwright, public_team["id"], email)
        assert req_data["status"] == "pending"
        assert req_data["user_email"] == email

        # Cleanup: reject the request (by deleting it)
        admin_api.delete(f"/teams/{public_team['id']}/join-requests/{req_data['id']}")
        delete_test_user(admin_api, email)

    def test_list_join_requests(self, admin_api: APIRequestContext, public_team: dict, playwright: Playwright):
        """Team owner can list pending join requests."""
        email = f"join-list-{uuid.uuid4().hex[:8]}@example.com"
        create_test_user(admin_api, email)
        req_data = self._make_join_request(playwright, public_team["id"], email)

        resp = admin_api.get(f"/teams/{public_team['id']}/join-requests")
        assert resp.status == 200
        requests = resp.json()
        assert isinstance(requests, list)
        req_emails = [r["user_email"] for r in requests]
        assert email in req_emails

        # Cleanup
        admin_api.delete(f"/teams/{public_team['id']}/join-requests/{req_data['id']}")
        delete_test_user(admin_api, email)

    def test_approve_join_request(self, admin_api: APIRequestContext, public_team: dict, playwright: Playwright):
        """Team owner can approve a join request, making the user a member."""
        email = f"join-approve-{uuid.uuid4().hex[:8]}@example.com"
        create_test_user(admin_api, email)
        req_data = self._make_join_request(playwright, public_team["id"], email)

        # Approve
        approve_resp = admin_api.post(f"/teams/{public_team['id']}/join-requests/{req_data['id']}/approve")
        assert approve_resp.status == 200

        # Verify user is now a member
        members_resp = admin_api.get(f"/teams/{public_team['id']}/members")
        members = members_resp.json()
        member_list = members if isinstance(members, list) else members.get("members", [])
        member_emails = [m["user_email"] for m in member_list]
        assert email in member_emails

        # Cleanup
        admin_api.delete(f"/teams/{public_team['id']}/members/{email}")
        delete_test_user(admin_api, email)

    def test_private_team_join_request_denied(self, admin_api: APIRequestContext, private_team: dict, playwright: Playwright):
        """Users cannot request to join private teams."""
        email = f"join-priv-{uuid.uuid4().hex[:8]}@example.com"
        create_test_user(admin_api, email)

        user_jwt = _make_jwt(email, is_admin=False)
        user_ctx = playwright.request.new_context(
            base_url=BASE_URL,
            extra_http_headers={"Authorization": f"Bearer {user_jwt}", "Accept": "application/json"},
        )
        resp = user_ctx.post(f"/teams/{private_team['id']}/join", data={"message": "Let me in"})
        user_ctx.dispose()
        assert resp.status == 403, f"Private team join should be denied, got {resp.status}"

        delete_test_user(admin_api, email)
