import time

from fastapi import APIRouter, Depends, HTTPException, Request, status
from common_logging import get_logger
from sqlalchemy.orm import Session

from app.api.deps import get_current_user
from app.api.permissions import require_platform_admin
from app.core.i18n import get_translator
from app.db.session import get_db_without_tenant
from app.db.tenant_schema import deprovision_tenant_schema, provision_tenant_schema
from app.models.tenant import Tenant
from app.models.user import User
from app.schemas.tenant import TenantCreate, TenantResponse, TenantUpdate
from common_logging import get_logger

logger = get_logger(__name__)

logger = get_logger(__name__)
router = APIRouter(tags=["tenants"])


@router.get("", response_model=list[TenantResponse])
def list_tenants(
    skip: int = 0,
    limit: int = 100,
    db: Session = Depends(get_db_without_tenant),
    current_user: User = Depends(require_platform_admin()),
):
    tenants = db.query(Tenant).offset(skip).limit(limit).all()
    return tenants


@router.get("/{tenant_id}", response_model=TenantResponse)
def get_tenant(
    tenant_id: int,
    request: Request,
    db: Session = Depends(get_db_without_tenant),
    current_user: User = Depends(get_current_user),
):
    t = get_translator(request)
    if current_user.role == "platform_admin":
        pass
    elif current_user.tenant_id != tenant_id:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Access denied")
    tenant = db.query(Tenant).filter(Tenant.id == tenant_id).first()
    if not tenant:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=t.t("company.not_found"))
    return tenant


@router.post("", response_model=TenantResponse, status_code=status.HTTP_201_CREATED)
def create_tenant(
    tenant: TenantCreate,
    request: Request,
    db: Session = Depends(get_db_without_tenant),
    current_user: User = Depends(require_platform_admin()),
):
    t = get_translator(request)
    logger.bind(tenant_name=tenant.name, user_id=current_user.id).info("Creating tenant")
    existing = db.query(Tenant).filter(Tenant.name == tenant.name).first()
    if existing:
        logger.bind(tenant_name=tenant.name).warning("Tenant name already exists")
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST, detail=t.t("company.name_exists")
        )
    tenant_data = tenant.model_dump()
    if not tenant_data.get("code"):
        timestamp = str(int(time.time() * 1000))[-6:]
        base_code = tenant.name[:10].upper().replace(" ", "_")
        tenant_data["code"] = f"{base_code}_{timestamp}"
    if tenant_data["code"]:
        existing_code = db.query(Tenant).filter(Tenant.code == tenant_data["code"]).first()
        if existing_code:
            logger.bind(tenant_code=tenant_data["code"]).warning("Tenant code already exists")
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST, detail=t.t("company.code_exists")
            )
    if not tenant_data.get("description"):
        tenant_data["description"] = ""
    db_tenant = Tenant(**tenant_data)
    db.add(db_tenant)
    db.commit()
    db.refresh(db_tenant)
    try:
        success = provision_tenant_schema(db, db_tenant.id)
        if not success:
            logger.bind(tenant_id=db_tenant.id).error("Failed to provision tenant schema")
            db.delete(db_tenant)
            db.commit()
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="Failed to provision tenant schema",
            )
        logger.bind(tenant_id=db_tenant.id).info("Tenant created with schema")
    except Exception as e:
        logger.bind(tenant_id=db_tenant.id).error(f"Error provisioning tenant schema: {e}")
        db.delete(db_tenant)
        db.commit()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to provision tenant: {str(e)}",
        ) from e
    return db_tenant


@router.put("/{tenant_id}", response_model=TenantResponse)
def update_tenant(
    tenant_id: int,
    tenant: TenantUpdate,
    request: Request,
    db: Session = Depends(get_db_without_tenant),
    current_user: User = Depends(require_platform_admin()),
):
    t = get_translator(request)
    logger.bind(tenant_id=tenant_id, user_id=current_user.id).info("Updating tenant")
    db_tenant = db.query(Tenant).filter(Tenant.id == tenant_id).first()
    if not db_tenant:
        logger.bind(tenant_id=tenant_id).warning("Tenant not found for update")
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=t.t("company.not_found"))
    if tenant.name and tenant.name != db_tenant.name:
        existing = db.query(Tenant).filter(Tenant.name == tenant.name).first()
        if existing:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST, detail=t.t("company.name_exists")
            )
    if tenant.code and tenant.code != db_tenant.code:
        existing_code = db.query(Tenant).filter(Tenant.code == tenant.code).first()
        if existing_code:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST, detail=t.t("company.code_exists")
            )
    update_data = tenant.model_dump(exclude_unset=True)
    for field, value in update_data.items():
        setattr(db_tenant, field, value)
    db.commit()
    db.refresh(db_tenant)
    logger.bind(tenant_id=tenant_id).info("Tenant updated")
    return db_tenant


@router.delete("/{tenant_id}")
def delete_tenant(
    tenant_id: int,
    request: Request,
    db: Session = Depends(get_db_without_tenant),
    current_user: User = Depends(require_platform_admin()),
):
    t = get_translator(request)
    logger.bind(tenant_id=tenant_id, user_id=current_user.id).info("Deleting tenant")
    db_tenant = db.query(Tenant).filter(Tenant.id == tenant_id).first()
    if not db_tenant:
        logger.bind(tenant_id=tenant_id).warning("Tenant not found for deletion")
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=t.t("company.not_found"))
    user_count = db.query(User).filter(User.tenant_id == tenant_id).count()
    if user_count > 0:
        logger.bind(tenant_id=tenant_id, user_count=user_count).warning("Cannot delete tenant with active users")
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=t.t("company.has_users", count=user_count),
        )
    try:
        success = deprovision_tenant_schema(db, tenant_id)
        if not success:
            logger.bind(tenant_id=tenant_id).warning("Failed to deprovision schema, continuing with deletion")
    except Exception as e:
        logger.bind(tenant_id=tenant_id).error(f"Error deprovisioning tenant schema: {e}")
    db.delete(db_tenant)
    db.commit()
    logger.bind(tenant_id=tenant_id).info("Tenant deleted")
    return {"success": True, "message": t.t("company.deleted")}
