from test_main import *
from PIL import Image
import io

def create_test_image():
    img = Image.new('RGB', (100, 100), color='red')
    img_byte_arr = io.BytesIO()
    img.save(img_byte_arr, format='JPEG')
    img_byte_arr.seek(0)
    return img_byte_arr

def create_test_pin(token, user_id="682c71ee4b4ac435f3d5af17"):
    pin_response = client.post(
        "/pin/add", 
        json={
            "title": "Test Pin", 
            "description": "Test Description", 
            "location": [0,0], 
            "complete_address": "Paris, Île-de-France, France métropolitaine, France",
            "files": [], 
            "user_id": user_id
        }, 
        headers={"Authorization": f"Bearer {token}"}
    )
    return pin_response.json()["id"]

def add_test_image(token, pin_id="null", caption="Test caption"):
    test_image = create_test_image()
    response = client.post(
        f"/image/pin/{pin_id}/add",
        files={"image": ("test.jpg", test_image, "image/jpeg")},
        data={"exif_date": "2024-03-20T12:00:00", "caption": caption},
        headers={"Authorization": f"Bearer {token}"}
    )
    return response.json()["id"]

def test_add_image_without_pin(token):
    image_id = add_test_image(token)
    assert image_id is not None

def test_add_image_with_pin(token, user_id):
    pin_id = create_test_pin(token, user_id)
    image_id = add_test_image(token, pin_id)
    assert image_id is not None

def test_get_image(token):
    pin_id = create_test_pin(token)
    image_id = add_test_image(token, pin_id)
    
    response = client.get(
        f"/image/{image_id}", 
        headers={"Authorization": f"Bearer {token}"}
    )
    assert response.status_code == 200
    assert response.headers["content-type"] == "image/jpeg"

def test_get_image_without_permission(token):
    image_id = add_test_image(token)
    
    response = client.get(
        f"/image/{image_id}", 
        headers={"Authorization": f"Bearer {token}"}
    )
    assert response.status_code == 403
    
def test_get_image_with_wrong_pin_id(token):
    image_id = add_test_image(token)
    
    response = client.get(
        f"/image/{image_id}", 
        headers={"Authorization": f"Bearer {token}"}
    )
    assert response.status_code == 403

def test_get_image_wrong_format(token):
    response = client.get(
        "/image/randomIdThatDoesntExists", 
        headers={"Authorization": f"Bearer {token}"}
    )
    assert response.status_code == 422

def test_get_image_unknown_id(token):
    response = client.get(
        "/image/123456789987654321abcdef", 
        headers={"Authorization": f"Bearer {token}"}
    )
    assert response.status_code == 404

def test_delete_image(token):
    pin_id = create_test_pin(token)
    image_id = add_test_image(token, pin_id)
    
    response = client.delete(
        f"/image/{image_id}", 
        headers={"Authorization": f"Bearer {token}"}
    )
    assert response.status_code == 200
    
    get_response = client.get(
        f"/image/{image_id}", 
        headers={"Authorization": f"Bearer {token}"}
    )
    assert get_response.status_code == 404

def test_update_caption(token):
    pin_id = create_test_pin(token)
    image_id = add_test_image(token, pin_id, "Original caption")
    
    response = client.patch(
        f"/image/{image_id}/caption",
        json={"caption": "Updated caption"},
        headers={"Authorization": f"Bearer {token}"}
    )
    assert response.status_code == 200

def test_get_caption_unauthorized(token, token_second):
    pin_id = create_test_pin(token)
    image_id = add_test_image(token, pin_id)
    
    response = client.get(
        f"/image/{image_id}/caption",
        headers={"Authorization": f"Bearer {token_second}"}
    )
    assert response.status_code == 403

def test_get_metadata(token):
    pin_id = create_test_pin(token)
    image_id = add_test_image(token, pin_id)
    
    response = client.get(
        f"/image/{image_id}/metadata",
        headers={"Authorization": f"Bearer {token}"}
    )
    assert response.status_code == 200
    data = response.json()
    assert "metadata" in data
    assert "pin_id" in data
    assert data["pin_id"] == pin_id
    assert data["metadata"]["original_filename"] == "test.jpg"
    assert data["metadata"]["mime_type"] == "image/jpeg"

def test_get_metadata_unauthorized(token, token_second):
    pin_id = create_test_pin(token)
    image_id = add_test_image(token, pin_id)
    
    response = client.get(
        f"/image/{image_id}/metadata",
        headers={"Authorization": f"Bearer {token_second}"}
    )
    assert response.status_code == 403

def test_image_permissions(token, token_second):
    pin_id = create_test_pin(token)
    image_id = add_test_image(token, pin_id)
    
    response = client.get(
        f"/image/{image_id}", 
        headers={"Authorization": f"Bearer {token_second}"}
    )
    assert response.status_code == 403

def test_invalid_image_type(token):
    text_file = io.BytesIO(b"Not an image")
    text_file.name = "test.txt"
    
    response = client.post(
        "/image/pin/null/add",
        files={"image": ("test.txt", text_file, "text/plain")},
        data={"exif_date": "2024-03-20T12:00:00", "caption": "Test caption"},
        headers={"Authorization": f"Bearer {token}"}
    )
    assert response.status_code == 415

def test_image_without_exif_date(token):
    # Créer d'abord un pin pour l'image
    pin_id = create_test_pin(token)
    
    test_image = create_test_image()
    response = client.post(
        f"/image/pin/{pin_id}/add",
        files={"image": ("test.jpg", test_image, "image/jpeg")},
        data={"caption": "Test caption"},
        headers={"Authorization": f"Bearer {token}"}
    )
    assert response.status_code == 200
    image_id = response.json()["id"]
    
    # Vérifier que la date a été générée automatiquement
    metadata_response = client.get(
        f"/image/{image_id}/metadata",
        headers={"Authorization": f"Bearer {token}"}
    )
    assert metadata_response.status_code == 200
    data = metadata_response.json()
    assert "created_at" in data["metadata"]
    assert data["metadata"]["created_at"] is not None

def test_image_with_invalid_pin_id(token):
    test_image = create_test_image()
    response = client.post(
        "/image/pin/123456789987654321abcdef/add",
        files={"image": ("test.jpg", test_image, "image/jpeg")},
        data={"exif_date": "2024-03-20T12:00:00", "caption": "Test caption"},
        headers={"Authorization": f"Bearer {token}"}
    )
    assert response.status_code == 404  # Le pin n'existe pas

# K.O
#
# def test_image_too_large(token):
#     # Créer une grande image
#     img = Image.fromarray(np.random.randint(0, 256, (8000, 8000, 3), dtype=np.uint8), 'RGB')
#     buf = io.BytesIO()
#     img.save(buf, format='JPEG', quality=100)
#     buf.seek(0)
#     buf.name = "large.jpg"
    
#     # Vérifier la taille de l'image
#     image_size = len(buf.getvalue())
#     print(f"Image size: {image_size} bytes ({image_size / (1024*1024):.2f} MB)")
    
#     response = client.post(
#         "/image/pin/null/add",
#         files={"image": ("large.jpg", buf, "image/jpeg")},
#         data={"exif_date": "2024-03-20T12:00:00", "caption": "Test caption"},
#         headers={"Authorization": f"Bearer {token}"}
#     )
#     print(f"Response status: {response.status_code}")
#     print(f"Response body: {response.text}")
#     assert response.status_code == 413 