import uuid

import pytest
from sqlalchemy import select

from app.core.security import hash_password
from app.db.session import SessionLocal
from app.models.branch import Branch
from app.models.membership import Membership, MembershipBranch
from app.models.user import User
from test_products_inventory import another_business, headers, product, workspace

pytest_plugins = ("test_workspace",)


def adjust(client,user,business,branch,product_id,quantity,reason):
    return client.post(f"/api/businesses/{business}/branches/{branch}/stock-adjustments",json={"product_id":product_id,"quantity_changed":quantity,"reason":reason},headers=headers(user))


def test_business_product_history_filters_order_pagination_and_detail_compatibility(client,verified_user):
    data=workspace(client,verified_user,"History");business,branch=data["business"]["id"],data["accessible_branches"][0]["id"]
    first=product(client,verified_user,business,"Alpha",sku="A",barcode="111").json();second=product(client,verified_user,business,"Beta",sku="B").json()
    assert adjust(client,verified_user,business,branch,first["id"],"10","RESTOCK").status_code==201
    assert adjust(client,verified_user,business,branch,second["id"],"5","RETURN").status_code==201
    assert adjust(client,verified_user,business,branch,first["id"],"-2","DAMAGE").status_code==201
    url=f"/api/businesses/{business}/products/history"
    rows=client.get(url,headers=headers(verified_user));assert rows.status_code==200 and len(rows.json())==3
    assert rows.json()[0]["quantity_changed"]==-2 and rows.json()[0]["product_name"]=="Alpha"
    assert client.get(url,params={"product_id":first["id"],"reason":"DAMAGE","search":"111"},headers=headers(verified_user)).json()[0]["quantity_changed"]==-2
    assert len(client.get(url,params={"branch_id":branch,"limit":1,"offset":1},headers=headers(verified_user)).json())==1
    assert client.get(f"/api/businesses/{business}/products/{first['id']}/stock-history",headers=headers(verified_user)).status_code==200


def test_product_history_business_branch_and_permission_isolation(client,verified_user):
    data=workspace(client,verified_user,"History isolation");business,main=data["business"]["id"],data["accessible_branches"][0]["id"]
    db=SessionLocal();other_branch=Branch(business_id=uuid.UUID(business),name="Other",is_active=True);db.add(other_branch);db.commit();db.refresh(other_branch)
    try:
        first=product(client,verified_user,business,"Private").json();assert adjust(client,verified_user,business,main,first["id"],"2","RESTOCK").status_code==201;assert adjust(client,verified_user,business,str(other_branch.id),first["id"],"3","RESTOCK").status_code==201
        other=another_business(client,verified_user,"Other history")["business"]["id"]
        assert client.get(f"/api/businesses/{other}/products/history",headers=headers(verified_user)).json()==[]
        limited=User(full_name="Storekeeper",email=f"history-{uuid.uuid4().hex}@x.test",password_hash=hash_password("Password123!"),is_email_verified=True);cashier=User(full_name="Cashier",email=f"history-cash-{uuid.uuid4().hex}@x.test",password_hash=hash_password("Password123!"),is_email_verified=True)
        db.add_all([limited,cashier]);db.flush();member=Membership(business_id=uuid.UUID(business),user_id=limited.id,role="STOREKEEPER",all_branches=False);db.add_all([member,Membership(business_id=uuid.UUID(business),user_id=cashier.id,role="CASHIER",all_branches=True)]);db.flush();db.add(MembershipBranch(membership_id=member.id,branch_id=uuid.UUID(main)));db.commit()
        rows=client.get(f"/api/businesses/{business}/products/history",headers=headers(limited));assert rows.status_code==200 and len(rows.json())==1 and rows.json()[0]["branch_id"]==main
        assert client.get(f"/api/businesses/{business}/products/history",headers=headers(cashier)).status_code==403
    finally:
        db.query(MembershipBranch).filter(MembershipBranch.membership_id.in_(select(Membership.id).where(Membership.business_id==uuid.UUID(business)))).delete(synchronize_session=False);db.query(Membership).filter(Membership.business_id==uuid.UUID(business),Membership.user_id!=verified_user.id).delete(synchronize_session=False);db.query(User).filter(User.email.like("history-%")).delete(synchronize_session=False);db.commit();db.close()
