import argparse
import math
import sys
import os
import shutil
from pathlib import Path
import pandas as pd
from PIL import Image, ImageDraw, ImageFont

# Configuration constants
ODS_PATH = "/home/sebastien/Rust/gestion_classe/Staging/simple_eval.ods"
OUTPUT_DIR = Path("/home/sebastien/Rust/Server/copies")
FONT_PATH = "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf" # Standard Linux font path

def get_rounded_score(score):
    """Round score to one decimal place below (floor)."""
    try:
        val = float(score)
        return math.floor(val * 10) / 10
    except (ValueError, TypeError):
        return None

def process_images(base_dir):
    # 1. Load Data
    try:
        # header=None assumes the file starts directly with data.
        # If row 0 is a header, change to header=0
        df = pd.read_excel(ODS_PATH, engine="odf", header=None)
        # Create a lookup dictionary: {Name: Score}
        score_db = dict(zip(df[0], df[1]))
    except Exception as e:
        print(f"CRITICAL ERROR: Could not read ODS file.\n{e}")
        sys.exit(1)

    # 2. Prepare Output Directory
    OUTPUT_DIR.mkdir(parents=True, exist_ok=True)

    # 3. Iterate Files
    # Structure: Dir/A Rendre/{name}/{name}.jpg
    search_path = base_dir / "A Rendre"

    if not search_path.exists():
        print(f"Error: Directory '{search_path}' not found.")
        sys.exit(1)

    for img_path in sorted(search_path.glob("*/*.jpg")):
        student_name = img_path.stem # Filename without extension

        # 4. Find Score
        if student_name not in score_db:
            print(f"Error: Student '{student_name}' not found in ODS file.")
            continue

        raw_score = score_db[student_name]
        score = get_rounded_score(raw_score)

        if score is None:
            print(f"Error: Invalid score '{raw_score}' for '{student_name}'.")
            continue

        # 5. Process Image
        try:
            with Image.open(img_path) as img:
                img = img.convert("RGB")
                draw = ImageDraw.Draw(img)
                width, height = img.size

                # Dynamic font size (15% of image height)
                font_size = int(width * 0.08)

                try:
                    font = ImageFont.truetype(FONT_PATH, font_size)
                except IOError:
                    # Fallback if specific font not found
                    font = ImageFont.load_default()
                    print(f"Warning: System font not found, using default for {student_name}")

                text = str(score)

                # Calculate text size and position (Top Right)
                bbox = draw.textbbox((0, 0), text, font=font)
                text_w = bbox[2] - bbox[0]
                text_h = bbox[3] - bbox[1]

                # 30px padding
                x = width - text_w - 30
                y = 30

                # Draw Text (Red)
                draw.text((x, y), text, fill=(255, 0, 0), font=font)

                # Save
                save_path = OUTPUT_DIR / f"{student_name}.jpg"
                img.save(save_path)
                print(f"Processed: {student_name} -> {score}")

        except Exception as e:
            print(f"Error processing image for '{student_name}': {e}")

    for pdf_path in sorted(search_path.glob("*/*.pdf")):
        student_name = pdf_path.stem # Filename without extension
        save_path = OUTPUT_DIR / f"{student_name}.pdf"

        shutil.copy(str(pdf_path), str(save_path))


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Stamp scores on exam copies.")
    parser.add_argument("dir", type=Path, help="Root directory containing 'A Rendre' folder")


    args = parser.parse_args()

    OUTPUT_DIR = OUTPUT_DIR / args.dir
    OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
    process_images(args.dir)
