"""Covers app/routers/uploads.py — upload/download round-trip, tenant
isolation (a file uploaded by tenant A must 404 for tenant B, not leak
existence via a 403), unauthenticated rejection, and the Masters "file"
field type's validation against real uploaded_files rows."""

import uuid

from sqlalchemy import text

from app.core.auth import create_access_token
from tests.conftest import AsyncSessionLocal


async def test_upload_then_download_round_trip(client, auth_headers):
    upload_resp = await client.post(
        "/uploads",
        headers=auth_headers,
        files={"file": ("hello.txt", b"hello from pytest", "text/plain")},
    )
    assert upload_resp.status_code == 201
    file_id = upload_resp.json()["id"]
    assert upload_resp.json()["filename"] == "hello.txt"
    assert upload_resp.json()["size_bytes"] == len(b"hello from pytest")

    download_resp = await client.get(f"/uploads/{file_id}/download", headers=auth_headers)
    assert download_resp.status_code == 200
    assert download_resp.content == b"hello from pytest"


async def test_download_without_auth_is_rejected(client, auth_headers):
    upload_resp = await client.post(
        "/uploads", headers=auth_headers, files={"file": ("secret.txt", b"secret", "text/plain")}
    )
    file_id = upload_resp.json()["id"]

    resp = await client.get(f"/uploads/{file_id}/download")
    assert resp.status_code == 401


async def test_download_from_other_tenant_is_rejected(client, auth_headers, test_tenant):
    upload_resp = await client.post(
        "/uploads", headers=auth_headers, files={"file": ("mine.txt", b"only for my tenant", "text/plain")}
    )
    file_id = upload_resp.json()["id"]

    # A real, licensed tenant — one that doesn't exist is turned away before
    # the file is even looked up (app/crud/licensing.py).
    other_id = uuid.uuid4()
    async with AsyncSessionLocal() as db:
        async with db.begin():
            await db.execute(
                text("INSERT INTO tenants (id, name, status, license_set_at) VALUES (:id, :n, 'active', now())"),
                {"id": other_id, "n": f"Pytest Tenant {other_id.hex[:8]}"},
            )
    try:
        other_tenant_token = create_access_token(tenant_id=other_id, user_id=uuid.uuid4(), vendor_id=None)
        resp = await client.get(f"/uploads/{file_id}/download", headers={"Authorization": f"Bearer {other_tenant_token}"})
        assert resp.status_code == 404
    finally:
        async with AsyncSessionLocal() as db:
            async with db.begin():
                await db.execute(text("DELETE FROM tenants WHERE id = :id"), {"id": other_id})


async def test_download_nonexistent_file_is_404(client, auth_headers):
    resp = await client.get(f"/uploads/{uuid.uuid4()}/download", headers=auth_headers)
    assert resp.status_code == 404


async def test_delete_removes_file(client, auth_headers):
    upload_resp = await client.post(
        "/uploads", headers=auth_headers, files={"file": ("todelete.txt", b"bye", "text/plain")}
    )
    file_id = upload_resp.json()["id"]

    delete_resp = await client.delete(f"/uploads/{file_id}", headers=auth_headers)
    assert delete_resp.status_code == 204

    get_resp = await client.get(f"/uploads/{file_id}", headers=auth_headers)
    assert get_resp.status_code == 404


async def test_master_file_field_accepts_valid_upload_id(client, auth_headers):
    upload_resp = await client.post(
        "/uploads", headers=auth_headers, files={"file": ("doc.txt", b"a document", "text/plain")}
    )
    file_id = upload_resp.json()["id"]

    master_resp = await client.post(
        "/masters",
        headers=auth_headers,
        json={"name": "File Field Test", "field_schema": [{"name": "attachment", "type": "file"}]},
    )
    master_id = master_resp.json()["id"]

    record_resp = await client.post(
        f"/masters/{master_id}/records", headers=auth_headers, json={"field_values": {"attachment": file_id}}
    )
    assert record_resp.status_code == 201
    assert record_resp.json()["field_values"]["attachment"] == file_id


async def test_master_file_field_rejects_unknown_file_id(client, auth_headers):
    master_resp = await client.post(
        "/masters",
        headers=auth_headers,
        json={"name": "File Field Reject Test", "field_schema": [{"name": "attachment", "type": "file"}]},
    )
    master_id = master_resp.json()["id"]

    record_resp = await client.post(
        f"/masters/{master_id}/records",
        headers=auth_headers,
        json={"field_values": {"attachment": str(uuid.uuid4())}},
    )
    assert record_resp.status_code == 422
