"""Tests for notificationtypes.boardorder (row order on the shopfloor board).

Rows used to run in display-style order and then alphabetically, so what led
the screen was an accident of styling and the alphabet. Each type now carries a
position, low first, and a shared category row sits wherever its
earliest-ordered type puts it.

The sort itself is frontend (ShopfloorDashboard.vue); pinned here is the
contract it sorts on - the feed carries boardorder per card, the type API
round-trips and validates it, and the migration seeds the shipped order.
"""

from plugins.notifications.models import Notification, NotificationType


def _make_type(db, typename, boardorder=100, displaystyle='grid', boardcategory=None):
    t = NotificationType(typename=typename, typecolor='#17a2b8', isactive=True,
                         displaystyle=displaystyle, boardcategory=boardcategory,
                         boardorder=boardorder)
    db.session.add(t)
    db.session.commit()
    return t


def _make_note(db, ntype, text):
    n = Notification(notificationtypeid=ntype.notificationtypeid,
                     notification=text, businessunitid=None,
                     isactive=True, isshopfloor=True)
    db.session.add(n)
    db.session.commit()
    return n


def _current(client):
    resp = client.get('/api/notifications/shopfloor')
    assert resp.status_code == 200, resp.get_json()
    return resp.get_json()['data']['current']


def test_feed_carries_the_order_per_card(client, db):
    ntype = _make_type(db, 'Recognition', boardorder=10)
    _make_note(db, ntype, 'ten years')

    assert _current(client)[0]['boardorder'] == 10


def test_a_type_defaults_to_the_back(client, db):
    """A new type lands behind the seeded rows rather than jumping the queue."""
    ntype = NotificationType(typename='Fresh', typecolor='#17a2b8', isactive=True)
    db.session.add(ntype)
    db.session.commit()

    assert ntype.boardorder == 100


def test_api_round_trips_the_order(client, db, auth_headers):
    create = client.post('/api/notifications/types',
                         json={'typename': 'Awareness', 'boardorder': 30},
                         headers=auth_headers)
    assert create.status_code in (200, 201), create.get_json()
    typeid = create.get_json()['data']['notificationtypeid']
    assert create.get_json()['data']['boardorder'] == 30

    updated = client.put(f'/api/notifications/types/{typeid}',
                         json={'boardorder': 40}, headers=auth_headers)
    assert updated.get_json()['data']['boardorder'] == 40


def test_api_rejects_a_nonsense_order(client, db, auth_headers):
    resp = client.post('/api/notifications/types',
                       json={'typename': 'Bad', 'boardorder': 'first'},
                       headers=auth_headers)

    assert resp.status_code == 400
    assert 'boardorder' in resp.get_data(as_text=True)


def test_api_rejects_an_out_of_range_order(client, db, auth_headers):
    resp = client.post('/api/notifications/types',
                       json={'typename': 'Bad', 'boardorder': 1000},
                       headers=auth_headers)

    assert resp.status_code == 400


def test_order_change_moves_the_config_version(client, db, auth_headers):
    """Open kiosks reload on a layout change; a re-ordered board is one."""
    ntype = _make_type(db, 'Awareness')
    before = client.get('/api/notifications/shopfloor').get_json()['data']['configversion']

    client.put(f'/api/notifications/types/{ntype.notificationtypeid}',
               json={'boardorder': 30}, headers=auth_headers)

    after = client.get('/api/notifications/shopfloor').get_json()['data']['configversion']
    assert before != after


def test_types_in_one_category_can_carry_different_orders(client, db):
    """The row takes the lowest; the feed still reports each type's own."""
    change = _make_type(db, 'Change', boardorder=30, boardcategory='Current Events')
    incident = _make_type(db, 'Incident', boardorder=50, boardcategory='Current Events')
    _make_note(db, change, 'retooling')
    _make_note(db, incident, 'press down')

    orders = {c['typename']: c['boardorder'] for c in _current(client)}
    assert orders == {'Change': 30, 'Incident': 50}
