from sqlalchemy import insert, select, update, and_

from app.dao.base import BaseDAO
from app.database import async_session_maker
from app.users.models import Users
from app.users.chat.models import Chats, Messages


class ChatDAO(BaseDAO):
    model = Chats

    @classmethod
    async def create(cls, user_id: int):
        query = insert(Chats).values(chat_for=user_id)
        async with async_session_maker() as session:
            await session.execute(query)
            await session.commit()
        return True

    @classmethod
    async def send_message(cls, user_id, chat_id: int, message: str):
        query = insert(Messages).values(chat_id=chat_id, user_id=user_id, message=message, image_url=None)
        async with async_session_maker() as session:
            await session.execute(query)
            await session.commit()
        return True

    @classmethod
    async def get_message_by_id(cls, message_id: int):
        query = select(Messages.__table__.columns).where(
            and_(
                Messages.id == message_id,
                Messages.visibility == True
            )

        )
        async with async_session_maker() as session:
            result = await session.execute(query)
        result = result.mappings().all()
        if result:
            return result[0]

    @classmethod
    async def delete_message(cls, message_id: int):
        query = update(Messages).where(Messages.id == message_id).values(visibility=False)
        async with async_session_maker() as session:
            await session.execute(query)
            await session.commit()
        return True

    @classmethod
    async def get_some_messages(cls, chat_id: int, message_number_from: int, messages_to_get: int):
        """
        WITH messages_with_users AS (
            SELECT *
            FROM messages
            LEFT JOIN users ON messages.user_id = users.id
        )

        SELECT message, image_url, chat_id, user_id, created_at, avatar_image
        FROM messages_with_users
        WHERE visibility = true AND chat_id = 2
        ORDER BY created_at DESC
        LIMIT 15 OFFSET 0;
        """
        messages_with_users = (
            select(Messages.__table__.columns, Users.__table__.columns)
            .select_from(Messages)
            .join(Users, Messages.user_id == Users.id)).cte('messages_with_users')

        messages = (select(messages_with_users.c.message, messages_with_users.c.image_url,
                           messages_with_users.c.chat_id, messages_with_users.c.user_id,
                           messages_with_users.c.created_at, messages_with_users.c.avatar_image)
                    .where(
            and_(
                messages_with_users.c.chat_id == chat_id,
                messages_with_users.c.visibility == True
            )
        ).order_by(messages_with_users.c.created_at.desc()).limit(messages_to_get).offset(message_number_from))
        async with async_session_maker() as session:
            result = await session.execute(messages)
        result = result.mappings().all()
        if result:
            return result

