import datetime as dt

import pytest

from flyway.domain.errors import BusinessError, PermissionDenied
from flyway.services.master import (
    ClientData, delete_batches, delete_clients, delete_products, save_batch, save_client, save_product,
    save_supplier,
)
from tests import builders as b


def test_client_requires_name_and_trims(db):
    with pytest.raises(BusinessError) as e:
        save_client(db, b.STAFF, ClientData(name="  "))
    assert e.value.field == "name"
    c = save_client(db, b.STAFF, ClientData(name=" Acme ", email=" a@x "))
    assert (c.name, c.email) == ("Acme", "a@x")


def test_client_with_documents_cannot_be_deleted(db):
    c = b.client(db)
    b.transfer(db, c)
    with pytest.raises(PermissionDenied):
        delete_clients(db, b.STAFF, [c.id])
    with pytest.raises(BusinessError):
        delete_clients(db, b.ADMIN, [c.id])
    empty = save_client(db, b.STAFF, ClientData(name="Empty"))
    delete_clients(db, b.ADMIN, [empty.id])


def test_product_units_validated_and_used_product_kept(db):
    with pytest.raises(BusinessError):
        save_product(db, b.STAFF, "P", 6, "10")
    p = save_product(db, b.STAFF, "P", 6, "12,24")
    b.batch(db, p)
    with pytest.raises(BusinessError):
        delete_products(db, b.ADMIN, [p.id])


def test_batch_number_unique_per_product(db):
    p = b.product(db)
    save_batch(db, b.STAFF, p.id, "B1", dt.date(2026, 1, 1), None)
    with pytest.raises(BusinessError) as e:
        save_batch(db, b.STAFF, p.id, " b1", dt.date(2026, 1, 1), None)
    assert e.value.field == "number"


def test_batch_in_use_cannot_be_deleted(db):
    c, p = b.client(db), b.product(db)
    bt = b.batch(db, p)
    b.item(db, b.transfer(db, c), bt, 1)
    with pytest.raises(BusinessError):
        delete_batches(db, b.ADMIN, [bt.id])


def test_supplier_is_admin_only(db):
    with pytest.raises(PermissionDenied):
        save_supplier(db, b.STAFF, "Farm", "R1")
    assert save_supplier(db, b.ADMIN, "Farm", "R1").rmp_number == "R1"
