{"version":3,"sources":["../src/lib/ScormProvider.tsx","../src/lib/withScorm.tsx"],"names":["React","createContext","useEffect","useState","useCallback","SCORM","debug","ScoContext","formatSessionTime","__name","milliseconds","totalSeconds","hours","minutes","seconds","ScormProvider","children","version","isDebug","apiConnected","setApiConnected","learnerName","setLearnerName","learnerID","setLearnerID","completionStatus","setCompletionStatus","suspendData","setSuspendDataState","scormVersion","setScormVersion","createScormAPIConnection","closeScormAPIConnection","learner","status","setSuspendData","commitData","exitMode","success","e","error","getSuspendData","data","parsedData","locationData","score","sessionTime","commitSuccess","savedData","clearSuspendData","setStatus","setScore","saveResult","set","key","value","get","useScorm","context","ScormProvider_default","withScorm","WrappedComponent","props","withScorm_default"],"mappings":"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","sourcesContent":["import React, { createContext, useEffect, useState, useCallback, ReactNode } from \"react\";\nimport { SCORM, debug } from \"pipwerks-scorm-api-wrapper\";\nimport { Score } from \".\";\nimport { IScormContextProps } from \"@/@types/scorm-context-props\";\n\nexport const ScoContext = createContext<IScormContextProps | undefined>(undefined);\n\ninterface ScormProviderProps {\n  children: ReactNode;\n  version?: \"1.2\" | \"2004\";\n  debug?: boolean;\n}\n\nconst formatSessionTime = (milliseconds: number): string => {\n  const totalSeconds = Math.floor(milliseconds / 1000);\n  const hours = Math.floor(totalSeconds / 3600);\n  const minutes = Math.floor((totalSeconds % 3600) / 60);\n  const seconds = totalSeconds % 60;\n\n  return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}.00`;\n};\n\nconst ScormProvider: React.FC<ScormProviderProps> = ({ children, version, debug: isDebug }) => {\n  const [apiConnected, setApiConnected] = useState(false);\n  const [learnerName, setLearnerName] = useState(\"unknown\");\n  const [learnerID, setLearnerID] = useState(\"unknown\");\n  const [completionStatus, setCompletionStatus] = useState(\"unknown\");\n  const [suspendData, setSuspendDataState] = useState<Record<string, any>>({});\n  const [scormVersion, setScormVersion] = useState<string>(\"\");\n\n  useEffect(() => {\n    createScormAPIConnection();\n    window.addEventListener(\"beforeunload\", closeScormAPIConnection);\n    return () => {\n      closeScormAPIConnection();\n      window.removeEventListener(\"beforeunload\", closeScormAPIConnection);\n    };\n  }, []);\n\n  const createScormAPIConnection = useCallback(() => {\n    if (apiConnected) return;\n\n    if (version) SCORM.version = version;\n    if (typeof isDebug === \"boolean\") debug.isActive = isDebug;\n\n    if (SCORM.init()) {\n      const version = SCORM.version;\n      const learner = version === \"1.2\" ? SCORM.get(\"cmi.core.student_name\") : SCORM.get(\"cmi.learner_name\");\n      const learnerID = version === \"1.2\" ? SCORM.get(\"cmi.core.student_id\") : SCORM.get(\"cmi.learner_id\");\n      const status = SCORM.status(\"get\");\n\n      setApiConnected(true);\n      setLearnerName(learner || \"unknown\");\n      setLearnerID(learnerID || \"unknown\");\n      setCompletionStatus(status || \"unknown\");\n      setScormVersion(version);\n      // getSuspendData();\n    } else {\n      console.error(\"ScormProvider init error: could not create the SCORM API connection\");\n    }\n  }, [apiConnected, version, isDebug]);\n\n  const closeScormAPIConnection = useCallback(() => {\n    if (!apiConnected) return;\n\n    setSuspendData();\n    SCORM.status(\"set\", completionStatus);\n    SCORM.save();\n\n    if (SCORM.quit()) {\n      setApiConnected(false);\n      setLearnerName(\"unknown\");\n      setCompletionStatus(\"unknown\");\n      setSuspendDataState({});\n      setScormVersion(\"\");\n    } else {\n      console.error(\"ScormProvider error: could not close the API connection\");\n    }\n  }, [apiConnected, completionStatus]);\n\n  /**\n  * @description Saves all current student progress to the LMS without ending the session (LMSCommit)\n  * @example\n  * commitData();\n  * @returns {boolean} A promise that resolves with the result of the save operation\n  * @throws {Error} If the SCORM API is not connected\n  */\n  const commitData = useCallback((): boolean => {\n    if (!apiConnected) {\n      throw new Error(\"SCORM API não conectada\");\n    }\n\n    try {\n      // 1. Garantir que dados críticos estejam definidos\n      const exitMode = SCORM.get(\"cmi.core.exit\");\n      if (!exitMode || exitMode !== \"suspend\") {\n        SCORM.set(\"cmi.core.exit\", \"suspend\");\n      }\n\n      // 2. Tentar commit usando diferentes métodos\n      let success = false;\n\n      // Método 1: Função direta do provedor\n      if (typeof SCORM.save === \"function\") {\n        success = SCORM.save() !== \"false\";\n      }\n\n      // Método 2: LMSCommit direto (mais confiável em alguns LMS)\n      if (!success && SCORM.version === \"1.2\") {\n        try {\n          // @ts-ignore - Acesso direto à API SCORM\n          success = SCORM.API.LMSCommit(\"\") !== \"false\";\n        } catch (e) {\n          console.warn(\"Erro ao tentar LMSCommit direto:\", e);\n        }\n      }\n\n      // 3. Verificar se o commit funcionou\n      const suspendData = SCORM.get(\"cmi.suspend_data\");\n      if (!suspendData || suspendData === \"{}\") {\n        console.warn(\"Commit não persistiu dados em suspend_data\");\n      }\n\n      return success;\n    } catch (error) {\n      console.error(\"Erro no commit:\", error);\n      return false;\n    }\n  }, [apiConnected]);\n\n  const getSuspendData = useCallback(() => {\n    if (!apiConnected) {\n      throw new Error(\"SCORM API não conectada\");\n    }\n\n    try {\n      const data = SCORM.get(\"cmi.suspend_data\");\n      let parsedData = {};\n\n      if (data && data !== \"{}\") {\n        try {\n          parsedData = JSON.parse(data);\n          console.log(\"Dados recuperados de suspend_data com sucesso\");\n        } catch (e) {\n          console.warn(\"Erro ao processar dados de suspend_data:\", e);\n        }\n      } else {\n        console.warn(\"Nenhum dado encontrado em suspend_data\");\n\n        const locationData = SCORM.get(\"cmi.core.lesson_location\");\n        if (locationData && locationData.includes(\"activityId=\")) {\n          console.log(\"Encontrado identificador em lesson_location:\", locationData);\n        }\n      }\n\n      const status = SCORM.get(\"cmi.core.lesson_status\");\n      if (status === \"completed\" || status === \"passed\") {\n        console.log(\"Atividade já marcada como concluída no LMS\");\n\n        const score = SCORM.get(\"cmi.core.score.raw\");\n        if (score) {\n          console.log(\"Pontuação recuperada:\", score);\n        }\n      }\n\n      setSuspendDataState(parsedData);\n      return true;\n    } catch (error) {\n      console.error(\"Erro ao carregar suspend_data:\", error);\n      return false;\n    }\n  }, [apiConnected]);\n\n  const setSuspendData = useCallback(() => {\n    if (!apiConnected) {\n      console.warn(\"SCORM API não conectada, impossível salvar dados\");\n      return false;\n    }\n\n    try {\n      SCORM.set(\"cmi.suspend_data\", JSON.stringify(suspendData));\n\n      const locationData = `activityId=${Object.keys(suspendData).join(',')}&ts=${Date.now()}`;\n      SCORM.set(\"cmi.core.lesson_location\", locationData);\n\n      SCORM.set(\"cmi.core.exit\", \"suspend\");\n\n      const sessionTime = formatSessionTime(30 * 60 * 1000);\n      SCORM.set(\"cmi.core.session_time\", sessionTime);\n\n      const status = SCORM.get(\"cmi.core.lesson_status\");\n      if (status !== \"completed\" && status !== \"passed\") {\n        SCORM.set(\"cmi.core.lesson_status\", \"incomplete\");\n      }\n\n      const commitSuccess = commitData();\n\n      const savedData = SCORM.get(\"cmi.suspend_data\");\n      if (!savedData || savedData === \"{}\") {\n        console.warn(\"Dados não foram persistidos corretamente no suspend_data\");\n        return false;\n      }\n\n      return commitSuccess;\n    } catch (error) {\n      console.error(\"Erro ao salvar suspend_data:\", error);\n      return false;\n    }\n  }, [apiConnected, suspendData, commitData]);\n\n  const clearSuspendData = useCallback(() => setSuspendDataState({}), []);\n\n  const setStatus = useCallback((status: string) => {\n    if (!apiConnected) return;\n    setCompletionStatus(status);\n    SCORM.status(\"set\", status);\n  }, [apiConnected]);\n\n  const setScore = useCallback(async (score: Score): Promise<any> => {\n    if (!apiConnected) {\n      return Promise.reject(new Error(\"SCORM API not connected\"));\n    }\n\n    try {\n      SCORM.set(\"cmi.score.raw\", score.value);\n\n      if (scormVersion === \"2004\") {\n        SCORM.set(\"cmi.score.min\", score.min);\n        SCORM.set(\"cmi.score.max\", score.max);\n      } else if (scormVersion === \"1.2\") {\n        SCORM.set(\"cmi.core.score.min\", score.min);\n        SCORM.set(\"cmi.core.score.max\", score.max);\n      }\n\n      if (score.status && score.status !== \"0\") {\n        setStatus(score.status);\n      }\n\n      const saveResult = SCORM.save();\n\n      return Promise.resolve({\n        success: true,\n        saveResult,\n        score\n      });\n    } catch (error) {\n      return Promise.reject(error);\n    }\n  }, [apiConnected, scormVersion, setStatus]);\n\n  const set = useCallback((key: string, value: any) => {\n    if (!apiConnected) return;\n    SCORM.set(key, value);\n  }, [apiConnected]);\n\n  const get = useCallback((key: string) => {\n    if (!apiConnected) return null;\n    return SCORM.get(key);\n  }, [apiConnected]);\n\n  return (\n    <ScoContext.Provider\n      value={{\n        apiConnected,\n        learnerName,\n        learnerID,\n        completionStatus,\n        suspendData,\n        scormVersion,\n        getSuspendData,\n\t\t\t\tsetSuspendData,\n        clearSuspendData,\n        setStatus,\n        setScore,\n        set,\n        get,\n        commitData,\n      }}\n    >\n      {children}\n    </ScoContext.Provider>\n  );\n};\n\nexport const useScorm = (): IScormContextProps => {\n  const context = React.useContext(ScoContext);\n  if (!context) {\n    throw new Error(\"useScorm must be used within a ScormProvider\");\n  }\n  return context;\n};\n\nexport default ScormProvider;\n","import React from 'react';\nimport { ScoContext } from './ScormProvider';\n\nfunction withScorm() {\n\n  return function(WrappedComponent) {\n\n    const WithScorm = function(props) {\n      return (\n        <ScoContext.Consumer>\n          {value => <WrappedComponent {...props} sco={value} />}\n        </ScoContext.Consumer>\n      )\n    }\n\n    return WithScorm;\n  }\n}\n\nexport default withScorm;\n"]}