"""Tests for Brand model."""
import uuid
from datetime import datetime, timezone

import pytest
from sqlalchemy import select

from app.models.brand import Brand


class TestBrandModel:
    """Test cases for Brand model."""

    @pytest.mark.asyncio
    async def test_brand_create(self, async_session, test_user):
        """Test creating a new brand."""
        brand = Brand(
            id=uuid.uuid4(),
            user_id=test_user.id,
            name="Test Brand",
            aliases=["TestBrand", "TB"],
            website="https://testbrand.com",
            industry="technology",
            platforms=["wenxin", "kimi"],
            frequency="weekly",
            status="active",
        )
        async_session.add(brand)
        await async_session.commit()
        await async_session.refresh(brand)

        assert brand.id is not None
        assert brand.user_id == test_user.id
        assert brand.name == "Test Brand"
        assert brand.aliases == ["TestBrand", "TB"]
        assert brand.website == "https://testbrand.com"
        assert brand.industry == "technology"
        assert brand.platforms == ["wenxin", "kimi"]
        assert brand.frequency == "weekly"
        assert brand.status == "active"
        assert brand.created_at is not None
        assert brand.updated_at is not None

    @pytest.mark.asyncio
    async def test_brand_default_values(self, async_session, test_user):
        """Test brand default values."""
        brand = Brand(
            user_id=test_user.id,
            name="Default Brand",
            platforms=["wenxin"],
        )
        async_session.add(brand)
        await async_session.commit()
        await async_session.refresh(brand)

        assert brand.aliases == []
        assert brand.website is None
        assert brand.industry is None
        assert brand.frequency == "weekly"
        assert brand.status == "active"
        assert brand.last_queried_at is None
        assert brand.next_query_at is None

    @pytest.mark.asyncio
    async def test_brand_fields(self, async_session, test_user):
        """Test brand field validation and constraints."""
        brand = Brand(
            user_id=test_user.id,
            name="Field Test Brand",
            aliases=["FTA", "FieldTest"],
            website="https://fieldtest.com",
            industry="finance",
            platforms=["wenxin", "kimi", "tongyi"],
            frequency="daily",
            status="active",
            last_queried_at=datetime.now(timezone.utc),
            next_query_at=datetime.now(timezone.utc),
        )
        async_session.add(brand)
        await async_session.commit()
        await async_session.refresh(brand)

        # Verify all fields
        assert brand.name == "Field Test Brand"
        assert len(brand.name) == 16
        assert brand.aliases == ["FTA", "FieldTest"]
        assert brand.website == "https://fieldtest.com"
        assert len(brand.website) <= 500
        assert brand.industry == "finance"
        assert brand.platforms == ["wenxin", "kimi", "tongyi"]
        assert brand.frequency == "daily"
        assert brand.status == "active"
        assert brand.last_queried_at is not None
        assert brand.next_query_at is not None

    @pytest.mark.asyncio
    async def test_brand_query_by_id(self, async_session, test_user):
        """Test querying brand by ID."""
        brand_id = uuid.uuid4()
        brand = Brand(
            id=brand_id,
            user_id=test_user.id,
            name="Query Test Brand",
            platforms=["wenxin"],
        )
        async_session.add(brand)
        await async_session.commit()

        result = await async_session.execute(
            select(Brand).where(Brand.id == brand_id)
        )
        fetched_brand = result.scalar_one()

        assert fetched_brand is not None
        assert fetched_brand.id == brand_id
        assert fetched_brand.name == "Query Test Brand"

    @pytest.mark.asyncio
    async def test_brand_query_by_user_id(self, async_session, test_user):
        """Test querying brands by user ID."""
        # Create multiple brands for the same user
        brand1 = Brand(
            user_id=test_user.id,
            name="User Brand 1",
            platforms=["wenxin"],
        )
        brand2 = Brand(
            user_id=test_user.id,
            name="User Brand 2",
            platforms=["kimi"],
        )
        async_session.add(brand1)
        async_session.add(brand2)
        await async_session.commit()

        result = await async_session.execute(
            select(Brand).where(Brand.user_id == test_user.id)
        )
        brands = result.scalars().all()

        assert len(brands) == 2

    @pytest.mark.asyncio
    async def test_brand_timestamps(self, async_session, test_user):
        """Test brand created_at and updated_at timestamps."""
        brand = Brand(
            user_id=test_user.id,
            name="Timestamp Brand",
            platforms=["wenxin"],
        )
        async_session.add(brand)
        await async_session.commit()
        await async_session.refresh(brand)

        assert brand.created_at is not None
        assert brand.updated_at is not None
        assert isinstance(brand.created_at, datetime)
        assert isinstance(brand.updated_at, datetime)

    @pytest.mark.asyncio
    async def test_brand_update(self, async_session, test_user):
        """Test updating brand fields."""
        brand = Brand(
            user_id=test_user.id,
            name="Update Test Brand",
            platforms=["wenxin"],
            frequency="weekly",
        )
        async_session.add(brand)
        await async_session.commit()

        # Update brand
        brand.name = "Updated Brand Name"
        brand.frequency = "daily"
        brand.aliases = ["Updated", "Alias"]
        await async_session.commit()
        await async_session.refresh(brand)

        assert brand.name == "Updated Brand Name"
        assert brand.frequency == "daily"
        assert brand.aliases == ["Updated", "Alias"]

    @pytest.mark.asyncio
    async def test_brand_delete(self, async_session, test_user):
        """Test deleting a brand."""
        brand = Brand(
            user_id=test_user.id,
            name="Delete Test Brand",
            platforms=["wenxin"],
        )
        async_session.add(brand)
        await async_session.commit()
        brand_id = brand.id

        await async_session.delete(brand)
        await async_session.commit()

        result = await async_session.execute(
            select(Brand).where(Brand.id == brand_id)
        )
        deleted_brand = result.scalar_one_or_none()

        assert deleted_brand is None
