import base64
import os
from io import BytesIO

from itables import show
from loguru import logger
from PIL import Image


def get_base64_image(filepath, width=200):
    try:
        with Image.open(filepath) as img:
            # Convert to RGB if needed
            if img.mode != "RGB":
                img = img.convert("RGB")

            aspect_ratio = img.height / img.width
            height = int(width * aspect_ratio)
            img = img.resize((width, height), Image.Resampling.LANCZOS)
            buffered = BytesIO()
            img.save(buffered, format="JPEG")
            img_str = base64.b64encode(buffered.getvalue()).decode()
            return f'<img src="data:image/jpeg;base64,{img_str}" width="{width}" alt="Sample Image">'
    except Exception as e:
        logger.warning(f"Failed to encode image {filepath}: {e}")
        return None


def show_interactive_table(df, filepath_col="filepath", image_col="image"):
    """
    Display an interactive table with images from filepaths.

    Args:
        df: pandas DataFrame that contains a 'filepath' column
    """
    # Create a copy to avoid modifying the original dataframe
    interactive_df = df.copy()

    # Add image column by applying get_base64_image to filepath column
    interactive_df[image_col] = interactive_df[filepath_col].apply(get_base64_image)

    # Convert filepath to clickable link with relative path
    interactive_df[filepath_col] = interactive_df[filepath_col].apply(
        lambda x: f'<a href="{x.replace(os.sep, "/")}">{x}</a>'
    )

    # Reorder columns to show image first
    cols = interactive_df.columns.tolist()
    cols.remove(image_col)
    interactive_df = interactive_df[[image_col] + cols]

    # Display interactive table
    show(
        interactive_df,
        columnDefs=[{"width": "200px", "targets": "_all"}],
        style="width:1200px",
        autoWidth=False,
    )
