"""
Cashier role restriction guard - enforces POS-only access for cashier users
"""
from fastapi import HTTPException, status, Depends, Request
from sqlalchemy.orm import Session
from app.core.database import get_db
from app.core.security import get_current_user
from app.models.user import User

# Routes that cashier users are allowed to access
CASHIER_ALLOWED_ROUTES = {
    # POS
    "/api/v1/pos/",

    # Sales (read products, customers, invoices created by POS)
    "/api/v1/sales/",

    # Quotations (create and manage quotations from POS)
    "/api/v1/quotations/",

    # Inventory (read-only products, stock levels)
    "/api/v1/inventory/products/",

    # Customers (read-only)
    "/api/v1/users/customers",

    # Banking (read-only, deposit/withdrawal for POS)
    "/api/v1/banking/bank-accounts",
    "/api/v1/banking/accounts",
    "/api/v1/banking/transactions",

    # Branches (read branch details for current branch context)
    "/api/v1/branches/",

    # Receipts
    "/api/v1/receipts/",

    # Auth (refresh, logout)
    "/api/v1/auth/refresh",
    "/api/v1/auth/logout",
    "/api/v1/auth/switch-branch",

    # Settings (read POS configuration only)
    "/api/v1/settings/",
    "/api/v1/app-settings/",
    "/api/v1/app-setting/",
}

# Routes explicitly forbidden for cashier users
CASHIER_FORBIDDEN_ROUTES = {
    # Accounting & Finance
    "/api/v1/accounting/",
    "/api/v1/accounting-codes/",
    "/api/v1/general-ledger/",
    "/api/v1/journal-entries/",
    "/api/v1/vat/",

    # Users & Permissions
    "/api/v1/users/",
    "/api/v1/roles/",

    # Purchases
    "/api/v1/purchases/",
    "/api/v1/procurement/",

    # Asset Management
    "/api/v1/asset-management/",

    # Admin
    "/api/v1/backup/",
    "/api/v1/invoice-designer/",
    "/api/v1/admin/",
    "/api/v1/workflows/",

    # Manufacturing
    "/api/v1/manufacturing/",
}


def check_cashier_route_access(request: Request, current_user = Depends(get_current_user)):
    """
    Dependency to check if cashier user is accessing allowed routes.
    Should be used as a dependency in endpoints that need to restrict cashiers.
    """
    if not current_user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Not authenticated"
        )

    role = (getattr(current_user, 'role', '') or '').lower()
    path = request.url.path

    # Admins and other roles bypass this check
    if role not in ('cashier', 'pos_user'):
        return current_user

    # Check if route is explicitly forbidden
    for forbidden in CASHIER_FORBIDDEN_ROUTES:
        if path.startswith(forbidden):
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="Cashier users cannot access this feature. Only POS, Sales, and Inventory read access are allowed."
            )

    # For POS users, allow specific routes
    is_allowed = False
    for allowed in CASHIER_ALLOWED_ROUTES:
        if path.startswith(allowed):
            is_allowed = True
            break

    if not is_allowed:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Cashier users are restricted to POS and related functions. This endpoint is not available."
        )

    return current_user


def get_cashier_user(
    request: Request,
    db: Session = Depends(get_db),
    current_user = Depends(check_cashier_route_access)
):
    """
    Enhanced dependency that enforces cashier restrictions AND fetches the full user model.
    Use this in endpoints that need cashier-safe user data.
    """
    if not current_user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Not authenticated"
        )

    # If it's a dummy dev user, return as-is
    if hasattr(current_user, 'username') and 'dev' in current_user.username.lower():
        return current_user

    # Fetch full user from DB
    user_id = getattr(current_user, 'id', None)
    if user_id:
        user = db.query(User).filter(User.id == user_id).first()
        if user:
            return user

    return current_user
