import uuid
from datetime import datetime

import pytest
from sqlalchemy import select

from app.models.brand import Brand
from app.models.suggestion import Suggestion
from app.models.user import User


class TestSuggestionModel:

    def test_suggestion_table_name(self):
        assert Suggestion.__tablename__ == "suggestions"

    def test_suggestion_has_required_fields(self):
        fields = Suggestion.__table__.columns.keys()
        assert "id" in fields
        assert "brand_id" in fields
        assert "type" in fields
        assert "priority" in fields
        assert "title" in fields
        assert "description" in fields
        assert "action" in fields
        assert "expected_impact" in fields
        assert "difficulty" in fields
        assert "status" in fields
        assert "generated_at" in fields
        assert "updated_at" in fields
        assert "batch_id" in fields
        assert "source" in fields

    def test_suggestion_field_types(self):
        columns = Suggestion.__table__.columns
        id_type = str(columns["id"].type).upper()
        assert "UUID" in id_type or "CHAR" in id_type
        brand_id_type = str(columns["brand_id"].type).upper()
        assert "UUID" in brand_id_type or "CHAR" in brand_id_type
        type_type = str(columns["type"].type).upper()
        assert "VARCHAR" in type_type or "STRING" in type_type
        priority_type = str(columns["priority"].type).upper()
        assert "VARCHAR" in priority_type or "STRING" in priority_type
        title_type = str(columns["title"].type).upper()
        assert "VARCHAR" in title_type or "STRING" in title_type
        assert "TEXT" in str(columns["description"].type).upper()
        difficulty_type = str(columns["difficulty"].type).upper()
        assert "VARCHAR" in difficulty_type or "STRING" in difficulty_type
        status_type = str(columns["status"].type).upper()
        assert "VARCHAR" in status_type or "STRING" in status_type

    def test_suggestion_relationships_defined(self):
        relationships = Suggestion.__mapper__.relationships
        rel_keys = relationships.keys()
        assert "brand" in rel_keys

    def test_suggestion_priority_default(self):
        columns = Suggestion.__table__.columns
        priority_col = columns["priority"]
        assert priority_col.default is not None
        assert priority_col.default.arg == "medium"

    def test_suggestion_status_default(self):
        columns = Suggestion.__table__.columns
        status_col = columns["status"]
        assert status_col.default is not None
        assert status_col.default.arg == "pending"

    def test_suggestion_difficulty_default(self):
        columns = Suggestion.__table__.columns
        difficulty_col = columns["difficulty"]
        assert difficulty_col.default is not None
        assert difficulty_col.default.arg == "medium"

    def test_suggestion_source_default(self):
        columns = Suggestion.__table__.columns
        source_col = columns["source"]
        assert source_col.default is not None
        assert source_col.default.arg == "rule"

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

        suggestion = Suggestion(
            id=uuid.uuid4(),
            brand_id=brand.id,
            type="content_optimization",
            priority="high",
            title="Optimize content structure",
            description="Improve heading hierarchy for better AI citation",
            action="Restructure headings using H2/H3 hierarchy",
            expected_impact="20% increase in citation rate",
            difficulty="easy",
            status="pending",
            source="rule",
        )
        async_session.add(suggestion)
        await async_session.commit()
        await async_session.refresh(suggestion)

        assert suggestion.id is not None
        assert suggestion.brand_id == brand.id
        assert suggestion.type == "content_optimization"
        assert suggestion.priority == "high"
        assert suggestion.title == "Optimize content structure"
        assert suggestion.description == "Improve heading hierarchy for better AI citation"
        assert suggestion.action == "Restructure headings using H2/H3 hierarchy"
        assert suggestion.expected_impact == "20% increase in citation rate"
        assert suggestion.difficulty == "easy"
        assert suggestion.status == "pending"
        assert suggestion.source == "rule"
        assert suggestion.generated_at is not None
        assert suggestion.updated_at is not None
        assert suggestion.batch_id is not None

    @pytest.mark.asyncio
    async def test_suggestion_default_values(self, async_session, test_user):
        brand = Brand(
            user_id=test_user.id,
            name="Default Suggestion Brand",
            platforms=["kimi"],
        )
        async_session.add(brand)
        await async_session.commit()
        await async_session.refresh(brand)

        suggestion = Suggestion(
            brand_id=brand.id,
            type="competitor_gap",
            title="Fill competitor gap",
            description="Address missing topics that competitors cover",
        )
        async_session.add(suggestion)
        await async_session.commit()
        await async_session.refresh(suggestion)

        assert suggestion.priority == "medium"
        assert suggestion.difficulty == "medium"
        assert suggestion.status == "pending"
        assert suggestion.source == "rule"
        assert suggestion.action is None
        assert suggestion.expected_impact is None

    @pytest.mark.asyncio
    async def test_suggestion_query_by_brand(self, async_session, test_user):
        brand = Brand(
            user_id=test_user.id,
            name="Query Suggestion Brand",
            platforms=["wenxin"],
        )
        async_session.add(brand)
        await async_session.commit()
        await async_session.refresh(brand)

        s1 = Suggestion(
            brand_id=brand.id,
            type="content_optimization",
            title="Suggestion 1",
            description="Desc 1",
        )
        s2 = Suggestion(
            brand_id=brand.id,
            type="platform_targeting",
            title="Suggestion 2",
            description="Desc 2",
        )
        async_session.add(s1)
        async_session.add(s2)
        await async_session.commit()

        result = await async_session.execute(
            select(Suggestion).where(Suggestion.brand_id == brand.id)
        )
        suggestions = result.scalars().all()

        assert len(suggestions) == 2
