"""Non-regression tests for the P1 issues found during the UI audit.

The audit VM is not available in this environment; these tests exercise the
same routes against the local Flask test database.
"""

from app_new.extensions import db
from app_new.core.models.college import Building, Zone, Room
from app_new.core.models.maintenance import Intervention
from app_new.core.models.cleaning import ProductGeneric
from app_new.core.models.equipment import Equipment, EquipmentCategory


def test_room_form_lists_buildings_and_rejects_cross_building_zone(authenticated_client, app):
    authenticated_client.post('/equipments/buildings/new', data={'name': 'UI test bâtiment A'})
    authenticated_client.post('/equipments/buildings/new', data={'name': 'UI test bâtiment B'})
    with app.app_context():
        building_a = Building.query.filter_by(name="UI test bâtiment A").one()
        building_b = Building.query.filter_by(name="UI test bâtiment B").one()
        zone_b = Zone(name="UI test zone B", building_id=building_b.id)
        db.session.add(zone_b)
        db.session.commit()
        a_id, b_id, zone_id = building_a.id, building_b.id, zone_b.id

    response = authenticated_client.get("/equipments/rooms/new")
    assert response.status_code == 200
    body = response.get_data(as_text=True)
    assert "UI test bâtiment A" in body
    assert "UI test bâtiment B" in body

    response = authenticated_client.post("/equipments/rooms/new", data={
        "name": "Salle incohérente",
        "building_id": str(a_id),
        "zone_id": str(zone_id),
    })
    assert response.status_code == 400
    with app.app_context():
        assert Room.query.filter_by(name="Salle incohérente").first() is None


def test_optional_location_is_safe_in_interventions(authenticated_client, app):
    with app.app_context():
        intervention = Intervention(title="UI intervention sans localisation")
        db.session.add(intervention)
        db.session.commit()
    assert authenticated_client.get("/interventions/").status_code == 200


def test_intervention_list_supports_all_optional_location_combinations(authenticated_client, app):
    """Une intervention peut cibler salle, équipement, les deux ou aucun."""
    with app.app_context():
        building = Building(name="UI combinations building")
        db.session.add(building)
        db.session.flush()
        room = Room(name="UI combinations room", building_id=building.id)
        category = EquipmentCategory(name="UI combinations category")
        db.session.add_all([room, category])
        db.session.flush()
        equipment = Equipment(
            name="UI combinations equipment", room_id=room.id,
            category_id=category.id, status="en_service",
        )
        db.session.add(equipment)
        db.session.flush()
        interventions = [
            Intervention(title="UI both", room_id=room.id, equipment_id=equipment.id),
            Intervention(title="UI room only", room_id=room.id),
            Intervention(title="UI equipment only", equipment_id=equipment.id),
            Intervention(title="UI neither"),
        ]
        db.session.add_all(interventions)
        db.session.commit()
        intervention_ids = [intervention.id for intervention in interventions]

    response = authenticated_client.get("/interventions/")
    assert response.status_code == 200
    source = open("app_new/interventions/templates/index.html", encoding="utf-8").read()
    assert "Localisation non renseignée" in source
    from app_new.interventions.crud import detail as intervention_detail
    with app.app_context(), app.test_request_context("/interventions/1"):
        for intervention_id in intervention_ids:
            rendered = intervention_detail.__wrapped__(intervention_id)
            assert "Intervention" in rendered or "Localisation" in rendered
    assert authenticated_client.get("/").status_code == 200


def test_optional_equipment_is_safe_on_dashboard(authenticated_client, app):
    with app.app_context():
        db.session.add(Intervention(title="UI dashboard sans équipement"))
        db.session.commit()
    assert authenticated_client.get("/").status_code == 200


def test_intervention_detail_template_exposes_document_actions():
    template = open('app_new/interventions/templates/detail.html', encoding='utf-8').read()
    assert 'documents.download_intervention_document' in template
    assert 'documents.delete_intervention_document' in template
    assert 'documents.upload_intervention' in template


