import os
import sys
import json
import ezodf
import re
from pathlib import Path

from utils import natural_key, read_all_labels

# Configuration
ODS_PATH = "/home/sebastien/Rust/gestion_classe/Staging/current_eval.ods"
TARGET_DIR_NAME = "A Rendre"

def main():
    if len(sys.argv) < 2:
        # Default to current directory if not provided, or raise error
        work_dir = os.getcwd()
    else:
        work_dir = os.path.abspath(sys.argv[1])

    all_labels = read_all_labels(Path(work_dir))

    a_rendre_path = os.path.join(work_dir, TARGET_DIR_NAME)

    if not os.path.isdir(a_rendre_path):
        print(f"Error: Directory '{TARGET_DIR_NAME}' not found in {work_dir}")
        sys.exit(1)

    if not os.path.exists(ODS_PATH):
        print(f"Error: ODS file not found at {ODS_PATH}")
        sys.exit(1)

    print(f"Opening ODS file: {ODS_PATH}...")
    try:
        doc = ezodf.opendoc(ODS_PATH)
    except Exception as e:
        print(f"Failed to open ODS: {e}")
        sys.exit(1)

    # Assuming the data is in the first sheet
    sheet = doc.sheets[0]

    # Map Student Names to Column Indices
    # User specified: Names are in the second line (index 1)
    # User specified: Ignore first 3 columns (0, 1, 2)
    name_row_index = 1
    name_to_col = {}

    for col_idx in range(3, sheet.ncols()):
        cell = sheet[name_row_index, col_idx]
        if cell.value:
            # Normalize name: strip spaces
            name = str(cell.value).strip()
            name_to_col[name] = col_idx

    print(f"Found {len(name_to_col)} students in ODS.")

    # Iterate over folders in "A Rendre"
    for item in os.listdir(a_rendre_path):
        student_dir = os.path.join(a_rendre_path, item)

        # Check if it is a directory and has a name (ignoring the (ID) suffix if present from previous script)
        # The directory name might be "Name" or "Name (ID)".
        # The ODS usually contains just "Name".

        if not os.path.isdir(student_dir):
            continue

        # Extract strict name for ODS matching (remove potential ID suffix if added by previous tool)
        # Assuming the ODS name matches the folder name prefix
        # If folder is "Doe John (123)", ODS likely has "Doe John" or "Doe John (123)"?
        # Based on previous prompt, ODS has "AMELOT Gautier".
        # We try exact match first, then simplified match.

        json_path = os.path.join(student_dir, "score.json")
        if not os.path.exists(json_path):
            continue

        with open(json_path, 'r', encoding='utf-8') as f:
            try:
                scores_data = json.load(f)
            except json.JSONDecodeError:
                print(f"Error decoding JSON for {item}")
                continue

        # Determine Column Index
        col_idx = name_to_col.get(item)

        # If not found exact match, try stripping ID suffix e.g. "Name (123)" -> "Name"
        if col_idx is None and '(' in item:
            clean_name = item.rsplit('(', 1)[0].strip()
            col_idx = name_to_col.get(clean_name)

        if col_idx is None:
            print(f"Skipping '{item}': Name not found in ODS columns.")
            continue

        # Sort keys naturally (Ex 2 comes before Ex 10)
        # sorted_keys = natsorted(scores_data.keys())

        # Start filling from Row 2 (index 2), immediately below the name line
        start_row = 2

        # for i, key in enumerate(scores_data.keys()):
        for i, key in enumerate(all_labels):
            row_idx = start_row + i

            # Ensure we don't go out of bounds
            if row_idx >= sheet.nrows():
                sheet.append_rows(1)

            if key in scores_data:
                val_str = str(scores_data[key])
            else:
                val_str = ""

            # Logic: if "" -> "NT"
            new_val = "NT" if val_str == "" else val_str

            cell = sheet[row_idx, col_idx]
            current_val = cell.value

            # Conflict Detection
            # Normalize current ODS value to string for comparison
            # ODS might store 2.0 as float 2.0. JSON has "2.0".
            is_different = False

            if current_val is not None and current_val != "":
                # specific check to handle float/string mismatch (2.0 vs "2.0")
                try:
                    if float(str(current_val)) != float(str(new_val)):
                        is_different = True
                except ValueError:
                    # If conversion fails (e.g. comparing "NT" to "2.0"), compare strings
                    if str(current_val).strip() != str(new_val).strip():
                        is_different = True

                if is_different:
                    print(f"DEBUG: Conflict for {item} at {key} (Row {row_idx}). "
                          f"Existing: '{current_val}' vs New: '{new_val}'. Overwriting.")

            # Set value
            # Try to set as float if it looks like a number, otherwise string
            if new_val == "NT":
                cell.set_value(new_val)
            else:
                try:
                    cell.set_value(float(new_val))
                except ValueError:
                    cell.set_value(new_val)

    print("Saving ODS file...")
    doc.save()
    print("Done.")

if __name__ == "__main__":
    main()
