import { create } from 'zustand';
import { persist } from 'zustand/middleware';
import type { ProgresoEjercicio, ProgresoModulo, Badge, NivelUsuario } from '../types';
import { progresoService } from '../services/api';

interface ProgresoState {
  progresoModulos: ProgresoModulo[];
  badges: Badge[];
  totalPuntuacion: number;
  nivel: NivelUsuario;
  isLoading: boolean;
  error: string | null;
  
  // Actions
  loadProgreso: () => Promise<void>;
  saveProgreso: (ejercicioId: string, puntuacion: number, moduloNumero: number) => Promise<void>;
  getProgresoModulo: (moduloNumero: number) => ProgresoModulo | undefined;
  getEjercicioCompletado: (ejercicioId: string, moduloNumero: number) => boolean;
  getPuntuacionEjercicio: (ejercicioId: string, moduloNumero: number) => number;
  getPorcentajeModulo: (moduloNumero: number, totalEjercicios: number) => number;
  clearError: () => void;
}

export const useProgresoStore = create<ProgresoState>()(
  persist(
    (set, get) => ({
      progresoModulos: [],
      badges: [],
      totalPuntuacion: 0,
      nivel: 'Novato',
      isLoading: false,
      error: null,

      loadProgreso: async () => {
        set({ isLoading: true, error: null });
        try {
          const resumen = await progresoService.getResumen();
          set({
            progresoModulos: resumen.moduloProgreso,
            badges: resumen.badges,
            totalPuntuacion: resumen.totalPuntuacion,
            nivel: resumen.nivel,
            isLoading: false,
          });
        } catch (error: unknown) {
          const message = error instanceof Error ? error.message : 'Error al cargar progreso';
          set({ error: message, isLoading: false });
        }
      },

      saveProgreso: async (ejercicioId: string, puntuacion: number, moduloNumero: number) => {
        set({ isLoading: true, error: null });
        try {
          await progresoService.saveProgreso({
            modulo_numero: moduloNumero,
            ejercicio_id: ejercicioId,
            puntuacion,
            completado: true,
          });
          
          // Update local state
          const { progresoModulos } = get();
          const moduloIndex = progresoModulos.findIndex(m => m.moduloNumero === moduloNumero);
          
          if (moduloIndex >= 0) {
            const nuevoEjercicio: ProgresoEjercicio = {
              ejercicioId,
              completado: true,
              puntuacion,
              fecha: new Date().toISOString(),
            };
            
            const moduloActualizado = { ...progresoModulos[moduloIndex] };
            const ejercicioExistente = moduloActualizado.ejercicios.findIndex(
              e => e.ejercicioId === ejercicioId
            );
            
            if (ejercicioExistente >= 0) {
              moduloActualizado.ejercicios[ejercicioExistente] = nuevoEjercicio;
            } else {
              moduloActualizado.ejercicios.push(nuevoEjercicio);
            }
            
            const nuevosProgresos = [...progresoModulos];
            nuevosProgresos[moduloIndex] = moduloActualizado;
            
            set({ progresoModulos: nuevosProgresos, isLoading: false });
          }
          
          // Reload full progress to get updated badges and level
          await get().loadProgreso();
        } catch (error: unknown) {
          const message = error instanceof Error ? error.message : 'Error al guardar progreso';
          set({ error: message, isLoading: false });
        }
      },

      getProgresoModulo: (moduloNumero: number) => {
        return get().progresoModulos.find(m => m.moduloNumero === moduloNumero);
      },

      getEjercicioCompletado: (ejercicioId: string, moduloNumero: number) => {
        const modulo = get().getProgresoModulo(moduloNumero);
        if (!modulo) return false;
        const ejercicio = modulo.ejercicios.find(e => e.ejercicioId === ejercicioId);
        return ejercicio?.completado || false;
      },

      getPuntuacionEjercicio: (ejercicioId: string, moduloNumero: number) => {
        const modulo = get().getProgresoModulo(moduloNumero);
        if (!modulo) return 0;
        const ejercicio = modulo.ejercicios.find(e => e.ejercicioId === ejercicioId);
        return ejercicio?.puntuacion || 0;
      },

      getPorcentajeModulo: (moduloNumero: number, totalEjercicios: number) => {
        const modulo = get().getProgresoModulo(moduloNumero);
        if (!modulo || totalEjercicios === 0) return 0;
        const completados = modulo.ejercicios.filter(e => e.completado).length;
        return Math.round((completados / totalEjercicios) * 100);
      },

      clearError: () => set({ error: null }),
    }),
    {
      name: 'progreso-storage',
      partialize: (state) => ({
        progresoModulos: state.progresoModulos,
        totalPuntuacion: state.totalPuntuacion,
        nivel: state.nivel,
      }),
    }
  )
);
