import { defineComponent, ref, onMounted, computed } from 'vue'
import { useI18n } from 'vue-i18n'

import { tools } from '../../store/Modules/tools'

import { shared_consts } from '@src/common/shared_vuejs'

import { useUserStore } from '@store/UserStore'
import { useGlobalStore } from '@store/globalStore'
import { useQuasar } from 'quasar'
import { costanti } from '@costanti'
import { useRouter } from 'vue-router'

import { serv_constants } from '@store/Modules/serv_constants'

export default defineComponent({
  name: 'CAITools',
  props: {
  },
  components: {
  },
  setup(props, { emit }) {
    const $q = useQuasar()
    const { t } = useI18n()
    const userStore = useUserStore()
    const globalStore = useGlobalStore()
    const isfinishLoading = computed(() => globalStore.finishLoading)

    const $router = useRouter()

    const options = ref(<any>{})

    const querySel = ref('')

    const contestSysteList = [
      { label: 'Standard', value: '' },
      { label: 'Matematica', value: 'Sei un esperto in Matematica' },
      { label: 'Editoriale', value: 'Sei un esperto in Editoria e scrittura di articoli e blog' },
      { label: 'Programmazione', value: 'Sei un esperto in programmazione' },
    ]
    const modelList = [
      { label: 'DeepSeek', value: 'deepseek-chat' },
    ]

    const outputTypeList = [
      { label: 'Formato Testo', value: 'Ritornami l\'output in formato testo' },
      { label: 'Per Telegram', value: 'Ritornami l\'output formattato per incollarlo sulla chat Telegram, usando delle emoticons in punti chiave e il grassetto (**) nelle parole chiave, usando la sintassi markdown.' },
      { label: 'Formato JSON', value: 'Ritornami l\'output in formato JSON' },
      { label: 'Formato CSV (campi separati da \'|\')', value: 'Ritornami l\'output in formato CSV, con i campi separati da \'|\'' },
    ]

    const tempList = [{ label: 'Temperatura a 0.3', value: 0.3 },
    { label: 'Temperatura a 0.5', value: 0.5 },
    { label: 'Temperatura a 1', value: 1 },
    { label: 'Temperatura a 1.2', value: 1.2 },
    { label: 'Temperatura a 1.5', value: 1.5 },
    ]

    const tokenList = [
      { label: '50 Token', value: 50 },
      { label: '100 Token', value: 100 },
      { label: '200 Token', value: 200 },
      { label: '500 Token', value: 500 },
      { label: '1000 Token', value: 1000 },
      { label: '2500 Token', value: 2500 },
      { label: '4000 Token', value: 4000 },
      { label: '5000 Token', value: 5000 },
      { label: '10000 Token', value: 10000 },
    ]

    const model = ref('deepseek-chat')
    const max_tokens = ref(50)
    const outputType = ref('')
    const temperatura = ref(0.3)
    const stream = ref(false)
    const contestsystem = ref('')

    const inputPrompt = ref('');
    const result = ref('');
    const outputvisibile = ref('');
    const isLoading = ref(false);
    const errorMessage = ref('');
    const finish_reason = ref('');
    const withexplain = ref(false);

    const querylist = ref(<any[]>[])


    const modelLabel = computed(() => {
      const foundModel = modelList.find((item: any) => item.value === model.value);
      return foundModel ? foundModel.label : null;
    })

    function mount() {
      // Mount

      querylist.value = globalStore.getQueryAI()

      model.value = tools.getCookie('AI_MOD', 'deepseek-chat')
      max_tokens.value = tools.getCookie('AI_MT', 50, true)
      withexplain.value = tools.getCookie('AI_WS', '0') === '1'
      outputType.value = tools.getCookie('AI_OT', outputTypeList[0].value)
      temperatura.value = tools.convstrToNum(tools.getCookie('AI_TEM', '0.3'))
      stream.value = tools.getCookie('AI_ST', '0') === '1'
      contestsystem.value = tools.getCookie('AI_CON', '')
      inputPrompt.value = tools.getCookie('AI_PRO', '')

    }

    function getInput() {
      return "Prompt:\n" + inputPrompt.value + '\n\nRisposta:\n'
    }

    async function handleSubmit() {
      isLoading.value = true;
      errorMessage.value = '';
      if (outputvisibile.value) {
        outputvisibile.value += '\n\n'
      }
      outputvisibile.value += getInput();
      result.value = '';
      finish_reason.value = '';


      tools.setCookie('AI_MOD', model.value)
      tools.setCookie('AI_MT', max_tokens.value.toString())
      tools.setCookie('AI_OT', outputType.value)
      tools.setCookie('AI_TEM', temperatura.value.toString())
      tools.setCookie('AI_ST', stream.value ? '1' : '0')
      tools.setCookie('AI_WE', withexplain.value ? '1' : '0')
      tools.setCookie('AI_CON', contestsystem.value)
      tools.setCookie('AI_PRO', inputPrompt.value)

      options.value = {
        model: model.value,
        max_tokens: max_tokens.value,
        temp: temperatura.value,
        stream: stream.value,
        withexplain: withexplain.value,
        outputType: outputType.value,
      };

      try {
        if (options.value.stream) {
          // Modalità streaming
          const response = await globalStore.getQueryDS(inputPrompt.value, options.value);

          console.log('uscita da getQueryDS')

          isLoading.value = false;

          // Leggi il flusso di dati
          const reader = response.data.getReader();
          const decoder = new TextDecoder('utf-8');

          while (true) {
            const { done, value } = await reader.read();
            if (done) break;

            // Decodifica il chunk e gestisci i dati
            const chunk = decoder.decode(value);
            console.log('Received chunk:', chunk); // Log del chunk ricevuto

            const lines = chunk.split('\n\n').filter((line) => line.trim() !== '');

            for (const line of lines) {
              if (line.startsWith('data: ')) {
                const data = JSON.parse(line.slice(6)); // Rimuovi "data: " e parsifica il JSON
                if (data.choice && data.choice.delta && data.choice.delta.content) {
                  result.value += data.choice.delta.content || ''
                  outputvisibile.value += data.choice.delta.content || ''
                }

                /*errorMessage.value = data.error;
                  $q.notify({
                    color: 'negative',
                    icon: 'error',
                    message: 'Errore durante la richiesta',
                    caption: errorMessage.value,
                  });
                  break; // Interrompi il ciclo in caso di errore
                }*/
              } else if (line.startsWith('data: [DONE]')) {
                const data = JSON.parse(line.slice(12)); // Rimuovi "data: " e parsifica il JSON
                if (data.choice && data.choice.finish_reason) {
                  finish_reason.value = data.choice.finish_reason;
                }
                inputPrompt.value = '';

              }
            }


          }
        } else {
          // Modalità non streaming
          const resdata = await globalStore.getQueryDS(inputPrompt.value, options.value);

          if (resdata.code === serv_constants.RIS_CODE_OK) {
            inputPrompt.value = '';
            if (resdata.choice) {
              finish_reason.value = resdata.choice.finish_reason || '';
            }
            if (resdata.choice.message) {
              result.value = resdata.choice.message.content || '';
              outputvisibile.value += result.value
            }
          } else if (resdata.code === serv_constants.RIS_CODE_ERR) {
            errorMessage.value = resdata.error.message || resdata.error;
            $q.notify({
              color: 'negative',
              icon: 'error',
              message: 'Errore durante la richiesta',
              caption: errorMessage.value,
            });
          }

          isLoading.value = false;
        }
      } catch (error) {
        errorMessage.value = error.response?.data?.error || error.message;
        $q.notify({
          color: 'negative',
          icon: 'error',
          message: 'Errore durante la richiesta',
          caption: errorMessage.value,
        });
      }


    }

    const copyToClipboard = () => {
      if (!result.value) return;

      navigator.clipboard.writeText(result.value).then(() => {
        $q.notify({
          message: 'Copiato negli appunti!',
          color: 'positive',
          icon: 'check',
        });
      }).catch(err => {
        console.error('Errore nella copia:', err);
        $q.notify({
          message: 'Errore nella copia!',
          color: 'negative',
          icon: 'error',
        });
      });
    }

    function submitPrompt(event: any) {

      if (inputPrompt.value.trim()) { // Controlla che l'input non sia vuoto
        handleSubmit();        // Inviare la richiesta
      }
    }

    onMounted(mount)

    return {
      t,
      querySel,
      $q,
      globalStore,
      inputPrompt,
      result,
      outputvisibile,
      isLoading,
      errorMessage,
      handleSubmit,
      querylist,
      copyToClipboard,
      max_tokens,
      tokenList,
      modelList,
      tempList,
      stream,
      model,
      contestSysteList,
      contestsystem,
      finish_reason,
      modelLabel,
      withexplain,
      outputType,
      outputTypeList,
      temperatura,
      submitPrompt,
    }
  }
})
