from datetime import date,datetime,time,timezone
from uuid import UUID
from fastapi import APIRouter,Depends,HTTPException,Query
from sqlalchemy import select
from sqlalchemy.orm import Session
from app.api.workspace import get_verified_current_user
from app.core.permissions import Permission
from app.db.session import get_db
from app.models.audit import AuditLog
from app.models.membership import MembershipBranch
from app.models.user import User
from app.services.rbac import require_permission
router=APIRouter(tags=['Audit Log'])
def query(db,user,business,branch_id=None):
 m=require_permission(db,user,business,Permission.MANAGE_FINANCES);q=select(AuditLog).where(AuditLog.business_id==business)
 if branch_id:q=q.where(AuditLog.branch_id==branch_id)
 elif not m.all_branches:q=q.where(AuditLog.branch_id.in_(select(MembershipBranch.branch_id).where(MembershipBranch.membership_id==m.id)))
 return q
@router.get('/api/businesses/{business_id}/audit')
def listing(business_id:UUID,action:str|None=None,entity_type:str|None=None,entity_id:UUID|None=None,actor_user_id:UUID|None=None,branch_id:UUID|None=None,start_date:date|None=None,end_date:date|None=None,offset:int=Query(0,ge=0),limit:int=Query(50,ge=1,le=100),user:User=Depends(get_verified_current_user),db:Session=Depends(get_db)):
 q=query(db,user,business_id,branch_id)
 for col,val in [(AuditLog.action,action),(AuditLog.entity_type,entity_type),(AuditLog.entity_id,entity_id),(AuditLog.actor_user_id,actor_user_id)]:
  if val is not None:q=q.where(col==val)
 if start_date:q=q.where(AuditLog.created_at>=datetime.combine(start_date,time.min,tzinfo=timezone.utc))
 if end_date:q=q.where(AuditLog.created_at<=datetime.combine(end_date,time.max,tzinfo=timezone.utc))
 return list(db.scalars(q.order_by(AuditLog.created_at.desc()).offset(offset).limit(limit)))
@router.get('/api/businesses/{business_id}/audit/{audit_id}')
def detail(business_id:UUID,audit_id:UUID,user:User=Depends(get_verified_current_user),db:Session=Depends(get_db)):
 x=db.scalar(query(db,user,business_id).where(AuditLog.id==audit_id))
 if not x:raise HTTPException(404,'Audit log not found.')
 return x
