# app/services/product_service.py
"""
Product service for vendor catalog management.

This module provides:
- Product catalog CRUD operations
- Product publishing from marketplace staging
- Product search and filtering
"""

import logging
from datetime import UTC, datetime

from sqlalchemy.orm import Session

from app.exceptions import (
    ProductAlreadyExistsException,
    ProductNotFoundException,
    ValidationException,
)
from models.database.marketplace_product import MarketplaceProduct
from models.database.product import Product
from models.schema.product import ProductCreate, ProductUpdate

logger = logging.getLogger(__name__)


class ProductService:
    """Service for vendor catalog product operations."""

    def get_product(self, db: Session, vendor_id: int, product_id: int) -> Product:
        """
        Get a product from vendor catalog.

        Args:
            db: Database session
            vendor_id: Vendor ID
            product_id: Product ID

        Returns:
            Product object

        Raises:
            ProductNotFoundException: If product not found
        """
        try:
            product = (
                db.query(Product)
                .filter(Product.id == product_id, Product.vendor_id == vendor_id)
                .first()
            )

            if not product:
                raise ProductNotFoundException(f"Product {product_id} not found")

            return product

        except ProductNotFoundException:
            raise
        except Exception as e:
            logger.error(f"Error getting product: {str(e)}")
            raise ValidationException("Failed to retrieve product")

    def create_product(
        self, db: Session, vendor_id: int, product_data: ProductCreate
    ) -> Product:
        """
        Add a product from marketplace to vendor catalog.

        Args:
            db: Database session
            vendor_id: Vendor ID
            product_data: Product creation data

        Returns:
            Created Product object

        Raises:
            ProductAlreadyExistsException: If product already in catalog
            ValidationException: If marketplace product not found
        """
        try:
            # Verify marketplace product exists and belongs to vendor
            marketplace_product = (
                db.query(MarketplaceProduct)
                .filter(
                    MarketplaceProduct.id == product_data.marketplace_product_id,
                    MarketplaceProduct.vendor_id == vendor_id,
                )
                .first()
            )

            if not marketplace_product:
                raise ValidationException(
                    f"Marketplace product {product_data.marketplace_product_id} not found"
                )

            # Check if already in catalog
            existing = (
                db.query(Product)
                .filter(
                    Product.vendor_id == vendor_id,
                    Product.marketplace_product_id
                    == product_data.marketplace_product_id,
                )
                .first()
            )

            if existing:
                raise ProductAlreadyExistsException("Product already exists in catalog")

            # Create product
            product = Product(
                vendor_id=vendor_id,
                marketplace_product_id=product_data.marketplace_product_id,
                product_id=product_data.product_id,
                price=product_data.price,
                sale_price=product_data.sale_price,
                currency=product_data.currency,
                availability=product_data.availability,
                condition=product_data.condition,
                is_featured=product_data.is_featured,
                is_active=True,
                min_quantity=product_data.min_quantity,
                max_quantity=product_data.max_quantity,
            )

            db.add(product)
            db.flush()
            db.refresh(product)

            logger.info(f"Added product {product.id} to vendor {vendor_id} catalog")
            return product

        except (ProductAlreadyExistsException, ValidationException):
            raise
        except Exception as e:
            logger.error(f"Error creating product: {str(e)}")
            raise ValidationException("Failed to create product")

    def update_product(
        self,
        db: Session,
        vendor_id: int,
        product_id: int,
        product_update: ProductUpdate,
    ) -> Product:
        """
        Update product in vendor catalog.

        Args:
            db: Database session
            vendor_id: Vendor ID
            product_id: Product ID
            product_update: Update data

        Returns:
            Updated Product object
        """
        try:
            product = self.get_product(db, vendor_id, product_id)

            # Update fields
            update_data = product_update.model_dump(exclude_unset=True)
            for key, value in update_data.items():
                setattr(product, key, value)

            product.updated_at = datetime.now(UTC)
            db.flush()
            db.refresh(product)

            logger.info(f"Updated product {product_id} in vendor {vendor_id} catalog")
            return product

        except ProductNotFoundException:
            raise
        except Exception as e:
            logger.error(f"Error updating product: {str(e)}")
            raise ValidationException("Failed to update product")

    def delete_product(self, db: Session, vendor_id: int, product_id: int) -> bool:
        """
        Remove product from vendor catalog.

        Args:
            db: Database session
            vendor_id: Vendor ID
            product_id: Product ID

        Returns:
            True if deleted
        """
        try:
            product = self.get_product(db, vendor_id, product_id)

            db.delete(product)

            logger.info(f"Deleted product {product_id} from vendor {vendor_id} catalog")
            return True

        except ProductNotFoundException:
            raise
        except Exception as e:
            logger.error(f"Error deleting product: {str(e)}")
            raise ValidationException("Failed to delete product")

    def get_vendor_products(
        self,
        db: Session,
        vendor_id: int,
        skip: int = 0,
        limit: int = 100,
        is_active: bool | None = None,
        is_featured: bool | None = None,
    ) -> tuple[list[Product], int]:
        """
        Get products in vendor catalog with filtering.

        Args:
            db: Database session
            vendor_id: Vendor ID
            skip: Pagination offset
            limit: Pagination limit
            is_active: Filter by active status
            is_featured: Filter by featured status

        Returns:
            Tuple of (products, total_count)
        """
        try:
            query = db.query(Product).filter(Product.vendor_id == vendor_id)

            if is_active is not None:
                query = query.filter(Product.is_active == is_active)

            if is_featured is not None:
                query = query.filter(Product.is_featured == is_featured)

            total = query.count()
            products = query.offset(skip).limit(limit).all()

            return products, total

        except Exception as e:
            logger.error(f"Error getting vendor products: {str(e)}")
            raise ValidationException("Failed to retrieve products")


# Create service instance
product_service = ProductService()
