import { blobToBase64, convertirWavAMP3, emptyObject, useVariables } from "../..";
import { useState } from "react";
import { useEffect } from "react";
import { createContext } from "react";
import { useContext } from "react";
import { useAudioRecorder } from '@sarafhbk/react-audio-recorder'
/**
* Componente que permite grabar un audio desde el dispositivo
* @name Reactor.Components.Input.VoiceRecorder
* @param {string} name
* name del control y de la variable donde se van a guardar los datos del control
* @param {string} [default_value = ""] Url data con el contenido de un audio que inicie por defecto
* @param {string} [context = "global"] Contexto donde se encuentra la variable
* @param {BooleanString} [use_change = "false"]
* establece si envia el evento change al generar el audio
* @param {string?} max_seconds
* Cantidad de segundos que durara como máximo la grabación
* Se puede convinar con el uso del componente voice_recorder_auto_submit
* @class
* @example
<p>Ejemplo de VoiceRecorder con submit manual</p>
<form action="EjemplosVoiceRecorder" to="EjemplosVoiceRecorder" data='{}'>
<voice_recorder name="audio_prompt" context="gpt" use_change="true">
<voice_recorder_start>
<div class="btn btn-primary" href="#">Grabar</div>
</voice_recorder_start>
<voice_recorder_stop>
<div class="btn btn-secondary" href="#">Grabando</div>
</voice_recorder_stop>
<stamp variable="audio_prompt.recordingTime" context="gpt"></stamp>
<if variable="audio_prompt.urlData" context="gpt">
<condition value="" operator="!=" type="text">
<audio controls var-src="audio_prompt.urlData" context="gpt"></audio>
<br/>
<voice_recorder_delete>
<div class="btn btn-warning" href="#">Cancelar audio</div>
</voice_recorder_delete>
</condition>
<condition value="" operator="=" type="text">
no hay contenido
</condition>
</if>
</voice_recorder>
<input type="submit" value="enviar" />
</form>
<p>Ejemplo de VoiceRecorder con submit automatico</p>
<form action="EjemplosVoiceRecorder" to="EjemplosVoiceRecorder" data='{}'>
<voice_recorder name="audio_prompt2" context="gpt" use_change="true">
<voice_recorder_auto_submit></voice_recorder_auto_submit>
<voice_recorder_start>
<div class="btn btn-primary" href="#">Grabar</div>
</voice_recorder_start>
<voice_recorder_stop>
<div class="btn btn-secondary" href="#">Grabando</div>
</voice_recorder_stop>
<p><stamp variable="audio_prompt2.recordingTime" context="gpt"></stamp></p>
</voice_recorder>
</form>
<p>Ejemplo de VoiceRecorder con submit automatico y tiempo maximo de grabacion</p>
<form action="EjemplosVoiceRecorder" to="EjemplosVoiceRecorder" data='{}'>
<voice_recorder name="audio_prompt3" context="gpt" use_change="true" max_seconds="10">
<voice_recorder_auto_submit></voice_recorder_auto_submit>
<voice_recorder_start>
<div class="btn btn-primary" href="#">Grabar</div>
</voice_recorder_start>
<voice_recorder_stop>
<div class="btn btn-secondary" href="#">Grabando</div>
</voice_recorder_stop>
<p><stamp variable="audio_prompt3.recordingTime" context="gpt"></stamp></p>
<p><stamp variable="audio_prompt3.recordingTimeRemaining" context="gpt"></stamp></p>
</voice_recorder>
</form>
*/
export const VoiceRecorder = ({default_value = "", name, context = "global", children, use_change = "false", max_seconds}) => {
const variables = useVariables({variable: name, context});
const [state, setState] = useState(() => ({urlData: default_value, isPaused: false, isRecording: false, recordingTime: "", recordingTimeRemaining: ""}));
const recorderControls = useAudioRecorder();
const { status, startRecording, stopRecording } = recorderControls;
const isPaused = status === "paused";
const isRecording = status === "recording";
const timer = recorderControls.timer;
const recordingTime = isRecording ? new Date(timer * 1000).toISOString().substr(11, 8) : "";
const recordingBlob = recorderControls.audioResult;
const maxSeconds = max_seconds ? parseInt(max_seconds) : 0;
const remaining = maxSeconds - timer;
const recordingTimeRemaining = (isRecording && remaining >= 0) ? new Date((remaining) * 1000).toISOString().substr(11, 8) : ""
useEffect(() => {
setState(state => ({...state, isPaused, isRecording, recordingTime, status, recordingTimeRemaining}))
}, [isPaused, isRecording, recordingTime, status, recordingTimeRemaining])
useEffect(() => {
variables.setData(state);
}, [state])
useEffect(() => {
if(!isRecording && !!recordingBlob){
fetch(recordingBlob).then(response => {
response.blob().then(result => {
blobToBase64(result).then(base64 => {
setState(state => ({...state, urlData: base64}))
})
})
})
}
}, [isRecording, recordingBlob])
useEffect(() => {
if(isRecording && maxSeconds > 0 && remaining < 0){
stopRecording();
}
}, [isRecording, remaining, maxSeconds])
const deleteData = () => {
setState(state => ({...state, urlData: ""}))
}
const handleStopRecording = () => {
isRecording && stopRecording();
}
return (
<VoiceRecorderContext.Provider value={{state, startRecording, stopRecording: handleStopRecording, deleteData}}>
<input type="hidden" name={name} value={state.urlData} use_change={use_change}/>
{children}
</VoiceRecorderContext.Provider>
);
}
const VoiceRecorderContext = createContext({
state: {urlData: "", isPaused: false, isRecording: false, recordingTime: "", recordingTimeRemaining: ""},
startRecording: () => {},
stopRecording: () => {},
togglePauseResume: () => {},
deleteData: () => {},
});
export const useVoiceRecorderContext = () => useContext(VoiceRecorderContext);