@section('title', 'Ujian Kecemasan')
{{-- @section('body_status_overflow', 'overflow: hidden;') --}}
@section('main_style', 'min-height: 100vh;')
@extends('user.layouts.test_layout.index')
@section('content')
  <div class="container-fluid p-0 d-flex flex-column" style="min-height: 100vh">
    <nav class="navbar navbar-expand-lg bg-body-tertiary px-2">
      <div class="container-fluid">
        <a class="navbar-brand" href="#">Smart Anxiety</a>
        <div class="collapse navbar-collapse justify-content-between" id="navbarSupportedContent">
          <ul class="navbar-nav me-auto mb-2 mb-lg-0"></ul>
          <div class="d-flex col-md-4">
            <div class="col-md-4 d-flex justify-content-center align-items-center">
              Time Left: <span id="time_left"></span>
            </div>
            <div class="col-md-4 d-flex justify-content-center align-items-center">
              <span id="bg_status_tobii" class="rounded bg-warning d-block mx-2" style="width: 10px; aspect-ratio: 1/1;"></span>Status Tobii
            </div>
            <div class="col-md-4 d-flex justify-content-center align-items-center">
              <button id="fullscreen_btn" data-status="fullscreen" class="btn btn-sm btn-outline-secondary" onclick="openFullscreen()">Fullscreen</button>
            </div>
          </div>
        </div>
      </div>
    </nav>

    <div class="d-flex flex-grow-1 container-fluid">
      <div class="row flex-grow-1">
        <div class="col-md-9 border-end">
          <div class="row justify-content-center flex-column p-4">
            <div class="col-md-12 border-bottom fs-4 fw-bold p-2">Soal</div>
            <div class="col-md-12 p-2 d-none" id="id_question" style="text-align: justify"></div>
            <div class="col-md-12 p-2" id="text_question" style="text-align: justify"></div>
            <div class="col-md-12" id="answer_field">
              <div class="fs-4 fw-bold p-2">Jawaban:</div>
            </div>
          </div>
        </div>
        <div class="col-md-3">
          <div class="row p-3" id="navigation_field">
            <div class="col-md-12 border-bottom fs-4 fw-bold p-2 mb-3">Navigasi Soal</div>
          </div>
          <div class="row p-3">
            <div class="col-md-12">
              <div class="card">
                <div class="card-body">
                  <h5 class="card-title">Instruksi</h5>
                  <p class="card-text">Silahkan baca soal dengan teliti dan pilih jawaban yang paling tepat.</p>
                  <div class="card-text d-flex align-items-center">
                    <span class="col-md-1 bg-light-subtle border rounded p-0 m-1" style="aspect-ratio: 1/1.5;"></span>
                    <span>adalah tanda bahwa jawaban BELUM diisi.</span>
                  </div>
                  <div class="card-text d-flex align-items-center">
                    <span class="col-md-1 bg-secondary-subtle border rounded p-0 m-1" style="aspect-ratio: 1/1.5;"></span>
                    <span>adalah tanda bahwa jawaban SUDAH diisi.</span>
                  </div>
                  <div class="card-text d-flex align-items-center">
                    <span class="col-md-1 bg-info border rounded p-0 m-1 text-white" style="aspect-ratio: 1/1.5;"></span>
                    <span>adalah tanda bahwa anda sedang membaca/menjawab soal ini.</span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
@endsection

