# tests/integration/api/v1/admin/test_merchant_domains.py
"""Integration tests for admin merchant domain management endpoints.

Tests the /api/v1/admin/merchants/{id}/domains/* and
/api/v1/admin/merchants/domains/merchant/* endpoints.
"""

import uuid
from datetime import UTC, datetime

import pytest

from app.modules.tenancy.models.merchant_domain import MerchantDomain


@pytest.mark.integration
@pytest.mark.api
@pytest.mark.admin
class TestAdminMerchantDomainsAPI:
    """Test admin merchant domain management endpoints."""

    def test_create_merchant_domain(self, client, admin_headers, test_merchant):
        """Test POST create merchant domain returns 201-equivalent (200 with data)."""
        unique_id = str(uuid.uuid4())[:8]
        response = client.post(
            f"/api/v1/admin/merchants/{test_merchant.id}/domains",
            headers=admin_headers,
            json={
                "domain": f"newmerch{unique_id}.example.com",
                "is_primary": True,
            },
        )

        assert response.status_code == 200
        data = response.json()
        assert data["domain"] == f"newmerch{unique_id}.example.com"
        assert data["merchant_id"] == test_merchant.id
        assert data["is_primary"] is True
        assert data["is_verified"] is False
        assert data["is_active"] is False
        assert data["verification_token"] is not None

    def test_create_duplicate_domain(
        self, client, admin_headers, test_merchant, db
    ):
        """Test POST create duplicate domain returns 409 conflict."""
        unique_id = str(uuid.uuid4())[:8]
        domain_name = f"dup{unique_id}.example.com"

        # Create existing domain
        existing = MerchantDomain(
            merchant_id=test_merchant.id,
            domain=domain_name,
            verification_token=f"dup_{unique_id}",
        )
        db.add(existing)
        db.commit()

        response = client.post(
            f"/api/v1/admin/merchants/{test_merchant.id}/domains",
            headers=admin_headers,
            json={"domain": domain_name, "is_primary": True},
        )

        assert response.status_code == 409
        data = response.json()
        assert data["error_code"] == "MERCHANT_DOMAIN_ALREADY_EXISTS"

    def test_create_domain_invalid_format(
        self, client, admin_headers, test_merchant
    ):
        """Test POST create domain with invalid format returns 422."""
        response = client.post(
            f"/api/v1/admin/merchants/{test_merchant.id}/domains",
            headers=admin_headers,
            json={"domain": "notadomain", "is_primary": True},
        )

        assert response.status_code == 422

    def test_create_domain_merchant_not_found(self, client, admin_headers):
        """Test POST create domain for non-existent merchant returns 404."""
        response = client.post(
            "/api/v1/admin/merchants/99999/domains",
            headers=admin_headers,
            json={"domain": "test.example.com", "is_primary": True},
        )

        assert response.status_code == 404

    def test_list_merchant_domains(
        self, client, admin_headers, test_merchant, db
    ):
        """Test GET list merchant domains returns 200."""
        unique_id = str(uuid.uuid4())[:8]
        domain = MerchantDomain(
            merchant_id=test_merchant.id,
            domain=f"list{unique_id}.example.com",
            verification_token=f"list_{unique_id}",
        )
        db.add(domain)
        db.commit()

        response = client.get(
            f"/api/v1/admin/merchants/{test_merchant.id}/domains",
            headers=admin_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert data["total"] >= 1
        domain_names = [d["domain"] for d in data["domains"]]
        assert f"list{unique_id}.example.com" in domain_names

    def test_get_domain_detail(self, client, admin_headers, test_merchant, db):
        """Test GET domain detail returns 200."""
        unique_id = str(uuid.uuid4())[:8]
        domain = MerchantDomain(
            merchant_id=test_merchant.id,
            domain=f"detail{unique_id}.example.com",
            verification_token=f"det_{unique_id}",
        )
        db.add(domain)
        db.commit()
        db.refresh(domain)

        response = client.get(
            f"/api/v1/admin/merchants/domains/merchant/{domain.id}",
            headers=admin_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert data["id"] == domain.id
        assert data["domain"] == f"detail{unique_id}.example.com"

    def test_update_domain(self, client, admin_headers, test_merchant, db):
        """Test PUT update domain returns 200."""
        unique_id = str(uuid.uuid4())[:8]
        domain = MerchantDomain(
            merchant_id=test_merchant.id,
            domain=f"update{unique_id}.example.com",
            is_verified=True,
            verified_at=datetime.now(UTC),
            is_active=False,
            is_primary=False,
            verification_token=f"upd_{unique_id}",
        )
        db.add(domain)
        db.commit()
        db.refresh(domain)

        response = client.put(
            f"/api/v1/admin/merchants/domains/merchant/{domain.id}",
            headers=admin_headers,
            json={"is_active": True, "is_primary": True},
        )

        assert response.status_code == 200
        data = response.json()
        assert data["is_active"] is True
        assert data["is_primary"] is True

    def test_update_activate_unverified_domain(
        self, client, admin_headers, test_merchant, db
    ):
        """Test PUT activate unverified domain returns 400."""
        unique_id = str(uuid.uuid4())[:8]
        domain = MerchantDomain(
            merchant_id=test_merchant.id,
            domain=f"unver{unique_id}.example.com",
            is_verified=False,
            is_active=False,
            verification_token=f"unv_{unique_id}",
        )
        db.add(domain)
        db.commit()
        db.refresh(domain)

        response = client.put(
            f"/api/v1/admin/merchants/domains/merchant/{domain.id}",
            headers=admin_headers,
            json={"is_active": True},
        )

        assert response.status_code == 400
        data = response.json()
        assert data["error_code"] == "DOMAIN_NOT_VERIFIED"

    def test_delete_domain(self, client, admin_headers, test_merchant, db):
        """Test DELETE domain returns 200."""
        unique_id = str(uuid.uuid4())[:8]
        domain = MerchantDomain(
            merchant_id=test_merchant.id,
            domain=f"del{unique_id}.example.com",
            verification_token=f"del_{unique_id}",
        )
        db.add(domain)
        db.commit()
        db.refresh(domain)

        response = client.delete(
            f"/api/v1/admin/merchants/domains/merchant/{domain.id}",
            headers=admin_headers,
        )

        assert response.status_code == 200
        data = response.json()
        assert "deleted" in data["message"].lower()
        assert data["merchant_id"] == test_merchant.id

    def test_non_admin_access(self, client, auth_headers, test_merchant):
        """Test non-admin access returns 403."""
        response = client.get(
            f"/api/v1/admin/merchants/{test_merchant.id}/domains",
            headers=auth_headers,
        )

        assert response.status_code == 403
