import caldav
from caldav import DAVClient
from caldav import error  # Importar correctamente
import datetime
import locale
import json
import pytz
import os
import logging

# Configurar el registro de logs
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Establecer el locale a español para formatear fechas
try:
    locale.setlocale(locale.LC_TIME, "es_ES.utf8")
except locale.Error:
    logger.error("El locale 'es_ES.utf8' no está disponible en este sistema.")
    exit()

# Ruta al archivo de credenciales
credentials_file = '/home/teraflops/apikeys/icloud'

# Verificar si el archivo existe
if not os.path.isfile(credentials_file):
    logger.error(f"El archivo de credenciales '{credentials_file}' no existe.")
    exit()

# Leer las credenciales del archivo
credentials = {}
with open(credentials_file, 'r') as f:
    for line in f:
        line = line.strip()
        if line and not line.startswith('#'):
            key, value = line.split('=', 1)
            # Remover comillas y espacios
            key = key.strip()
            value = value.strip().strip("'").strip('"')
            credentials[key] = value

# Obtener el Apple ID y la contraseña
APPLE_ID = credentials.get('ICLOUD_APPLE_ID')
APP_PASSWORD = credentials.get('ICLOUD_APP_PASSWORD')

if not APPLE_ID or not APP_PASSWORD:
    logger.error(
        "Las credenciales de Apple no están configuradas correctamente en el archivo.")
    exit()

# Configuración de la zona horaria
timezone = pytz.timezone('Europe/Madrid')  # Cambia esto a tu zona horaria

# Inicializar el cliente con verificación SSL
client = DAVClient(
    url='https://caldav.icloud.com/',
    username=APPLE_ID,
    password=APP_PASSWORD,
    # ssl_verify_cert=True  # Asegúrate de que la verificación SSL esté habilitada
)

# Obtener el principal (usuario de iCloud)
principal = client.principal()

# Listar todos los calendarios disponibles
calendars = principal.calendars()

# Mostrar los nombres de los calendarios disponibles
logger.info("Calendarios disponibles:")
for calendar in calendars:
    logger.info(f"- '{calendar.name}'")

# Definir los nombres de los calendarios deseados
DESIRED_CALENDARS = ["Trabajo", "Recordatorios ⚠️"]

# Inicializar una lista para los calendarios seleccionados
selected_calendars = []

# Iterar a través de los calendarios para encontrar los deseados
for calendar in calendars:
    for desired_name in DESIRED_CALENDARS:
        if calendar.name.strip().lower() == desired_name.strip().lower():
            selected_calendars.append(calendar)
            logger.info(f"Calendario seleccionado: '{calendar.name}'")
            break  # Salimos del bucle interno una vez que encontramos una coincidencia

# Verificar si se encontraron los calendarios deseados
if not selected_calendars:
    logger.error(f"No se encontraron los calendarios especificados: {
                 ', '.join(DESIRED_CALENDARS)}")
    exit()

# Definir el rango de tiempo: ahora hasta 7 días después
now = datetime.datetime.now(timezone)
in_7_days = now + datetime.timedelta(days=7)

# Inicializar una lista para todos los eventos
all_events = []

# Obtener eventos de cada calendario seleccionado utilizando calendar.search
for calendar in selected_calendars:
    try:
        events = calendar.search(
            start=now,
            end=in_7_days,
            event=True,
            expand=True
        )
        logger.info(f"Eventos obtenidos del calendario '{
                    calendar.name}': {len(events)}")
        # Agregar una tupla con el evento y el nombre del calendario
        for event in events:
            all_events.append((event, calendar.name))
    except error.CalDAVError as e:
        logger.error(f"Error al obtener eventos del calendario '{
                     calendar.name}': {e}")
        continue

# Función clave para ordenar los eventos


