#!/usr/bin/env python3
"""
Quick script to generate deletion service boilerplate
Usage: python generate_deletion_service.py <service_name> <model1,model2,model3>
Example: python generate_deletion_service.py pos POSConfiguration,POSTransaction,POSSession
"""

import sys
import os
from pathlib import Path


def generate_deletion_service(service_name: str, models: list[str]):
    """Generate deletion service file from template"""

    service_class = f"{service_name.title().replace('_', '')}TenantDeletionService"
    model_imports = ", ".join(models)

    # Build preview section
    preview_code = []
    delete_code = []

    for i, model in enumerate(models):
        model_lower = model.lower().replace('_', ' ')
        model_plural = f"{model_lower}s" if not model_lower.endswith('s') else model_lower

        preview_code.append(f"""
            # Count {model_plural}
            try:
                {model.lower()}_count = await self.db.scalar(
                    select(func.count({model}.id)).where({model}.tenant_id == tenant_id)
                )
                preview["{model_plural}"] = {model.lower()}_count or 0
            except Exception:
                preview["{model_plural}"] = 0  # Table might not exist
""")

        delete_code.append(f"""
            # Delete {model_plural}
            try:
                {model.lower()}_delete = await self.db.execute(
                    delete({model}).where({model}.tenant_id == tenant_id)
                )
                result.add_deleted_items("{model_plural}", {model.lower()}_delete.rowcount)

                logger.info("Deleted {model_plural} for tenant",
                           tenant_id=tenant_id,
                           count={model.lower()}_delete.rowcount)

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

    template = f'''"""
{service_name.title()} Service - Tenant Data Deletion
Handles deletion of all {service_name}-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 {service_class}(BaseTenantDataDeletionService):
    """Service for deleting all {service_name}-related data for a tenant"""

    def __init__(self, db_session: AsyncSession):
        super().__init__("{service_name}-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 import {model_imports}
{"".join(preview_code)}
            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 import {model_imports}
{"".join(delete_code)}
            # 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
'''

    return template


def generate_api_endpoints(service_name: str):
    """Generate API endpoint code"""

    service_class = f"{service_name.title().replace('_', '')}TenantDeletionService"

    template = f'''
# ===== Tenant Data Deletion Endpoints =====

@router.delete("/tenant/{{tenant_id}}")
async def delete_tenant_data(
    tenant_id: str,
    current_user: dict = Depends(get_current_user_dep),
    db: AsyncSession = Depends(get_db)
):
    """
    Delete all {service_name}-related data for a tenant
    Only accessible by internal services (called during tenant deletion)
    """

    logger.info(f"Tenant data deletion request received for tenant: {{tenant_id}}")

    # Only allow internal service calls
    if current_user.get("type") != "service":
        raise HTTPException(
            status_code=403,
            detail="This endpoint is only accessible to internal services"
        )

    try:
        from app.services.tenant_deletion_service import {service_class}

        deletion_service = {service_class}(db)
        result = await deletion_service.safe_delete_tenant_data(tenant_id)

        return {{
            "message": "Tenant data deletion completed in {service_name}-service",
            "summary": result.to_dict()
        }}

    except Exception as e:
        logger.error(f"Tenant data deletion failed for {{tenant_id}}: {{e}}")
        raise HTTPException(
            status_code=500,
            detail=f"Failed to delete tenant data: {{str(e)}}"
        )


@router.get("/tenant/{{tenant_id}}/deletion-preview")
async def preview_tenant_data_deletion(
    tenant_id: str,
    current_user: dict = Depends(get_current_user_dep),
    db: AsyncSession = Depends(get_db)
):
    """
    Preview what data would be deleted for a tenant (dry-run)
    Accessible by internal services and tenant admins
    """

    # Allow internal services and admins
    is_service = current_user.get("type") == "service"
    is_admin = current_user.get("role") in ["owner", "admin"]

    if not (is_service or is_admin):
        raise HTTPException(
            status_code=403,
            detail="Insufficient permissions"
        )

    try:
        from app.services.tenant_deletion_service import {service_class}

        deletion_service = {service_class}(db)
        preview = await deletion_service.get_tenant_data_preview(tenant_id)

        return {{
            "tenant_id": tenant_id,
            "service": "{service_name}-service",
            "data_counts": preview,
            "total_items": sum(preview.values())
        }}

    except Exception as e:
        logger.error(f"Deletion preview failed for {{tenant_id}}: {{e}}")
        raise HTTPException(
            status_code=500,
            detail=f"Failed to get deletion preview: {{str(e)}}"
        )
'''

    return template


def main():
    if len(sys.argv) < 3:
        print("Usage: python generate_deletion_service.py <service_name> <model1,model2,model3>")
        print("Example: python generate_deletion_service.py pos POSConfiguration,POSTransaction,POSSession")
        sys.exit(1)

    service_name = sys.argv[1]
    models = [m.strip() for m in sys.argv[2].split(',')]

    # Generate service file
    service_code = generate_deletion_service(service_name, models)

    # Generate API endpoints
    api_code = generate_api_endpoints(service_name)

    # Output files
    service_dir = Path(f"services/{service_name}/app/services")

    print(f"\n{'='*80}")
    print(f"Generated code for {service_name} service with models: {', '.join(models)}")
    print(f"{'='*80}\n")

    print("1. DELETION SERVICE FILE:")
    print(f"   Location: {service_dir}/tenant_deletion_service.py")
    print("-" * 80)
    print(service_code)
    print()

    print("\n2. API ENDPOINTS TO ADD:")
    print(f"   Add to: services/{service_name}/app/api/<router>.py")
    print("-" * 80)
    print(api_code)
    print()

    # Optionally write files
    write = input("\nWrite files to disk? (y/n): ").lower().strip()
    if write == 'y':
        # Create service file
        service_dir.mkdir(parents=True, exist_ok=True)
        service_file = service_dir / "tenant_deletion_service.py"

        with open(service_file, 'w') as f:
            f.write(service_code)

        print(f"\n✅ Created: {service_file}")
        print(f"\n⚠️  Next steps:")
        print(f"   1. Review and customize {service_file}")
        print(f"   2. Add the API endpoints to services/{service_name}/app/api/<router>.py")
        print(f"   3. Test with: curl -X GET 'http://localhost:8000/api/v1/{service_name}/tenant/{{id}}/deletion-preview'")
    else:
        print("\n✅ Files not written. Copy the code above manually.")


if __name__ == "__main__":
    main()
