#!/usr/bin/env python3
# filepath: c:\Users\sof12\Desktop\ML\Code\rename_with_dates.py

"""
SCRIPT PARA RENOMBRAR IMÁGENES AGREGANDO FECHAS
==============================================

Este script:
1. Lee el CSV change_namesAV.csv que contiene Old_Name y New_Name
2. Extrae las fechas del formato original (YYYY_MM_DD_##_##_##_X.jpg)
3. Renombra las imágenes al formato: YYYY_MM_DD_NocciolaAV_###.jpg
4. Actualiza el CSV con los nuevos nombres

FORMATO ORIGINAL: YYYY_MM_DD_##_##_##_X.jpg
FORMATO NUEVO:    YYYY_MM_DD_NocciolaAV_###.jpg

AUTOR: Sofia Garcia Arcila
FECHA: Octubre 2025
VERSION: 1.0
"""

# =============================================================================
# IMPORTACIÓN DE LIBRERÍAS
# =============================================================================

import os
import pandas as pd
import re
from pathlib import Path

# =============================================================================
# FUNCIONES AUXILIARES
# =============================================================================

def extract_date_from_filename(filename):
    """
    Extrae la fecha del nombre de archivo original.
    
    Args:
        filename (str): Nombre del archivo original (ej: "2023_10_15_12_30_45_1.jpg")
        
    Returns:
        str: Fecha en formato YYYY_MM_DD o None si no se puede extraer
    """
    try:
        # Patrón para extraer fecha del formato YYYY_MM_DD_##_##_##_X.jpg
        pattern = r'^(\d{4}_\d{2}_\d{2})_\d+_\d+_\d+_\d+\.'
        match = re.match(pattern, filename)
        
        if match:
            return match.group(1)  # Retorna YYYY_MM_DD
        else:
            print(f"   ⚠️  No se pudo extraer fecha de: {filename}")
            return None
            
    except Exception as e:
        print(f"   ❌ Error extrayendo fecha de {filename}: {e}")
        return None

def create_new_filename_with_date(old_name, current_new_name, date_prefix):
    """
    Crea el nuevo nombre de archivo con la fecha al principio.
    
    Args:
        old_name (str): Nombre original del archivo
        current_new_name (str): Nombre actual (NocciolaAV_###.jpg)
        date_prefix (str): Prefijo de fecha (YYYY_MM_DD)
        
    Returns:
        str: Nuevo nombre con formato YYYY_MM_DD_NocciolaAV_###.jpg
    """
    try:
        if date_prefix is None:
            # Si no hay fecha, usar el nombre actual sin cambios
            return current_new_name
        
        # Extraer la parte después de "NocciolaAV_" y mantener la extensión
        # Por ejemplo: "NocciolaAV_001.jpg" -> "NocciolaAV_001.jpg"
        base_name, extension = os.path.splitext(current_new_name)
        
        # Crear nuevo nombre: YYYY_MM_DD_NocciolaAV_###.jpg
        new_name_with_date = f"{date_prefix}_{base_name}{extension}"
        
        return new_name_with_date
        
    except Exception as e:
        print(f"   ❌ Error creando nuevo nombre: {e}")
        return current_new_name  # Retornar nombre actual en caso de error

# =============================================================================
# FUNCIÓN PRINCIPAL
# =============================================================================