def sort_key(event_tuple):
    event = event_tuple[0]
    dtstart = event.instance.vevent.dtstart.value
    if isinstance(dtstart, datetime.date) and not isinstance(dtstart, datetime.datetime):
        # Convertir datetime.date a datetime.datetime a medianoche
        dtstart = datetime.datetime.combine(
            dtstart, datetime.time(0, 0), tzinfo=timezone)
    elif dtstart.tzinfo is None:
        # Si dtstart es datetime pero sin información de zona horaria
        dtstart = timezone.localize(dtstart)
    else:
        # Asegurarse de que dtstart esté en la zona horaria correcta
        dtstart = dtstart.astimezone(timezone)
    return dtstart


# Ordenar los eventos usando la función sort_key
all_events.sort(key=sort_key)

# Preparar eventos para el tooltip con formato de fecha en español
event_list = []
if all_events:
    for event, calendar_name in all_events:
        try:
            event_details = event.vobject_instance
            vevent = event_details.vevent

            # Título del evento
            summary = vevent.summary.value if hasattr(
                vevent, 'summary') else 'Sin título'

            # Fecha y hora de inicio
            dtstart = vevent.dtstart.value if hasattr(
                vevent, 'dtstart') else None

            # Fecha y hora de fin
            dtend = vevent.dtend.value if hasattr(vevent, 'dtend') else None

            # Todo el día
            all_day = isinstance(dtstart, datetime.date) and not isinstance(
                dtstart, datetime.datetime)

            # Formatear fecha y hora de inicio
            if dtstart:
                if all_day:
                    dtstart_str = dtstart.strftime(
                        '%A %d de %B') + " (Todo el día)"
                else:
                    if dtstart.tzinfo is None:
                        dtstart = timezone.localize(dtstart)
                    else:
                        dtstart = dtstart.astimezone(timezone)
                    dtstart_str = dtstart.strftime('%A %d de %B %H:%M')
            else:
                dtstart_str = ''

            # Formatear fecha y hora de fin
            if dtend:
                if all_day:
                    dtend_str = dtend.strftime(
                        '%A %d de %B') + " (Todo el día)"
                else:
                    if dtend.tzinfo is None:
                        dtend = timezone.localize(dtend)
                    else:
                        dtend = dtend.astimezone(timezone)
                    dtend_str = dtend.strftime('%A %d de %B %H:%M')
            else:
                dtend_str = ''

            # Construir el texto del evento
            event_text = f"📅 {summary} ({calendar_name})"
            event_text += f"\n  🕒 Inicio: {dtstart_str}" if dtstart_str else ''
            event_text += f"\n  🕔 Fin: {dtend_str}" if dtend_str else ''
            event_text += "\n  📆 Todo el día: Sí" if all_day else ''

            event_list.append(event_text)

        except Exception as e:
            logger.error(f"Error al procesar el evento: {e}")
            continue
else:
    event_list.append("No hay eventos en los próximos 7 días")

# **Modificar la creación del JSON de salida para Waybar**
# 1. Mostrar la fecha actual en español en la barra
# 2. Si hay eventos, añadir un icono o número junto a la fecha

# Definir el icono que se mostrará si hay eventos
EVENT_ICON = "󱢞"  # Puedes cambiar este icono por otro que prefieras

# Calcular el número de eventos próximos
event_count = len(all_events)

# Construir el texto para la barra
if event_count > 0:
    # Puedes optar por mostrar solo el número, el icono, o ambos
    # Ejemplos:
    # Solo número: text = "Fecha | 3"
    # Solo icono: text = "Fecha 📅"
    # Icono y número: text = "Fecha 📅3"

    # Aquí mostramos el icono y el número
    text = f"{now.strftime('%A %d de %B %H:%M')} {EVENT_ICON}{event_count}"
else:
    text = now.strftime('%A %d de %B %H:%M')

# Crear el JSON de salida para Waybar con tooltip en español
output = {
    "text": text,  # Texto modificado
    "tooltip": "\n\n".join(event_list),
    "class": "calendar"
}

# Salida JSON
print(json.dumps(output))
