"""
AIdol chatroom repository

Implements BaseRepository pattern for BaseCrudRouter compatibility.
"""

import uuid
from datetime import datetime, timezone

from aioia_core.repositories import BaseRepository
from sqlalchemy.orm import Session

from aidol.models import DBChatroom, DBMessage
from aidol.schemas import (
    Chatroom,
    ChatroomCreate,
    ChatroomUpdate,
    CompanionMessage,
    Message,
    MessageCreateWithAnonymousId,
    SenderType,
)


def _convert_db_chatroom_to_model(db_chatroom: DBChatroom) -> Chatroom:
    """Convert DB chatroom to Pydantic model."""
    return Chatroom(
        id=db_chatroom.id,
        name=db_chatroom.name,
        language=db_chatroom.language,
        created_at=db_chatroom.created_at.replace(tzinfo=timezone.utc),
        updated_at=db_chatroom.updated_at.replace(tzinfo=timezone.utc),
    )


def _convert_chatroom_create_to_db_model(schema: ChatroomCreate) -> dict:
    """Convert ChatroomCreate schema to DB model data dict."""
    return schema.model_dump(exclude_unset=True)


def _convert_db_message_to_model(db_message: DBMessage) -> Message:
    """Convert DB message to Pydantic model.

    Returns CompanionMessage if sender_type is COMPANION, else Message.
    """
    if db_message.sender_type == SenderType.COMPANION.value:
        return CompanionMessage(
            id=db_message.id,
            sender_type=SenderType.COMPANION,
            content=db_message.content,
            created_at=db_message.created_at.replace(tzinfo=timezone.utc),
        )

    return Message(
        id=db_message.id,
        sender_type=SenderType(db_message.sender_type),
        content=db_message.content,
        created_at=db_message.created_at.replace(tzinfo=timezone.utc),
    )


class ChatroomRepository(
    BaseRepository[Chatroom, DBChatroom, ChatroomCreate, ChatroomUpdate]
):
    """
    Database-backed chatroom repository.

    Extends BaseRepository for CRUD operations compatible with BaseCrudRouter.
    """

    def __init__(self, db_session: Session):
        super().__init__(
            db_session=db_session,
            db_model=DBChatroom,
            convert_to_model=_convert_db_chatroom_to_model,
            convert_to_db_model=_convert_chatroom_create_to_db_model,
        )

    # ========================================
    # AIdol-specific methods
    # ========================================

    def add_message_to_chatroom(
        self, chatroom_id: str, message: MessageCreateWithAnonymousId
    ) -> Message:
        """
        Add message to chatroom.

        Follows aioia-core pattern: CreateSchema (no id) → Model (with id).
        Returned Message always has id set (generated by repository).

        Args:
            chatroom_id: Chatroom ID
            message: MessageCreateWithAnonymousId or CompanionMessageCreate schema (with anonymous_id)

        Returns:
            Message or CompanionMessage with id guaranteed to be set
        """
        # sender_type.value is guaranteed by Pydantic validation
        sender_type_value = message.sender_type.value

        # Get companion_id if available (CompanionMessageCreate has it)
        companion_id = getattr(message, "companion_id", None)

        db_message = DBMessage(
            id=str(uuid.uuid4()),
            chatroom_id=chatroom_id,
            sender_type=sender_type_value,
            content=message.content,
            anonymous_id=message.anonymous_id,
            companion_id=companion_id,
            created_at=datetime.now(timezone.utc),
            updated_at=datetime.now(timezone.utc),
        )
        self.db_session.add(db_message)
        self.db_session.commit()
        self.db_session.refresh(db_message)
        return _convert_db_message_to_model(db_message)

    def get_messages_by_chatroom_id(
        self, chatroom_id: str, limit: int, offset: int
    ) -> list[Message]:
        """
        Get messages in chatroom with pagination.

        Args:
            chatroom_id: Chatroom ID
            limit: Maximum number of messages
            offset: Number of messages to skip

        Returns:
            List of messages ordered by created_at (descending, newest first)
        """
        db_messages = (
            self.db_session.query(DBMessage)
            .filter(DBMessage.chatroom_id == chatroom_id)
            .order_by(DBMessage.created_at.desc())
            .offset(offset)
            .limit(limit)
            .all()
        )
        return [_convert_db_message_to_model(msg) for msg in db_messages]
