"""QR Menu & QR Ordering repositories — Phase 12.2."""
from __future__ import annotations

from uuid import UUID

from sqlalchemy import select

from app.models.qr import Cart, CartLine, QrCode, QrMenuSession, QrOrderingSession
from app.repositories.base import TenantBaseRepository


class QrCodeRepository(TenantBaseRepository[QrCode]):
    model = QrCode

    async def get_by_code(
        self, tenant_id: UUID, venue_id: UUID, code: str
    ) -> QrCode | None:
        stmt = select(QrCode).where(
            QrCode.tenant_id == tenant_id,
            QrCode.venue_id == venue_id,
            QrCode.code == code,
            QrCode.is_deleted.is_(False),
        )
        result = await self.session.execute(stmt)
        return result.scalar_one_or_none()

    async def get_by_token(self, tenant_id: UUID, token: str) -> QrCode | None:
        stmt = select(QrCode).where(
            QrCode.tenant_id == tenant_id,
            QrCode.token == token,
            QrCode.is_deleted.is_(False),
        )
        result = await self.session.execute(stmt)
        return result.scalar_one_or_none()


class QrMenuSessionRepository(TenantBaseRepository[QrMenuSession]):
    model = QrMenuSession

    async def get_by_token(
        self, tenant_id: UUID, session_token: str
    ) -> QrMenuSession | None:
        stmt = select(QrMenuSession).where(
            QrMenuSession.tenant_id == tenant_id,
            QrMenuSession.session_token == session_token,
            QrMenuSession.is_deleted.is_(False),
        )
        result = await self.session.execute(stmt)
        return result.scalar_one_or_none()


class QrOrderingSessionRepository(TenantBaseRepository[QrOrderingSession]):
    model = QrOrderingSession

    async def get_by_token(
        self, tenant_id: UUID, session_token: str
    ) -> QrOrderingSession | None:
        stmt = select(QrOrderingSession).where(
            QrOrderingSession.tenant_id == tenant_id,
            QrOrderingSession.session_token == session_token,
            QrOrderingSession.is_deleted.is_(False),
        )
        result = await self.session.execute(stmt)
        return result.scalar_one_or_none()


class CartRepository(TenantBaseRepository[Cart]):
    model = Cart

    async def get_by_ordering_session(
        self, tenant_id: UUID, ordering_session_id: UUID
    ) -> Cart | None:
        stmt = select(Cart).where(
            Cart.tenant_id == tenant_id,
            Cart.ordering_session_id == ordering_session_id,
            Cart.is_deleted.is_(False),
        )
        result = await self.session.execute(stmt)
        return result.scalar_one_or_none()


class CartLineRepository(TenantBaseRepository[CartLine]):
    model = CartLine

    async def list_by_cart(self, tenant_id: UUID, cart_id: UUID):
        stmt = select(CartLine).where(
            CartLine.tenant_id == tenant_id,
            CartLine.cart_id == cart_id,
            CartLine.is_deleted.is_(False),
        )
        result = await self.session.execute(stmt)
        return result.scalars().all()