def rename_images_with_dates():
    """
    Función principal que renombra las imágenes agregando las fechas.
    
    Returns:
        bool: True si el proceso fue exitoso, False en caso contrario
    """
    
    print("🚀 INICIANDO RENOMBRADO CON FECHAS")
    print("=" * 50)
    
    # =========================================================================
    # 1. CONFIGURAR RUTAS
    # =========================================================================
    
    # Directorio donde están las imágenes actuales
    images_folder = r"C:\Users\sof12\Desktop\ML\dataset\Nocciola"
    
    # Archivo CSV con los cambios de nombres
    csv_path = r"C:\Users\sof12\Desktop\ML\dataset\Nocciola\change_namesAV.csv"
    
    # Nuevo archivo CSV que se generará
    new_csv_path = r"C:\Users\sof12\Desktop\ML\dataset\Nocciola\change_names_with_dates.csv"
    
    print(f"📁 Directorio de imágenes: {images_folder}")
    print(f"📄 CSV original: {csv_path}")
    print(f"📄 CSV nuevo: {new_csv_path}")
    
    # =========================================================================
    # 2. VERIFICAR ARCHIVOS
    # =========================================================================
    
    print(f"\n🔍 Verificando archivos...")
    
    if not os.path.exists(csv_path):
        print(f"❌ Error: No se encontró el archivo CSV en {csv_path}")
        return False
    
    if not os.path.exists(images_folder):
        print(f"❌ Error: No se encontró el directorio de imágenes en {images_folder}")
        return False
    
    print(f"   ✅ Archivos encontrados")
    
    # =========================================================================
    # 3. CARGAR CSV
    # =========================================================================
    
    print(f"\n📄 Cargando CSV...")
    
    try:
        # Intentar diferentes encodings
        try:
            df = pd.read_csv(csv_path, encoding='utf-8')
            print(f"   ✅ CSV cargado con UTF-8")
        except UnicodeDecodeError:
            df = pd.read_csv(csv_path, encoding='utf-8-sig')
            print(f"   ✅ CSV cargado con UTF-8-sig")
        
        print(f"   📊 Registros en CSV: {len(df)}")
        print(f"   🔍 Columnas: {list(df.columns)}")
        
        # Verificar columnas requeridas
        required_columns = ['Old_Name', 'New_Name']
        missing_columns = [col for col in required_columns if col not in df.columns]
        
        if missing_columns:
            print(f"❌ Error: Faltan columnas en el CSV: {missing_columns}")
            return False
            
    except Exception as e:
        print(f"❌ Error cargando CSV: {e}")
        return False
    
    # =========================================================================
    # 4. PROCESAR DATOS Y EXTRAER FECHAS
    # =========================================================================
    
    print(f"\n🔧 Procesando datos y extrayendo fechas...")
    
    # Crear nuevas columnas
    df['Date_Extracted'] = ''
    df['New_Name_With_Date'] = ''
    
    processed_count = 0
    dates_extracted = 0
    
    for index, row in df.iterrows():
        old_name = row['Old_Name']
        current_new_name = row['New_Name']
        
        # Extraer fecha del nombre original
        date_prefix = extract_date_from_filename(old_name)
        
        if date_prefix:
            dates_extracted += 1
        
        # Crear nuevo nombre con fecha
        new_name_with_date = create_new_filename_with_date(old_name, current_new_name, date_prefix)
        
        # Actualizar DataFrame
        df.at[index, 'Date_Extracted'] = date_prefix if date_prefix else 'No_Date'
        df.at[index, 'New_Name_With_Date'] = new_name_with_date
        
        processed_count += 1
        
        if processed_count % 50 == 0:
            print(f"   📊 Procesados {processed_count} registros...")
    
    print(f"   ✅ Procesamiento completado")
    print(f"   📊 Total procesados: {processed_count}")
    print(f"   📅 Fechas extraídas exitosamente: {dates_extracted}")
    print(f"   ⚠️  Sin fecha: {processed_count - dates_extracted}")
    
    # =========================================================================
    # 5. MOSTRAR EJEMPLOS
    # =========================================================================
    
    print(f"\n👀 EJEMPLOS DE CAMBIOS:")
    
    # Mostrar algunos ejemplos
    examples = df.head()
    for i, (_, row) in enumerate(examples.iterrows()):
        print(f"   {i+1}. {row['Old_Name']}")
        print(f"      └─ Actual: {row['New_Name']}")
        print(f"      └─ Nuevo:  {row['New_Name_With_Date']}")
        print()
    
    # =========================================================================
    # 6. RENOMBRAR ARCHIVOS FÍSICOS
    # =========================================================================
    
    print(f"🔄 Renombrando archivos físicos...")
    
    renamed_count = 0
    not_found_count = 0
    errors_count = 0
    
    for index, row in df.iterrows():
        current_name = row['New_Name']
        new_name_with_date = row['New_Name_With_Date']
        
        # Rutas completas
        current_path = os.path.join(images_folder, current_name)
        new_path = os.path.join(images_folder, new_name_with_date)
        
        try:
            # Verificar si el archivo actual existe
            if os.path.exists(current_path):
                # Renombrar archivo
                os.rename(current_path, new_path)
                renamed_count += 1
                
                if renamed_count % 50 == 0:
                    print(f"   📊 Renombrados {renamed_count} archivos...")
            else:
                print(f"   ⚠️  Archivo no encontrado: {current_name}")
                not_found_count += 1
                
        except Exception as e:
            print(f"   ❌ Error renombrando {current_name}: {e}")
            errors_count += 1
    
    print(f"   ✅ Renombrado completado")
    print(f"   📊 Archivos renombrados: {renamed_count}")
    print(f"   ⚠️  Archivos no encontrados: {not_found_count}")
    print(f"   ❌ Errores: {errors_count}")
    
    # =========================================================================
    # 7. GUARDAR NUEVO CSV
    # =========================================================================
    
    print(f"\n💾 Guardando nuevo CSV...")
    
    try:
        # Reordenar columnas
        column_order = ['Old_Name', 'New_Name', 'New_Name_With_Date', 'Date_Extracted']
        df_final = df[column_order]
        
        # Guardar CSV
        df_final.to_csv(new_csv_path, index=False, encoding='utf-8-sig')
        
        print(f"   ✅ CSV guardado exitosamente")
        print(f"   📁 Ruta: {new_csv_path}")
        print(f"   📊 Registros: {len(df_final)}")
        
    except Exception as e:
        print(f"   ❌ Error guardando CSV: {e}")
        return False
    
    return True

# =============================================================================
# FUNCIÓN PRINCIPAL
# =============================================================================

def main():
    """
    Función principal del script.
    """
    print("📋 RENOMBRADO DE IMÁGENES CON FECHAS")
    print("Formato: YYYY_MM_DD_NocciolaAV_###.jpg")
    print("=" * 50)
    
    # Ejecutar proceso
    success = rename_images_with_dates()
    
    if success:
        print(f"\n🎉 ¡PROCESO COMPLETADO EXITOSAMENTE!")
        print("📁 Las imágenes han sido renombradas con fechas")
        print("📄 Se generó el archivo 'change_names_with_dates.csv'")
        print("\n📊 ARCHIVOS GENERADOS:")
        print("   • Imágenes renombradas en formato: YYYY_MM_DD_NocciolaAV_###.jpg")
        print("   • CSV actualizado: change_names_with_dates.csv")
    else:
        print(f"\n❌ El proceso falló. Revisa los errores mostrados arriba.")

# =============================================================================
# PUNTO DE ENTRADA DEL SCRIPT
# =============================================================================

if __name__ == "__main__":
    main()