import os
import argparse
import shutil
from PIL import Image

# --- Konfiguracija skripte za projekt "Hermina" ---

# Predpostavka: ta skripta se nahaja v korenski mapi projekta.
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))

# Pot do mape, kjer se nahajajo slike, ki jih želimo optimizirati.
IMAGES_DIR_PATH = os.path.join("assets", "images")

# Ime podmape znotraj IMAGES_DIR_PATH, kamor se bodo shranile originalne slike.
ORIGINAL_IMAGES_SUBDIR_NAME = "original"

# Mape, ki jih želimo PREGLEDATI za posodobitev referenc na slike.
# '.' pomeni, da začnemo v korenski mapi in pregledamo vse podmape.
DIRECTORIES_TO_SCAN = ['.']

# Mape, ki jih želimo IZKLJUČITI iz pregledovanja (za hitrejše delovanje in varnost).
# Skripta ne bo iskala referenc v teh mapah.
DIRECTORIES_TO_EXCLUDE_FROM_SCAN = ['.git', '.gitea', '.vscode', '__pycache__']

# Končnice datotek, v katerih iščemo in posodabljamo reference na slike.
FILE_EXTENSIONS_TO_UPDATE = ['.html', '.css', '.js']

# Nastavitve optimizacije
WEBP_QUALITY = 85  # Kakovost kompresije za WebP (0-100). Višje = boljša kvaliteta, večja datoteka.
MAX_IMAGE_DIMENSION = 1920  # Slike, večje od te dimenzije (širina ali višina), bodo pomanjšane. 0 za izklop.

# Končnice slik, ki jih želimo optimizirati.
IMAGE_EXTENSIONS_TO_OPTIMIZE = ['.jpg', '.jpeg', '.png']

# Imena datotek, ki jih želimo preskočiti pri optimizaciji (npr. logotipi, ikone).
EXCLUDE_FILES_FROM_OPTIMIZATION = [
    'favicon.ico'
    # Dodajte imena drugih datotek po potrebi, npr. 'logo.png'
]


# --- Pomožne funkcije (večinoma nespremenjene) ---

def optimize_image(image_path, output_path, quality, max_dim, dry_run=False):
    """
    Naloži sliko, jo po potrebi pomanjša, optimizira in pretvori v WebP format.
    """
    try:
        with Image.open(image_path) as img:
            # Pretvorba slik s paleto (kot so nekatere PNG) v RGBA za ohranitev prosojnosti.
            if img.mode in ('P', 'LA'):
                img = img.convert("RGBA")

            if max_dim > 0 and (img.width > max_dim or img.height > max_dim):
                print(f"  Pomanjšujem sliko {os.path.basename(image_path)} iz {img.width}x{img.height} ...", end="")
                img.thumbnail((max_dim, max_dim), Image.Resampling.LANCZOS)
                print(f" na {img.width}x{img.height}")
            else:
                print(f"  Obdelujem sliko {os.path.basename(image_path)} ({img.width}x{img.height})...", end="")

            if not dry_run:
                img.save(output_path, "webp", quality=quality, method=6)
                print(f" Shrani v {os.path.basename(output_path)} (kvaliteta: {quality}).")
            else:
                print(f" DRY RUN: Shranil bi v {os.path.basename(output_path)} (kvaliteta: {quality}).")

            return True
    except FileNotFoundError:
        print(f"  Napaka: Izvorna slika '{image_path}' ni najdena.")
        return False
    except Exception as e:
        print(f"  Napaka pri optimizaciji slike '{image_path}': {e}")
        return False

def update_file_references(file_path, old_filename, new_filename, dry_run=False):
    """
    V dani datoteki zamenja vse pojavitve starega imena slike z novim.
    """
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            content = f.read()
    except Exception:
        # Ignoriramo binarne ali neberljive datoteke
        return False

    if old_filename in content:
        updated_content = content.replace(old_filename, new_filename)
        if not dry_run:
            try:
                with open(file_path, 'w', encoding='utf-8') as f:
                    f.write(updated_content)
                print(f"  Posodobljene reference v: '{os.path.relpath(file_path, PROJECT_ROOT)}'")
                return True
            except Exception as e:
                print(f"  Napaka pri zapisovanju v '{file_path}': {e}")
                return False
        else:
            print(f"  DRY RUN: Posodobil bi reference v: '{os.path.relpath(file_path, PROJECT_ROOT)}'")
            return True
    return False

def find_files_to_update(scan_dirs, exclude_dirs):
    """
    Rekurzivno poišče vse datoteke z ustreznimi končnicami, pri tem pa ignorira izključene mape.
    """
    found_files = []
    for directory in scan_dirs:
        scan_path = os.path.join(PROJECT_ROOT, directory)
        for dirpath, dirnames, filenames in os.walk(scan_path):
            # Učinkovit način za izključitev map: odstranimo jih iz seznama za nadaljnje pregledovanje
            dirnames[:] = [d for d in dirnames if d not in exclude_dirs]
            
            for filename in filenames:
                if any(filename.endswith(ext) for ext in FILE_EXTENSIONS_TO_UPDATE):
                    found_files.append(os.path.join(dirpath, filename))
    return sorted(list(set(found_files)))


# --- Glavna funkcija ---

