"""
POS Transaction Item Repository using Repository Pattern
"""

from typing import List, Optional
from uuid import UUID
from sqlalchemy import select, and_
from sqlalchemy.ext.asyncio import AsyncSession
import structlog

from app.models.pos_transaction import POSTransactionItem
from shared.database.repository import BaseRepository

logger = structlog.get_logger()


class POSTransactionItemRepository(BaseRepository[POSTransactionItem, dict, dict]):
    """Repository for POS transaction item operations"""

    def __init__(self, session: AsyncSession):
        super().__init__(POSTransactionItem, session)

    async def get_items_by_transaction(
        self,
        transaction_id: UUID
    ) -> List[POSTransactionItem]:
        """Get all items for a transaction"""
        try:
            query = select(POSTransactionItem).where(
                POSTransactionItem.transaction_id == transaction_id
            ).order_by(POSTransactionItem.created_at)

            result = await self.session.execute(query)
            return result.scalars().all()

        except Exception as e:
            logger.error("Failed to get transaction items",
                        transaction_id=str(transaction_id),
                        error=str(e))
            raise

    async def get_items_by_product(
        self,
        tenant_id: UUID,
        product_name: str,
        skip: int = 0,
        limit: int = 100
    ) -> List[POSTransactionItem]:
        """Get all transaction items for a specific product"""
        try:
            query = select(POSTransactionItem).where(
                and_(
                    POSTransactionItem.tenant_id == tenant_id,
                    POSTransactionItem.product_name.ilike(f"%{product_name}%")
                )
            ).order_by(POSTransactionItem.created_at.desc()).offset(skip).limit(limit)

            result = await self.session.execute(query)
            return result.scalars().all()

        except Exception as e:
            logger.error("Failed to get items by product",
                        product_name=product_name,
                        error=str(e))
            raise

    async def get_items_by_sku(
        self,
        tenant_id: UUID,
        sku: str
    ) -> List[POSTransactionItem]:
        """Get all transaction items for a specific SKU"""
        try:
            query = select(POSTransactionItem).where(
                and_(
                    POSTransactionItem.tenant_id == tenant_id,
                    POSTransactionItem.sku == sku
                )
            ).order_by(POSTransactionItem.created_at.desc())

            result = await self.session.execute(query)
            return result.scalars().all()

        except Exception as e:
            logger.error("Failed to get items by SKU",
                        sku=sku,
                        error=str(e))
            raise

    async def get_items_by_category(
        self,
        tenant_id: UUID,
        category: str,
        skip: int = 0,
        limit: int = 100
    ) -> List[POSTransactionItem]:
        """Get all transaction items for a specific category"""
        try:
            query = select(POSTransactionItem).where(
                and_(
                    POSTransactionItem.tenant_id == tenant_id,
                    POSTransactionItem.product_category == category
                )
            ).order_by(POSTransactionItem.created_at.desc()).offset(skip).limit(limit)

            result = await self.session.execute(query)
            return result.scalars().all()

        except Exception as e:
            logger.error("Failed to get items by category",
                        category=category,
                        error=str(e))
            raise
