from datetime import datetime
from uuid import UUID
from fastapi import APIRouter,Depends,HTTPException,Header
from sqlalchemy import select
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import Session
from app.api.workspace import get_verified_current_user
from app.db.session import get_db
from app.models.sale import Sale,SaleItem,SalePayment
from app.models.user import User
from app.schemas.sale import SaleCreate
from app.services.sales import cancel_sale,create_sale,get_sale
from app.services.workspace import get_membership_for_business
router=APIRouter(tags=['Sales / POS'])
def access(db,u,b):
 if not get_membership_for_business(db,u,b):raise HTTPException(404,'Business workspace not found.')
def run(db,f):
 try:return f()
 except LookupError as e:raise HTTPException(404,str(e))
 except ValueError as e:db.rollback();raise HTTPException(422,str(e))
 except IntegrityError:db.rollback();raise HTTPException(409,'Duplicate receipt number or idempotency key.')
def view(db,s):return {'sale':s,'items':list(db.scalars(select(SaleItem).where(SaleItem.sale_id==s.id))),'payments':list(db.scalars(select(SalePayment).where(SalePayment.sale_id==s.id)))}
@router.post('/api/businesses/{business_id}/sales',status_code=201)
def create(business_id:UUID,data:SaleCreate,idempotency_key:str|None=Header(default=None,alias='Idempotency-Key'),user:User=Depends(get_verified_current_user),db:Session=Depends(get_db)):
 access(db,user,business_id);return run(db,lambda:view(db,create_sale(db,business_id,user.id,idempotency_key,data)[0]))
@router.get('/api/businesses/{business_id}/sales')
def listing(business_id:UUID,branch_id:UUID|None=None,customer_id:UUID|None=None,payment_status:str|None=None,lifecycle_status:str|None=None,user:User=Depends(get_verified_current_user),db:Session=Depends(get_db)):
 access(db,user,business_id);q=select(Sale).where(Sale.business_id==business_id)
 for col,val in ((Sale.branch_id,branch_id),(Sale.customer_id,customer_id),(Sale.payment_status,payment_status),(Sale.lifecycle_status,lifecycle_status)):
  if val is not None:q=q.where(col==val)
 return list(db.scalars(q.order_by(Sale.created_at.desc())))
@router.get('/api/businesses/{business_id}/sales/{sale_id}')
def get(business_id:UUID,sale_id:UUID,user:User=Depends(get_verified_current_user),db:Session=Depends(get_db)):
 access(db,user,business_id);return run(db,lambda:view(db,get_sale(db,business_id,sale_id)))
@router.get('/api/businesses/{business_id}/sales/{sale_id}/payments')
def payments(business_id:UUID,sale_id:UUID,user:User=Depends(get_verified_current_user),db:Session=Depends(get_db)):
 access(db,user,business_id);run(db,lambda:get_sale(db,business_id,sale_id));return list(db.scalars(select(SalePayment).where(SalePayment.sale_id==sale_id)))
@router.post('/api/businesses/{business_id}/sales/{sale_id}/cancel')
def cancel(business_id:UUID,sale_id:UUID,user:User=Depends(get_verified_current_user),db:Session=Depends(get_db)):
 access(db,user,business_id);return run(db,lambda:cancel_sale(db,business_id,sale_id))
