from datetime import datetime, timezone
import uuid
import pytest
from fastapi.testclient import TestClient
from sqlalchemy import delete, select
from app.main import app
from app.db.session import SessionLocal
from app.core.security import create_access_token, hash_password
from app.models.user import User
from app.models.business import Business
from app.models.membership import Membership
from app.models.notification import Notification

@pytest.fixture
def client():
 with TestClient(app) as c: yield c
@pytest.fixture
def actor():
 db=SessionLocal();u=User(email=f'n-{uuid.uuid4()}@x.com',password_hash=hash_password('TestPassword123!'),is_email_verified=True);db.add(u);db.commit();db.refresh(u)
 try: yield u
 finally: db.execute(delete(User).where(User.id==u.id));db.commit();db.close()
def hdr(u):return {'Authorization':f'Bearer {create_access_token(str(u.id))}'}
def workspace(client,u):
 r=client.post('/api/businesses/onboarding',json={'name':'Notify Store','phone':'','email':'','address':'','city':'','state':'','country':'Nigeria','currency':'NGN','default_language':'en','main_branch_name':'Main'},headers=hdr(u));return r.json()
def test_notification_read_filters_and_isolation(client,actor):
 data=workspace(client,actor);bid=data['business']['id'];db=SessionLocal();n=Notification(business_id=uuid.UUID(bid),category='GENERAL',title='Real notice',message='x');db.add(n);db.commit();db.refresh(n)
 try:
  base=f'/api/businesses/{bid}/notifications';assert client.get(base,headers=hdr(actor)).status_code==200
  assert client.get(base+'/unread-count',headers=hdr(actor)).json()['count']==1
  assert client.get(base+'/'+str(n.id),headers=hdr(actor)).status_code==200
  assert client.patch(base+'/'+str(n.id)+'/read',headers=hdr(actor)).status_code==200
  assert client.patch(base+'/'+str(n.id)+'/read',headers=hdr(actor)).status_code==200
  assert client.get(base+'?is_read=true&category=GENERAL',headers=hdr(actor)).status_code==200
  assert client.patch(base+'/read-all',headers=hdr(actor)).status_code==200
 finally: db.close()
