"""
Suppliers Service - Tenant Data Deletion
Handles deletion of all supplier-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

logger = structlog.get_logger()


class SuppliersTenantDeletionService(BaseTenantDataDeletionService):
    """Service for deleting all supplier-related data for a tenant"""

    def __init__(self, db_session: AsyncSession):
        super().__init__("suppliers-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 = {}

            # Import models here to avoid circular imports
            from app.models.suppliers import (
                Supplier,
                SupplierProduct,
                PurchaseOrder,
                PurchaseOrderItem,
                SupplierPerformance
            )

            # Count suppliers
            supplier_count = await self.db.scalar(
                select(func.count(Supplier.id)).where(Supplier.tenant_id == tenant_id)
            )
            preview["suppliers"] = supplier_count or 0

            # Count supplier products
            product_count = await self.db.scalar(
                select(func.count(SupplierProduct.id)).where(SupplierProduct.tenant_id == tenant_id)
            )
            preview["supplier_products"] = product_count or 0

            # Count purchase orders
            po_count = await self.db.scalar(
                select(func.count(PurchaseOrder.id)).where(PurchaseOrder.tenant_id == tenant_id)
            )
            preview["purchase_orders"] = po_count or 0

            # Count purchase order items (CASCADE will delete these)
            poi_count = await self.db.scalar(
                select(func.count(PurchaseOrderItem.id))
                .join(PurchaseOrder)
                .where(PurchaseOrder.tenant_id == tenant_id)
            )
            preview["purchase_order_items"] = poi_count or 0

            # Count supplier performance records
            try:
                perf_count = await self.db.scalar(
                    select(func.count(SupplierPerformance.id)).where(SupplierPerformance.tenant_id == tenant_id)
                )
                preview["supplier_performance"] = perf_count or 0
            except Exception:
                # Table might not exist in all versions
                preview["supplier_performance"] = 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:
            # Import models here to avoid circular imports
            from app.models.suppliers import (
                Supplier,
                SupplierProduct,
                PurchaseOrder,
                PurchaseOrderItem,
                SupplierPerformance
            )

            # Get preview for CASCADE items
            preview = await self.get_tenant_data_preview(tenant_id)

            # Delete purchase order items first (foreign key to purchase orders)
            try:
                poi_delete = await self.db.execute(
                    delete(PurchaseOrderItem)
                    .where(PurchaseOrderItem.purchase_order_id.in_(
                        select(PurchaseOrder.id).where(PurchaseOrder.tenant_id == tenant_id)
                    ))
                )
                result.add_deleted_items("purchase_order_items", poi_delete.rowcount)
            except Exception as e:
                logger.error("Error deleting purchase order items",
                           tenant_id=tenant_id,
                           error=str(e))
                result.add_error(f"Purchase order item deletion: {str(e)}")

            # Delete purchase orders
            try:
                po_delete = await self.db.execute(
                    delete(PurchaseOrder).where(PurchaseOrder.tenant_id == tenant_id)
                )
                result.add_deleted_items("purchase_orders", po_delete.rowcount)

                logger.info("Deleted purchase orders for tenant",
                           tenant_id=tenant_id,
                           count=po_delete.rowcount)

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

            # Delete supplier performance records
            try:
                perf_delete = await self.db.execute(
                    delete(SupplierPerformance).where(SupplierPerformance.tenant_id == tenant_id)
                )
                result.add_deleted_items("supplier_performance", perf_delete.rowcount)
            except Exception as e:
                logger.warning("Error deleting supplier performance (table might not exist)",
                             tenant_id=tenant_id,
                             error=str(e))
                result.add_error(f"Supplier performance deletion: {str(e)}")

            # Delete supplier products
            try:
                product_delete = await self.db.execute(
                    delete(SupplierProduct).where(SupplierProduct.tenant_id == tenant_id)
                )
                result.add_deleted_items("supplier_products", product_delete.rowcount)

                logger.info("Deleted supplier products for tenant",
                           tenant_id=tenant_id,
                           count=product_delete.rowcount)

            except Exception as e:
                logger.error("Error deleting supplier products",
                           tenant_id=tenant_id,
                           error=str(e))
                result.add_error(f"Supplier product deletion: {str(e)}")

            # Delete suppliers (parent table)
            try:
                supplier_delete = await self.db.execute(
                    delete(Supplier).where(Supplier.tenant_id == tenant_id)
                )
                result.add_deleted_items("suppliers", supplier_delete.rowcount)

                logger.info("Deleted suppliers for tenant",
                           tenant_id=tenant_id,
                           count=supplier_delete.rowcount)

            except Exception as e:
                logger.error("Error deleting suppliers",
                           tenant_id=tenant_id,
                           error=str(e))
                result.add_error(f"Supplier 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
