"""Tests for the model-supplies (toner part-number) management API."""

import pytest


@pytest.fixture
def model(db):
    """A vendor + printer model to attach supplies to."""
    from shopdb.core.models import Vendor, Model

    vendor = Vendor(vendor='TestVendor')
    db.session.add(vendor)
    db.session.flush()

    model = Model(modelnumber='TestModel C999', vendorid=vendor.vendorid)
    db.session.add(model)
    db.session.commit()
    return model


def test_supplies_meta_lists_allowed_values(client, db):
    response = client.get('/api/printers/supplies/meta')
    assert response.status_code == 200
    data = response.get_json()['data']
    assert 'toner' in data['supplytypes']
    assert 'black' in data['colors']
    assert 'metered' in data['capacitytiers']


def test_create_and_list_model_supply(client, model, auth_headers):
    create = client.post(
        f'/api/printers/models/{model.modelnumberid}/supplies',
        json={
            'supplytype': 'toner', 'color': 'black', 'capacitytier': 'standard',
            'partnumber': 'W2020A', 'marketingname': '414A Black', 'pageyield': 2400,
        },
        headers=auth_headers,
    )
    assert create.status_code == 201

    listing = client.get(f'/api/printers/models/{model.modelnumberid}/supplies')
    assert listing.status_code == 200
    supplies = listing.get_json()['data']['supplies']
    assert len(supplies) == 1
    assert supplies[0]['partnumber'] == 'W2020A'


def test_duplicate_partnumber_rejected(client, model, auth_headers):
    payload = {'partnumber': 'W2020A', 'color': 'black'}
    client.post(f'/api/printers/models/{model.modelnumberid}/supplies',
                json=payload, headers=auth_headers)
    second = client.post(f'/api/printers/models/{model.modelnumberid}/supplies',
                         json=payload, headers=auth_headers)
    assert second.status_code == 409


def test_invalid_enum_rejected(client, model, auth_headers):
    response = client.post(
        f'/api/printers/models/{model.modelnumberid}/supplies',
        json={'partnumber': 'X1', 'color': 'purple'},
        headers=auth_headers,
    )
    assert response.status_code == 400


def test_create_requires_auth(client, model):
    response = client.post(
        f'/api/printers/models/{model.modelnumberid}/supplies',
        json={'partnumber': 'X1'},
    )
    assert response.status_code == 401


def test_update_and_delete_supply(client, model, auth_headers):
    created = client.post(
        f'/api/printers/models/{model.modelnumberid}/supplies',
        json={'partnumber': 'W2020A', 'color': 'black', 'capacitytier': 'standard'},
        headers=auth_headers,
    ).get_json()['data']
    supplyid = created['modelsupplyid']

    updated = client.put(
        f'/api/printers/supplies/{supplyid}',
        json={'capacitytier': 'high', 'marketingname': '414X Black'},
        headers=auth_headers,
    )
    assert updated.status_code == 200
    assert updated.get_json()['data']['capacitytier'] == 'high'

    deleted = client.delete(f'/api/printers/supplies/{supplyid}', headers=auth_headers)
    assert deleted.status_code == 200

    listing = client.get(f'/api/printers/models/{model.modelnumberid}/supplies')
    assert listing.get_json()['data']['supplies'] == []


def test_listmodels_reports_supplycount(client, model, auth_headers):
    client.post(f'/api/printers/models/{model.modelnumberid}/supplies',
                json={'partnumber': 'W2020A', 'color': 'black'}, headers=auth_headers)

    response = client.get('/api/printers/models', query_string={'search': 'C999'})
    assert response.status_code == 200
    rows = response.get_json()['data']
    match = next(r for r in rows if r['modelnumberid'] == model.modelnumberid)
    assert match['supplycount'] == 1


def test_seed_supplies_corrected_data(app, db):
    """The seed loads corrected part numbers (C405 colors, no B405 waste)."""
    with app.app_context():
        from plugins.printers.services import seedsupplies, lookupsupplies
        from shopdb.core.models import Model

        seedsupplies()

        c405 = Model.query.filter(Model.modelnumber.ilike('%C405%')).first()
        yellow = lookupsupplies(c405.modelnumberid, 'yellow', 'toner')
        assert any(s['partnumber'] == '106R03501' for s in yellow)

        b405 = Model.query.filter(Model.modelnumber.ilike('%B405%')).first()
        assert lookupsupplies(b405.modelnumberid, 'none', 'waste') == []