def main():
    parser = argparse.ArgumentParser(description="Optimizira slike v WebP in posodobi reference v projektu.")
    parser.add_argument("--dry-run", action="store_true", help="Prikaže, katere spremembe bi se zgodile, a jih ne izvede.")
    args = parser.parse_args()

    images_full_path = os.path.join(PROJECT_ROOT, IMAGES_DIR_PATH)
    original_images_full_path = os.path.join(images_full_path, ORIGINAL_IMAGES_SUBDIR_NAME)
    
    # Dodamo mapo z originali v seznam za izključitev, da ne skeniramo še tam.
    DIRECTORIES_TO_EXCLUDE_FROM_SCAN.append(ORIGINAL_IMAGES_SUBDIR_NAME)

    if not os.path.isdir(images_full_path):
        print(f"Napaka: Mapa s slikami '{images_full_path}' ne obstaja. Preverite pot v konfiguraciji.")
        return

    if not args.dry_run:
        os.makedirs(original_images_full_path, exist_ok=True)
        print(f"Mapa za originale: '{original_images_full_path}'")
    else:
        print(f"DRY RUN: Mapa za originale bi bila '{original_images_full_path}'.")

    optimized_images_map = []
    
    print("\n--- FAZA 1: OPTIMIZACIJA SLIK ---")
    for dirpath, dirnames, filenames in os.walk(images_full_path):
        # preskoči mapo z originali, če že obstaja
        dirnames[:] = [
            d for d in dirnames
            if os.path.relpath(os.path.join(dirpath, d), images_full_path) != ORIGINAL_IMAGES_SUBDIR_NAME
        ]

        for filename in filenames:
            file_path = os.path.join(dirpath, filename)

            if not os.path.isfile(file_path):
                continue

            name, ext = os.path.splitext(filename)
            ext = ext.lower()

            if filename in EXCLUDE_FILES_FROM_OPTIMIZATION:
                print(f"- Preskakujem izključeno datoteko: '{filename}'")
                continue

            if ext in IMAGE_EXTENSIONS_TO_OPTIMIZE:
                new_filename = f"{name}.webp"
                new_file_path = os.path.join(dirpath, new_filename)

                rel_dir = os.path.relpath(dirpath, images_full_path)
                rel_dir = "" if rel_dir == "." else rel_dir
                old_rel_path = os.path.join(rel_dir, filename) if rel_dir else filename
                new_rel_path = os.path.join(rel_dir, new_filename) if rel_dir else new_filename
                old_rel_path = old_rel_path.replace(os.sep, "/")
                new_rel_path = new_rel_path.replace(os.sep, "/")

                # Preveri, če WebP verzija že obstaja in je novejša
                if os.path.exists(new_file_path) and os.path.getmtime(new_file_path) > os.path.getmtime(file_path):
                    print(f"- WebP '{new_rel_path}' že obstaja in je posodobljen. Preskakujem optimizacijo.")
                    optimized_images_map.append({'old': filename, 'new': new_filename, 'old_path': old_rel_path, 'new_path': new_rel_path})
                    continue

                if optimize_image(file_path, new_file_path, WEBP_QUALITY, MAX_IMAGE_DIMENSION, args.dry_run):
                    optimized_images_map.append({'old': filename, 'new': new_filename, 'old_path': old_rel_path, 'new_path': new_rel_path})
                    if not args.dry_run:
                        try:
                            destination_dir = os.path.join(original_images_full_path, rel_dir) if rel_dir else original_images_full_path
                            os.makedirs(destination_dir, exist_ok=True)
                            shutil.move(file_path, os.path.join(destination_dir, filename))
                            print(f"  Original '{old_rel_path}' premaknjen v '{ORIGINAL_IMAGES_SUBDIR_NAME}/'.")
                        except Exception as e:
                            print(f"  NAPAKA pri premikanju '{old_rel_path}': {e}")
                    else:
                        print(f"  DRY RUN: Original '{old_rel_path}' bi bil premaknjen v '{ORIGINAL_IMAGES_SUBDIR_NAME}/'.")

    if not optimized_images_map:
        print("\nNi bilo najdenih novih slik za optimizacijo.")
    
    print("\n--- FAZA 2: POSODABLJANJE REFERENC V PROJEKTU ---")
    
    files_to_scan = find_files_to_update(DIRECTORIES_TO_SCAN, DIRECTORIES_TO_EXCLUDE_FROM_SCAN)
    
    if not files_to_scan:
        print("Ni najdenih .html, .css ali .js datotek za pregled.")
    else:
        print(f"Najdenih {len(files_to_scan)} datotek za pregled...")

    updated_files_count = 0
    for file_path in files_to_scan:
        file_was_updated = False
        for img_info in optimized_images_map:
            replaced = False
            if update_file_references(file_path, img_info['old_path'], img_info['new_path'], args.dry_run):
                replaced = True
            # za nazaj združljivost: če je v datoteki samo ime brez poti
            if update_file_references(file_path, img_info['old'], img_info['new'], args.dry_run):
                replaced = True

            if replaced:
                file_was_updated = True
        
        if file_was_updated:
            updated_files_count += 1
            
    print(f"\nPregledanih je bilo {len(files_to_scan)} datotek.")
    print(f"Posodobljenih je bilo {updated_files_count} datotek.")
    print("\n--- SKRIPTA JE ZAKLJUČILA Z DELOM ---")

if __name__ == "__main__":
    main()