def test_logs_navigation_uses_the_permission_required_by_logs_route():
    from app_new.core.authorization import required_permission

    assert required_permission("logs.index", "GET") == "watchdog_dnd.view"
    source = open("app_new/templates/base.html", encoding="utf-8").read()
    assert "has_permission('watchdog_dnd.view')" in source
    assert "has_permission('audit.view')" not in source[source.find("Notifications système") - 200:source.find("Notifications système") + 200]


def test_grouped_equipment_detail_and_hierarchy(authenticated_client, app):
    """Une famille quantitative localisée doit rester consultable."""
    assert "nl2br" in app.jinja_env.filters
    with app.app_context():
        building = Building(name="UI equipment detail building")
        db.session.add(building)
        db.session.flush()
        room = Room(name="UI equipment detail room", building_id=building.id)
        category = EquipmentCategory(name="UI equipment detail category")
        db.session.add_all([room, category])
        db.session.flush()
        equipment = Equipment(
            name="UI grouped chairs", room_id=room.id, category_id=category.id,
            status="en_service", is_group=False, quantity=30, mobility="mobile",
        )
        db.session.add(equipment)
        db.session.commit()
        equipment_id = equipment.id
        assert db.session.get(Equipment, equipment_id) is not None

    from app_new.equipments.main import detail as equipment_detail, hierarchy as equipment_hierarchy
    with app.app_context(), app.test_request_context(f"/equipments/{equipment_id}"):
        detail_response = equipment_detail.__wrapped__(equipment_id)
        assert "UI grouped chairs" in detail_response
        hierarchy_response = equipment_hierarchy.__wrapped__(equipment_id)
        assert hierarchy_response.status_code == 200
        payload = hierarchy_response.get_json()
    assert payload["zones"]
    assert payload["zones"][0]["rooms"][0]["name"] == "UI equipment detail room"
    assert payload["zones"][0]["rooms"][0]["items"][0]["quantity"] == 30


def test_empty_intervention_and_company_are_validation_errors(authenticated_client):
    assert authenticated_client.post("/interventions/new", data={}).status_code == 400
    assert authenticated_client.post("/companies/new", data={}).status_code == 400


def test_invalid_product_quantity_is_validation_error(authenticated_client, app):
    authenticated_client.post('/cleaning/products/new', data={
        'name': 'UI produit quantité invalide',
        'reference_unit': 'unité',
        'stock_minimum': '0', 'stock_security': '0', 'forecast_daily_quantity': '0',
    })
    with app.app_context():
        product = ProductGeneric.query.filter_by(name="UI produit quantité invalide").one()
        product_id = product.id
    response = authenticated_client.post(f"/cleaning/products/{product_id}/edit", data={
        "name": "UI produit quantité invalide",
        "stock_minimum": "pas-un-nombre",
        "stock_security": "0",
        "forecast_daily_quantity": "0",
    })
    assert response.status_code == 400
    assert "numériques" in response.get_data(as_text=True)


def test_product_request_enabled_is_editable(authenticated_client, app):
    response = authenticated_client.get('/cleaning/products/new')
    assert response.status_code == 200
    assert 'request_enabled' in response.get_data(as_text=True)


def test_cleaning_pages_load_without_reference_data(authenticated_client, app):
    # Some legacy RBAC tests intentionally alter the admin role. Restore only
    # the permission required by this independent route smoke test.
    with app.app_context():
        from app_new.core.models.rbac import Role, Permission, RolePermission
        role = Role.query.filter_by(slug='admin').first()
        permission = Permission.query.filter_by(code='stock.view').first()
        if role and permission and not RolePermission.query.filter_by(role_id=role.id, permission_id=permission.id).first():
            db.session.add(RolePermission(role_id=role.id, permission_id=permission.id, effect='allow'))
            db.session.commit()
    assert authenticated_client.get("/cleaning/transvasement").status_code == 200
    assert authenticated_client.get("/cleaning/forecast-config").status_code == 200
    assert authenticated_client.get("/cleaning/stock").status_code == 200
