import datetime as dt
import uuid

import pytest
from sqlalchemy import inspect
from sqlalchemy.exc import IntegrityError

from flyway.models import Client, Product, ProductBatch, Transfer

NOW = dt.datetime(2026, 1, 5, 3, 0, tzinfo=dt.UTC)


def _client(db):
    c = Client(name="C1", email="", mobile_phone="")
    db.add(c)
    db.flush()
    return c


def _transfer(db, client, code, **kw):
    t = Transfer(id=uuid.uuid4(), client=client, code=code, date=NOW, **kw)
    db.add(t)
    return t


def test_legacy_and_app_tables_exist(engine):
    names = set(inspect(engine).get_table_names())
    for t in ["fw_Client", "fw_ClientTransfer", "fw_ClientTransferItem", "fw_ProductBatch",
              "fw_ShippingParcels", "app_user", "app_session", "audit_log", "migration_legacy_value"]:
        assert t in names


def test_transfer_code_unique_ignores_case_and_spaces(db):
    c = _client(db)
    _transfer(db, c, "LI-1")
    db.flush()
    _transfer(db, c, " li-1 ")
    with pytest.raises(IntegrityError):
        db.flush()


def test_transfer_in_shares_code_with_transfer_out(db):
    c = _client(db)
    out = _transfer(db, c, "TR-1", is_load_out=True, is_local=True)
    _transfer(db, c, "TR-1", is_local=True, transfer_from=out)
    db.flush()


def test_batch_number_unique_per_product(db):
    p1, p2 = Product(title="P1"), Product(title="P2")
    db.add_all([p1, p2])
    db.flush()
    db.add_all([
        ProductBatch(product=p1, number="B1", date=dt.date(2026, 1, 1)),
        ProductBatch(product=p2, number="B1", date=dt.date(2026, 1, 1)),
    ])
    db.flush()
    db.add(ProductBatch(product=p1, number="b1 ", date=dt.date(2026, 1, 1)))
    with pytest.raises(IntegrityError):
        db.flush()
