"""
Orders Service - Tenant Data Deletion
Handles deletion of all order-related data for a tenant
"""
from typing import Dict
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, delete, func
import structlog

from shared.services.tenant_deletion import BaseTenantDataDeletionService, TenantDataDeletionResult
from app.models.order import CustomerOrder, OrderItem, OrderStatusHistory
from app.models.customer import Customer, CustomerContact

logger = structlog.get_logger()


class OrdersTenantDeletionService(BaseTenantDataDeletionService):
    """Service for deleting all orders-related data for a tenant"""

    def __init__(self, db_session: AsyncSession):
        super().__init__("orders-service")
        self.db = db_session

    async def get_tenant_data_preview(self, tenant_id: str) -> Dict[str, int]:
        """Get counts of what would be deleted"""

        try:
            preview = {}

            # Count orders
            order_count = await self.db.scalar(
                select(func.count(CustomerOrder.id)).where(CustomerOrder.tenant_id == tenant_id)
            )
            preview["orders"] = order_count or 0

            # Count order items (will be deleted via CASCADE)
            order_item_count = await self.db.scalar(
                select(func.count(OrderItem.id))
                .join(CustomerOrder)
                .where(CustomerOrder.tenant_id == tenant_id)
            )
            preview["order_items"] = order_item_count or 0

            # Count order status history (will be deleted via CASCADE)
            status_history_count = await self.db.scalar(
                select(func.count(OrderStatusHistory.id))
                .join(CustomerOrder)
                .where(CustomerOrder.tenant_id == tenant_id)
            )
            preview["order_status_history"] = status_history_count or 0

            # Count customers
            customer_count = await self.db.scalar(
                select(func.count(Customer.id)).where(Customer.tenant_id == tenant_id)
            )
            preview["customers"] = customer_count or 0

            # Count customer contacts (will be deleted via CASCADE)
            contact_count = await self.db.scalar(
                select(func.count(CustomerContact.id))
                .join(Customer)
                .where(Customer.tenant_id == tenant_id)
            )
            preview["customer_contacts"] = contact_count or 0

            return preview

        except Exception as e:
            logger.error("Error getting deletion preview",
                        tenant_id=tenant_id,
                        error=str(e))
            return {}

    async def delete_tenant_data(self, tenant_id: str) -> TenantDataDeletionResult:
        """Delete all data for a tenant"""

        result = TenantDataDeletionResult(tenant_id, self.service_name)

        try:
            # Get preview before deletion for reporting
            preview = await self.get_tenant_data_preview(tenant_id)

            # Delete customers (CASCADE will delete customer_contacts)
            try:
                customer_delete = await self.db.execute(
                    delete(Customer).where(Customer.tenant_id == tenant_id)
                )
                deleted_customers = customer_delete.rowcount
                result.add_deleted_items("customers", deleted_customers)

                # Customer contacts are deleted via CASCADE
                result.add_deleted_items("customer_contacts", preview.get("customer_contacts", 0))

                logger.info("Deleted customers for tenant",
                           tenant_id=tenant_id,
                           count=deleted_customers)

            except Exception as e:
                logger.error("Error deleting customers",
                           tenant_id=tenant_id,
                           error=str(e))
                result.add_error(f"Customer deletion: {str(e)}")

            # Delete orders (CASCADE will delete order_items and order_status_history)
            try:
                order_delete = await self.db.execute(
                    delete(CustomerOrder).where(CustomerOrder.tenant_id == tenant_id)
                )
                deleted_orders = order_delete.rowcount
                result.add_deleted_items("orders", deleted_orders)

                # Order items and status history are deleted via CASCADE
                result.add_deleted_items("order_items", preview.get("order_items", 0))
                result.add_deleted_items("order_status_history", preview.get("order_status_history", 0))

                logger.info("Deleted orders for tenant",
                           tenant_id=tenant_id,
                           count=deleted_orders)

            except Exception as e:
                logger.error("Error deleting orders",
                           tenant_id=tenant_id,
                           error=str(e))
                result.add_error(f"Order deletion: {str(e)}")

            # Commit all deletions
            await self.db.commit()

            logger.info("Tenant data deletion completed",
                       tenant_id=tenant_id,
                       deleted_counts=result.deleted_counts)

        except Exception as e:
            logger.error("Fatal error during tenant data deletion",
                        tenant_id=tenant_id,
                        error=str(e))
            await self.db.rollback()
            result.add_error(f"Fatal error: {str(e)}")

        return result
