import React, { createContext, useContext, useState, useCallback, useEffect } from 'react';
import PropTypes from 'prop-types';
import { letramentoEventBus, LETRAMENTO_EVENTS } from '../utils/letramentoEvents';
import { saveProgress } from '../services/letramentoStorage';

export const ATIVIDADE_STATES = {
  IDLE:      'idle',
  STARTED:   'started',
  RUNNING:   'running',
  SUCCESS:   'success',
  FAILURE:   'failure',
  COMPLETED: 'completed',
};

const LetramentoStateContext = createContext(null);

export function LetramentoStateProvider({ children, atividadeId }) {
  const [status,      setStatus]      = useState(ATIVIDADE_STATES.IDLE);
  const [attempts,    setAttempts]    = useState(0);
  const [score,       setScore]       = useState(null);
  const [currentStep, setCurrentStep] = useState(0);

  const persist = useCallback((update) => {
    if (!atividadeId) return;
    saveProgress(atividadeId, update);
  }, [atividadeId]);

  useEffect(() => {
    const onStarted = ({ detail }) => {
      setStatus(ATIVIDADE_STATES.STARTED);
      persist({ status: ATIVIDADE_STATES.STARTED, startedAt: new Date().toISOString(), ...detail });
    };

    const onRunning = ({ detail }) => {
      setStatus(ATIVIDADE_STATES.RUNNING);
      if (detail?.step) setCurrentStep(detail.step);
      persist({ status: ATIVIDADE_STATES.RUNNING, ...detail });
    };

    const onSuccess = ({ detail }) => {
      setStatus(ATIVIDADE_STATES.SUCCESS);
      setScore(detail?.score ?? null);
      persist({ status: ATIVIDADE_STATES.SUCCESS, score: detail?.score ?? null, ...detail });
    };

    const onFailure = ({ detail }) => {
      setAttempts((a) => {
        const next = a + 1;
        persist({ status: ATIVIDADE_STATES.FAILURE, attempts: next, ...detail });
        return next;
      });
      setStatus(ATIVIDADE_STATES.FAILURE);
    };

    const onCompleted = ({ detail }) => {
      setStatus(ATIVIDADE_STATES.COMPLETED);
      persist({ status: ATIVIDADE_STATES.COMPLETED, completedAt: new Date().toISOString(), ...detail });
    };

    letramentoEventBus.addEventListener(LETRAMENTO_EVENTS.STARTED,   onStarted);
    letramentoEventBus.addEventListener(LETRAMENTO_EVENTS.RUNNING,   onRunning);
    letramentoEventBus.addEventListener(LETRAMENTO_EVENTS.SUCCESS,   onSuccess);
    letramentoEventBus.addEventListener(LETRAMENTO_EVENTS.FAILURE,   onFailure);
    letramentoEventBus.addEventListener(LETRAMENTO_EVENTS.COMPLETED, onCompleted);

    return () => {
      letramentoEventBus.removeEventListener(LETRAMENTO_EVENTS.STARTED,   onStarted);
      letramentoEventBus.removeEventListener(LETRAMENTO_EVENTS.RUNNING,   onRunning);
      letramentoEventBus.removeEventListener(LETRAMENTO_EVENTS.SUCCESS,   onSuccess);
      letramentoEventBus.removeEventListener(LETRAMENTO_EVENTS.FAILURE,   onFailure);
      letramentoEventBus.removeEventListener(LETRAMENTO_EVENTS.COMPLETED, onCompleted);
    };
  }, [atividadeId, persist]);

  const reset = useCallback(() => {
    setStatus(ATIVIDADE_STATES.IDLE);
    setScore(null);
    setCurrentStep(0);
  }, []);

  return (
    <LetramentoStateContext.Provider value={{ status, attempts, score, currentStep, reset, atividadeId }}>
      {children}
    </LetramentoStateContext.Provider>
  );
}

LetramentoStateProvider.propTypes = {
  children:    PropTypes.node.isRequired,
  atividadeId: PropTypes.string.isRequired,
};

export function useLetramentoState() {
  const ctx = useContext(LetramentoStateContext);
  if (!ctx) throw new Error('useLetramentoState deve ser usado dentro de LetramentoStateProvider');
  return ctx;
}