@section('script')
  <script>
    let ws = null;
    let reconnectDelay = 1000;
    let maxReconnectDelay = 10000;
    const SESSION_ID = '{{ $data_session->id_test_sessions }}';
    const TOKEN_SESSION = '{{ $data_session->token_session }}';
    let UNIX_END_TIME = null;
    let QUESTION_INDEX = 1;
    let QUESTION_ID = null;
    let CURRENT_BTN = null;
    let CAPTION_BTN = null;

    function startWebsocket() {
      console.log("Connecting to WebSocket...");
      ws = new WebSocket('{{ env("WEBSOCKET_URL") }}');
      ws.onopen = () => {
        console.log("Connected to WebSocket");
        ws.send(JSON.stringify({
          type: "register",
          session_id: SESSION_ID,
          token_session: TOKEN_SESSION,
          role: "web"
        }));

        document.addEventListener('fullscreenchange', checkFullscreen);

        ws.send(JSON.stringify({
          type: "update_status",
          status_sessions: true,
          session_id: SESSION_ID
        }));

        searchingTobiiDevice()
        checkFullscreen();
        getTimeLeft();
        setInterval(updateTimeLeft, 1000);
        getNavigationField();
        setCurrentNavigation();
        fetchQuestion(QUESTION_INDEX);
      };

      ws.onmessage = (event) => {
        const data = JSON.parse(event.data);

        if(data.type === 'reset_start_tobii') {
          startTobii();
        }

        if(data.type === 'status_tobii_device') {
          if(data.status) {
            // console.log('Tobii device is connected');
            // document.getElementById('status_tobii_device').innerText = 'Connected';
            document.getElementById('bg_status_tobii').classList.remove('bg-warning');
            document.getElementById('bg_status_tobii').classList.remove('bg-danger');
            document.getElementById('bg_status_tobii').classList.add('bg-success');
          } else {
            console.log('Tobii device is not connected');
            searchingTobiiDevice();
            // document.getElementById('status_tobii_device').innerText = 'Not Connected';
            document.getElementById('bg_status_tobii').classList.remove('bg-success');
            document.getElementById('bg_status_tobii').classList.remove('bg-warning');
            document.getElementById('bg_status_tobii').classList.add('bg-danger');
          }
        }
      };

      ws.onerror = function (error) {
        console.log("WebSocket error");
      };

      ws.onclose = function () {
        setTimeout(() => {
          reconnectDelay = Math.min(
            reconnectDelay * 2,
            maxReconnectDelay
          );
          console.log("Disconnected from WebSocket. Retrying in " + reconnectDelay + " ms...");
          document.getElementById('bg_status_tobii').classList.remove('bg-success');
          document.getElementById('bg_status_tobii').classList.remove('bg-warning');
          document.getElementById('bg_status_tobii').classList.add('bg-danger');
          startWebsocket();
        }, reconnectDelay);
      };
    }

    async function searchingTobiiDevice() {
      try {
        console.log('Searching for tobii...');
        const response = await fetch('{{ env('TOBII_API_URL') }}', {
            method: "POST",
            headers: {
              "Content-Type": "application/json"
            },
            body: JSON.stringify({
              session_id: SESSION_ID,
              token: TOKEN_SESSION,
              url: "{{ env('WEBSOCKET_URL') }}"
            })
          }
        );
        if (!response.ok) {
          console.error('Failed to get tobii device, retrying...');
          setTimeout(5000);
          searchingTobiiDevice();
          return;
        }
        const data = await response.json();
        if(data.session_id == SESSION_ID && data.token == TOKEN_SESSION) {
          // tobiiConnectedStatus = true;
          startTobii();
          document.getElementById('bg_status_tobii').classList.remove('bg-success');
          document.getElementById('bg_status_tobii').classList.remove('bg-warning');
          document.getElementById('bg_status_tobii').classList.add('bg-danger');
          console.log('Done searching...');
        }
      } catch (error) {
        console.error('Error getting Tobii device:', error);
        document.getElementById('bg_status_tobii').classList.remove('bg-success');
        document.getElementById('bg_status_tobii').classList.remove('bg-warning');
        document.getElementById('bg_status_tobii').classList.add('bg-danger');
        setTimeout(5000);
        searchingTobiiDevice();
      }
    }

    function changeQuestion(num) {
      Swal.showLoading();

      let xhttp = new XMLHttpRequest();
      let the_answer = null;
      let token = document.getElementById('_token').getAttribute('value');
      let formData = new FormData();

      if(QUESTION_INDEX == num) {
        console.log('same question');
        Swal.close();
        return;
      }

      document.getElementsByName('jawaban_final').forEach(element => {
        if (element.checked) {
          the_answer = {
            key: element.id.split('_')[1],
          };
        }
      });
      if(the_answer) {
        formData.append('jawaban_final', the_answer.key);
        formData.append('_token', token);
        formData.append('question', num);
        formData.append('id_question', QUESTION_ID);
        formData.append('session_id', SESSION_ID);
        xhttp.open("POST", "{{ route('ujian.store') }}", true);
        xhttp.send(formData);
      }
      // stopTobii();
      QUESTION_INDEX = num;
      getNavigationField();
      fetchQuestion(QUESTION_INDEX);
    }

    function setCurrentNavigation() {
      $('#nomor_' + QUESTION_INDEX).removeClass('bg-light-subtle');
      $('#nomor_' + QUESTION_INDEX).removeClass('bg-secondary-subtle');
      $('#nomor_' + QUESTION_INDEX).addClass('bg-info');
    }

    function fetchQuestion(question_index) {
      let xhttp = new XMLHttpRequest();

      xhttp.onreadystatechange = function() {
        if(this.readyState == 4 && this.status == 200) {
          let response = JSON.parse(this.responseText);
          if(response.status) {
            $('#text_question').html(response.data.pertanyaan);
            QUESTION_ID = response.data.id_soal;
            getCurrentAnswer(response.data.id_soal);
          } else {
            Swal.fire({
              title: 'Error',
              icon: 'error',
              text: 'Terjadi kesalahan saat mengambil soal. Silahkan refresh halaman ini.',
              confirmButtonText: 'OK'
            });
          }
        }
      }

      xhttp.open("GET", "{{ route('ujian.fetchQuestion') }}?session_id=" + SESSION_ID + "&question_index=" + question_index, true);
      xhttp.send();
    }

    function finishExam() {
      Swal.fire({
        title: 'Alert',
        icon: 'question',
        text: 'Apakah Anda yakin ingin mengakhiri ujian? (aksi tidak dapat dikembalikan)',
        confirmButtonText: 'Ya',
        cancelButtonText: 'Tidak',
        showCancelButton: true,
        showCloseButton: true,

      }).then((result) => {
        if (result.isConfirmed) {
          event.preventDefault();
          let xhttp = new XMLHttpRequest();
          let the_answer = null;
          let token = document.getElementById('_token').getAttribute('value');
          let formData = new FormData();

          document.getElementsByName('jawaban_final').forEach(element => {
            if (element.checked) {
              the_answer = {
                key: element.id.split('_')[1],
              };
            }
          });
          if(the_answer) {
            formData.append('jawaban_final', the_answer.key);
            formData.append('_token', token);
            formData.append('question', QUESTION_INDEX);
            formData.append('id_question', QUESTION_ID);
            formData.append('session_id', SESSION_ID);
            xhttp.open("POST", "{{ route('ujian.store') }}", false);
            xhttp.send(formData);
            console.log("sending answer (finish)");
          }

          ws.send(JSON.stringify({
            type: "command",
            action: "stop",
            session_id: SESSION_ID
          }));

          //send_data_to_db
          ws.send(JSON.stringify({
            type: "send_data_to_db",
            session_id: SESSION_ID
          }));

          ws.send(JSON.stringify({
            type: "update_status",
            status_sessions: false,
            session_id: SESSION_ID
          })); 

          window.location.href = "{{ route('hasil-tes.index') }}?id_test_sessions=" + SESSION_ID;
        }
      });
    }

    function getCurrentAnswer(id_question) {
      let xhttp = new XMLHttpRequest();

      xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
          let response = JSON.parse(this.responseText);
          if (response.status) {
            let choices_html = '';
            $('#answer_field').html('<div class="fs-4 fw-bold p-2">Jawaban:</div>');
            response.choices.forEach((choice) => {
              choices_html += `
                <div class="form-check m-2">
                  <input class="form-check-input" type="radio" name="jawaban_final" id="jawaban_${choice.key}">
                  <label class="form-check-label" for="jawaban_${choice.key}">${choice.value}</label>
                </div>
              `;
            });
            $('#answer_field').append(choices_html);
            if(response.jawaban != null) {
              document.getElementsByName('jawaban_final').forEach(element => {
                if (element.id.split('_')[1] == response.jawaban) {
                  element.checked = true;
                }
              });
            }
            Swal.close();
            checkFullscreen();
          }
        }
      };
      xhttp.open("GET", "{{ route('ujian.getCurrentAnswer') }}?session_id=" + SESSION_ID + "&id_question=" + id_question, false);
      xhttp.send();
    }

    function getNavigationField() {
      let xhttp = new XMLHttpRequest();
      let total_question = 0;

      xhttp.onreadystatechange = function() {
        if(this.readyState == 4 && this.status == 200) {
          let response = JSON.parse(this.responseText);
          if(response.status) {
            let navigation_field = '<div class="col-md-12 border-bottom fs-4 fw-bold p-2 mb-3">Navigasi Soal</div>';
            $('#navigation_field').html(navigation_field);
            response.data.forEach((q) => {
              let answered = 'bg-light-subtle';
              if(q.answered) {
                answered = 'bg-secondary-subtle'
              }
              navigation_field += `
                <div onclick="changeQuestion(${q.index})" id="nomor_${q.index}" class="col-md-1 btn d-flex justify-content-center align-items-center ${answered} border rounded p-0 m-1" style="aspect-ratio: 1/1.5;">${q.index}</div>
              `;
              total_question += 1;
            });
            if(QUESTION_INDEX <= total_question) {
              let next_num = 0;
              next_num = QUESTION_INDEX + 1;
              if(next_num > total_question) {
                // tombol finish dan back
                navigation_field += `
                  <div class="btn btn-secondary mb-2" onclick="changeQuestion(${QUESTION_INDEX - 1})">Back</div>
                `;
                navigation_field += `
                  <div class="btn btn-success" onclick="finishExam()">Finish</div>
                `;
              } else {
                if((QUESTION_INDEX - 1) != 0) {
                  navigation_field += `
                    <div class="btn btn-secondary mb-2" onclick="changeQuestion(${QUESTION_INDEX - 1})">Back</div>
                  `;
                }
                navigation_field += `
                  <div class="btn btn-primary" status="false" onclick="changeQuestion(${QUESTION_INDEX + 1})">Next</div>
                `;
              }
            }
            $('#navigation_field').html(navigation_field);
            setCurrentNavigation();
          }
        }
      };

      xhttp.open('GET', '{{ route('ujian.navigationField') }}?session_id=' + SESSION_ID, true);
      xhttp.send();
    }

    function getTimeLeft() {
      let xhttp = new XMLHttpRequest();

      xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
          let response = JSON.parse(this.responseText);
          console.log('Time left:', response.time_left);
          UNIX_END_TIME = response.time_left;
        }
      };
      xhttp.open("GET", "{{ route('ujian.getTimeLeft') }}?session_id=" + SESSION_ID, false);
      xhttp.send();
    }

    function updateTimeLeft() {
      let time_left = UNIX_END_TIME - Math.floor(Date.now() / 1000);
      if(time_left < 0) {
        time_left = 0;
        finishExam();
      }
      let minutes = Math.floor(time_left / 60);
      let seconds = time_left % 60;
      document.getElementById('time_left').innerText = ' ' + minutes + ':' + (seconds < 10 ? '0' : '') + seconds;
    }

    function startTobii() {
      ws.send(JSON.stringify({
        type: "command",
        action: "start",
        session_id: SESSION_ID
      }));
    }

    function stopTobii() {
      ws.send(JSON.stringify({
        type: "command",
        action: "stop",
        session_id: SESSION_ID
      }));
    }

    function openFullscreen() {
      const status = $('#fullscreen_btn').attr('data-status');
      const elem = document.documentElement;
      if (status === 'fullscreen') {
        if (elem.requestFullscreen) {
          elem.requestFullscreen();
        } else if (elem.webkitRequestFullscreen) {
          elem.webkitRequestFullscreen(); // Safari
        } else if (elem.msRequestFullscreen) {
          elem.msRequestFullscreen(); // IE
        }
        $('#fullscreen_btn').attr('data-status', 'exit-fullscreen');
        $('#fullscreen_btn').text('Exit Fullscreen');
        startTobii();
      } else if (status === 'exit-fullscreen') {
        if (document.exitFullscreen) {
          document.exitFullscreen();
        } else if (document.webkitExitFullscreen) {
          document.webkitExitFullscreen(); // Safari
        } else if (document.msExitFullscreen) {
          document.msExitFullscreen(); // IE
        }
        $('#fullscreen_btn').attr('data-status', 'fullscreen');
        $('#fullscreen_btn').text('Enter Fullscreen');
      }
    }

    function checkFullscreen() {
      if (!document.fullscreenElement) {
        ws.send(JSON.stringify({
          type: "command",
          action: "stop",
          session_id: SESSION_ID
        }));

        Swal.fire({
          title: 'Alert',
          icon: 'warning',
          text: 'Anda keluar dari mode fullscreen, harap masuk ke mode fullscreen untuk melanjutkan ujian.',
          confirmButtonText: 'Ya',
          showCancelButton: false,
          showCloseButton: false,
          allowOutsideClick: false,
          allowEscapeKey: false,
          backdrop: `rgba(0, 0, 0, 0.4)`
        }).then((result) => {
          if (result.isConfirmed) {
            openFullscreen();
          }
        });
      }
    }

    $(document).ready(function() {
      startWebsocket();
    });
  </script>
@endsection