import re
import os
import shutil
import logging
from pathlib import Path

# Configuración del logger
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# Variables globales
source_path = [Path("/home/sergio/zx/tosec/all"), Path("/home/sergio/zx/tosec/pokes")]
destination_path = Path("/home/sergio/zx/tosec/final")
opt_print = True
opt_create_dirs = True
opt_split_modern_and_classic = True
last_classic_year = 1993
modern_folder_name = "modern"
classic_folder_name = "classics"

# Variables para almacenar datos de los archivos
paths = []      # Ruta donde se encuentra el fichero
files = []      # Nombre del fichero
names = []      # Nombre del juego
years = []      # Año del juego
companies = []  # Compañía o distribuidora del juego

def remove_destination_folder(destination_path):
    try:
        logging.info(f"Directorio: {destination_path} -> eliminando...")
        shutil.rmtree(destination_path)
        logging.info(f"Directorio: {destination_path} -> eliminado con éxito")
    except OSError as o:
        logging.error(f"Error, {o.strerror}: {destination_path}")

def create_destination_folder(destination_path):
    try:
        os.mkdir(destination_path)
        logging.info(f"Directorio: {destination_path} -> creado con éxito")
    except OSError as error:
        logging.error(f"Error al crear el directorio: {error}")

def get_file_list(source_paths):
    global paths, files
    paths = []
    files = []
    
    for path in source_paths:
        try:
            for file_name in os.listdir(path):
                if os.path.isfile(os.path.join(path, file_name)):  # Comprueba si es un fichero
                    paths.append(path)  # Añade la ruta
                    files.append(file_name)  # Añade el nombre del fichero
                    logging.info(f"Fichero encontrado: {file_name} en {path}")
        except OSError as error:
            logging.error(f"Error al acceder al directorio {path}: {error}")
    
    return paths, files

def extract_game_data():
    global files, names, years, companies
    regex_year = r"\(\d.*?\)"
    regex_company = r"^\(.*?\)"
    
    for file in files:
        # Año
        match = re.search(regex_year, file)  # Busca el año en el nombre del fichero
        if match:
            years.append(match.group())  # Añade el año con los parentesis a la lista
            pos = file.find(years[-1])  # Busca el carácter donde empieza el año
            names.append(file[0:pos].strip())  # Añade como nombre el texto desde el principio hasta el año
            match_company = re.search(regex_company, file[pos + len(years[-1]):])  # Busca la compañía en lo que queda después del año
            if match_company:
                companies.append(match_company.group())
            else:
                companies.append("-")

            # Limpia los paréntesis del año y la compañía
            years[-1] = years[-1][1:5]
            if companies[-1] != "-":
                companies[-1] = companies[-1][1:-1]
        else:
            years.append("0")
            names.append(file)
            companies.append("-")
        
        logging.info(f"Datos extraídos -> Nombre: {names[-1]}, Año: {years[-1]}, Compañía: {companies[-1]}")

def print_results():
    if opt_print:
        for i, item in enumerate(files):
            print(
                "File:    {}\nName:    {}\nYear:    {}\nCompany: {}\n".format(
                    item, names[i], years[i], companies[i]
                )
            )

def first_letter(name):
    if not name or name[0].isdigit():
        return "0-9"
    return name[0].upper()

def safe_int_conversion(value):
    try:
        return int(value)
    except ValueError:
        return "unknown"

def get_modern_and_classic_folder(year):
    year = safe_int_conversion(year)
    
    if year == "unknown":
        return "unknown"
    
    if opt_split_modern_and_classic:
        if year == "none" or year is None or year > last_classic_year:
            return modern_folder_name
        else:
            return classic_folder_name
    else:
        return ""

def copy_files():
    global files, names, years, companies, paths, destination_path, opt_create_dirs
    
    total_files = len(files)
    if opt_create_dirs:
        for i in range(total_files):
            logging.info("({} de {}) {}".format(i + 1, total_files, files[i]))
            game_dir = f"{names[i]} ({years[i]})"
            modern_and_classic_folder = get_modern_and_classic_folder(years[i])
            dst_path = os.path.join(destination_path, modern_and_classic_folder, first_letter(names[i]), game_dir)
            if not os.path.exists(dst_path):
                os.makedirs(dst_path)
                logging.info(f"Directorio creado: {dst_path}")
            src = os.path.join(paths[i], files[i])
            dst = os.path.join(dst_path, files[i])
            shutil.copyfile(src, dst)
            # logging.info(f"Archivo copiado de {src} a {dst}")

def main():
    global destination_path, source_path, opt_print, opt_create_dirs, paths, files

    # Eliminar la carpeta de destino si existe
    remove_destination_folder(destination_path)

    # Crear la carpeta de destino
    create_destination_folder(destination_path)

    # Obtener la lista de archivos desde los directorios de origen
    paths, files = get_file_list(source_path)

    # Extraer los datos del juego
    extract_game_data()

    # Imprimir los resultados
    # print_results()

    # Copiar los archivos
    copy_files()

if __name__ == "__main__":
    main()