import uuid
from datetime import datetime

import pytest
from sqlalchemy import select

from app.models.organization import Organization, OrgMember
from app.models.user import User


class TestOrganizationModel:

    def test_organization_table_name(self):
        assert Organization.__tablename__ == "organizations"

    def test_org_member_table_name(self):
        assert OrgMember.__tablename__ == "org_members"

    def test_organization_has_required_fields(self):
        fields = Organization.__table__.columns.keys()
        assert "id" in fields
        assert "name" in fields
        assert "slug" in fields
        assert "description" in fields
        assert "logo_url" in fields
        assert "plan" in fields
        assert "max_members" in fields
        assert "created_at" in fields
        assert "updated_at" in fields

    def test_org_member_has_required_fields(self):
        fields = OrgMember.__table__.columns.keys()
        assert "id" in fields
        assert "organization_id" in fields
        assert "user_id" in fields
        assert "role" in fields
        assert "joined_at" in fields
        assert "invited_by" in fields

    def test_organization_field_types(self):
        columns = Organization.__table__.columns
        id_type = str(columns["id"].type).upper()
        assert "UUID" in id_type or "CHAR" in id_type
        name_type = str(columns["name"].type).upper()
        assert "VARCHAR" in name_type or "STRING" in name_type
        slug_type = str(columns["slug"].type).upper()
        assert "VARCHAR" in slug_type or "STRING" in slug_type
        assert "INTEGER" in str(columns["max_members"].type).upper()

    def test_org_member_field_types(self):
        columns = OrgMember.__table__.columns
        id_type = str(columns["id"].type).upper()
        assert "UUID" in id_type or "CHAR" in id_type
        org_id_type = str(columns["organization_id"].type).upper()
        assert "UUID" in org_id_type or "CHAR" in org_id_type
        user_id_type = str(columns["user_id"].type).upper()
        assert "UUID" in user_id_type or "CHAR" in user_id_type
        role_type = str(columns["role"].type).upper()
        assert "VARCHAR" in role_type or "STRING" in role_type

    def test_organization_relationships_defined(self):
        relationships = Organization.__mapper__.relationships
        rel_keys = relationships.keys()
        assert "members" in rel_keys
        assert "users" in rel_keys

    def test_org_member_relationships_defined(self):
        relationships = OrgMember.__mapper__.relationships
        rel_keys = relationships.keys()
        assert "organization" in rel_keys
        assert "user" in rel_keys

    @pytest.mark.asyncio
    async def test_organization_create(self, async_session, test_user):
        org = Organization(
            id=uuid.uuid4(),
            name="Test Org",
            slug="test-org",
            description="A test organization",
            logo_url="https://example.com/logo.png",
            plan="free",
            max_members=5,
        )
        async_session.add(org)
        await async_session.commit()
        await async_session.refresh(org)

        assert org.id is not None
        assert org.name == "Test Org"
        assert org.slug == "test-org"
        assert org.description == "A test organization"
        assert org.logo_url == "https://example.com/logo.png"
        assert org.plan == "free"
        assert org.max_members == 5
        assert org.created_at is not None
        assert org.updated_at is not None

    @pytest.mark.asyncio
    async def test_organization_default_values(self, async_session):
        org = Organization(
            name="Default Org",
            slug="default-org",
        )
        async_session.add(org)
        await async_session.commit()
        await async_session.refresh(org)

        assert org.plan == "free"
        assert org.max_members == 5
        assert org.description is None
        assert org.logo_url is None

    @pytest.mark.asyncio
    async def test_org_member_create(self, async_session, test_user):
        org = Organization(
            name="Member Test Org",
            slug="member-test-org",
        )
        async_session.add(org)
        await async_session.commit()
        await async_session.refresh(org)

        member = OrgMember(
            id=uuid.uuid4(),
            organization_id=org.id,
            user_id=test_user.id,
            role="admin",
        )
        async_session.add(member)
        await async_session.commit()
        await async_session.refresh(member)

        assert member.id is not None
        assert member.organization_id == org.id
        assert member.user_id == test_user.id
        assert member.role == "admin"
        assert member.joined_at is not None

    @pytest.mark.asyncio
    async def test_org_member_default_role(self, async_session, test_user):
        org = Organization(
            name="Role Test Org",
            slug="role-test-org",
        )
        async_session.add(org)
        await async_session.commit()
        await async_session.refresh(org)

        member = OrgMember(
            organization_id=org.id,
            user_id=test_user.id,
        )
        async_session.add(member)
        await async_session.commit()
        await async_session.refresh(member)

        assert member.role == "viewer"
        assert member.invited_by is None
