"""Relationship-type directionality: CRUD carries isdirectional and the
per-asset relationships endpoint tags each row with its type directionality.

The frontend uses isdirectional to collapse symmetric-type rows (Dualpath and
other physical links) into one direction-blind card entry, and to render
directional types (controls, partof...) with source->target phrasing. That
dedupe is view logic verified live; here we lock the backend surface it needs.
"""

from shopdb.extensions import db
from shopdb.core.models import Asset, AssetType
from shopdb.core.models.relationship import RelationshipType, AssetRelationship


def _make_asset(assetnumber, typeid):
    asset = Asset(assetnumber=assetnumber, assettypeid=typeid)
    db.session.add(asset)
    db.session.flush()
    return asset


# ---------------------------------------------------------------------------
# Relationship type CRUD carries isdirectional
# ---------------------------------------------------------------------------

def test_create_type_defaults_directional(client, db, auth_headers):
    resp = client.post('/api/assets/relationshiptypes',
                       json={'relationshiptype': 'Backup For'},
                       headers=auth_headers)
    assert resp.status_code == 201, resp.get_json()
    assert resp.get_json()['data']['isdirectional'] is True


def test_create_symmetric_type(client, db, auth_headers):
    resp = client.post('/api/assets/relationshiptypes',
                       json={'relationshiptype': 'Dualpath',
                             'isdirectional': False},
                       headers=auth_headers)
    assert resp.status_code == 201, resp.get_json()
    assert resp.get_json()['data']['isdirectional'] is False


def test_update_toggles_directional(client, db, auth_headers):
    typeid = client.post('/api/assets/relationshiptypes',
                         json={'relationshiptype': 'USB'},
                         headers=auth_headers).get_json()['data']['relationshiptypeid']
    resp = client.put(f'/api/assets/relationshiptypes/{typeid}',
                      json={'isdirectional': False}, headers=auth_headers)
    assert resp.status_code == 200
    assert resp.get_json()['data']['isdirectional'] is False


def test_list_includes_directional(client, db, auth_headers):
    client.post('/api/assets/relationshiptypes',
                json={'relationshiptype': 'WiFi', 'isdirectional': False},
                headers=auth_headers)
    resp = client.get('/api/assets/relationshiptypes')
    assert resp.status_code == 200
    row = next(t for t in resp.get_json()['data']
               if t['relationshiptype'] == 'WiFi')
    assert row['isdirectional'] is False


# ---------------------------------------------------------------------------
# Per-asset relationships endpoint tags each row with isdirectional
# ---------------------------------------------------------------------------

def test_relationships_row_carries_isdirectional(client, db, auth_headers):
    atype = AssetType(assettype='machine')
    db.session.add(atype)
    db.session.flush()

    symmetric = RelationshipType(relationshiptype='Dualpath', isdirectional=False)
    directional = RelationshipType(relationshiptype='controls', isdirectional=True)
    db.session.add_all([symmetric, directional])
    db.session.flush()

    a = _make_asset('M-A', atype.assettypeid)
    b = _make_asset('M-B', atype.assettypeid)

    # symmetric link stored in both directions (legacy shape)
    db.session.add(AssetRelationship(sourceassetid=a.assetid, targetassetid=b.assetid,
                                     relationshiptypeid=symmetric.relationshiptypeid))
    db.session.add(AssetRelationship(sourceassetid=b.assetid, targetassetid=a.assetid,
                                     relationshiptypeid=symmetric.relationshiptypeid))
    # directional link a controls b
    db.session.add(AssetRelationship(sourceassetid=a.assetid, targetassetid=b.assetid,
                                     relationshiptypeid=directional.relationshiptypeid))
    db.session.commit()

    resp = client.get(f'/api/assets/{a.assetid}/relationships')
    assert resp.status_code == 200
    data = resp.get_json()['data']

    for row in data['outgoing']:
        assert 'isdirectional' in row
    for row in data['incoming']:
        assert 'isdirectional' in row

    # symmetric type reports False both directions; directional reports True
    sym_rows = [r for r in data['outgoing'] + data['incoming']
                if r['relationshiptypename'] == 'Dualpath']
    assert sym_rows and all(r['isdirectional'] is False for r in sym_rows)
    ctrl_rows = [r for r in data['outgoing']
                 if r['relationshiptypename'] == 'controls']
    assert ctrl_rows and all(r['isdirectional'] is True for r in ctrl_rows)
