import { ParameterType } from 'jspsych';
import { html } from './text-stimuli';
import getColourMap from './colours';

const info = {
  name: 'object-moving',
  version: "1.1",
  parameters: {
    selector: {
      type: ParameterType.STRING,
      pretty_name: 'Selector',
    },
    together_side: {
      type: ParameterType.STRING,
      pretty_name: 'together side',
    },
    location: {
      type: ParameterType.INT,
      pretty_name: 'Location',
    },
    together_colour: {
      type: ParameterType.STRING,
      pretty_name: 'Together colour',
    },
  },
  // prettier-ignore
  citations: '__CITATIONS__'
};

class jsPsychObjectMoving {
  constructor(jsPsych) {
    this.jsPsych = jsPsych;
  }
  static {
    this.info = info;
  }

  trial(display_element, trial) {

    const colourMap = getColourMap(trial.together_colour);

    const left_goal = trial.together_side === 'left' ? 'together' : 'alone';
    const right_goal = trial.together_side === 'left' ? 'alone' : 'together';

    const left_colour = trial.together_side === 'left' ? colourMap.get('togetherbg') : colourMap.get('alonebg');
    const right_colour = trial.together_side === 'left' ? colourMap.get('alonebg') : colourMap.get('togetherbg');

    display_element.innerHTML = html`
    <div class="flex flex-row min-w-screen absolute top-0 left-0 min-h-screen">
      <div id="${left_goal}-goal" class="w-1/12 ${left_colour}"></div>
      <div id="workspace" class="w-10/12"></div>
      <div id="${right_goal}-goal" class="w-1/12 ${right_colour}"></div>
      <div id="info-box" class="z-10 absolute bottom-1/40 min-w-screen justify-center items-center"></div>
    </div>
    `;

    const workspace = document.getElementById('workspace');
    const info_box = document.getElementById('info-box');
    const workspace_width = workspace.clientWidth;
    const viewport_width = window.visualViewport.width;
    const goal_offset = viewport_width * (1/12);
    const box_width = viewport_width * (3/100);
    const workspace_offset = workspace_width * trial.location/100;

    const offset_left = workspace_offset + goal_offset - box_width/2;

    const viewport_height = window.visualViewport.height;
    const top_offset = viewport_height * .5;
    const separation = box_width * 1.5;

    const objects = html`
    <div id="object-partner" class="object-moving-box ${colourMap.get('object-disabled')} absolute z-10" style="left: ${offset_left}px; top: ${top_offset - separation}px"></div>
    <div id="object-participant" class="object-moving-box ${colourMap.get('object-disabled')} absolute z-10" style="left: ${offset_left}px; top: ${top_offset + separation}px"></div>
    `;

    workspace.innerHTML = objects;

    const object_partner = document.getElementById('object-partner');
    const object_participant = document.getElementById('object-participant');

    object_partner.addEventListener('click', () => issue_alert('partner_click'));
    object_participant.addEventListener('click', () => issue_alert('early_click_choice'));

    const partner_turn = html`<span class="font-semi-bold text-gray-800 text-xl">Awaiting your partner's selection</span>
    <div class='loading'></div>`

    let choice;
    let go_clicked = false;
    let partner_finished = false;
    let participant_finished = false;
    let partner_choice_made = false;

    const jsPsych = this.jsPsych;

    let start_time = 0;
    let response_time = 0;

    if (trial.selector === 'participant') {
      display_choices();

    } else {
      info_box.innerHTML = partner_turn;

      const partner_choice_delay = jsPsych.randomization.sampleExGaussian(2000, 250, 1/100, true);

      let random = Math.random();


      //These probabilities are based on Azaad and Sebanz (2025)
      
      if (trial.location > 48 && trial.location < 52) {
        choice = random < 0.64 ? 'together' : 'alone';
      } else if (trial.location > 31 && trial.location < 35) {
        choice = random < 0.58 ? 'together' : 'alone';
      } else if (trial.location > 64 && trial.location < 68) {
        choice = random < 0.67 ? 'together' : 'alone';
      }

      setTimeout(() => {
        info_box.innerHTML = '';
        clear_boxes();
        display_go();
        initiate_partner_action();
      }, partner_choice_delay);
    }

    function display_choices(){
      info_box.innerHTML = html`<div class="flex flex-row justify-center items-center gap-2">
      <div id="${left_goal}-button" class="w-1/12 py-1 text-slate-50 ${left_colour}">${left_goal.charAt(0).toUpperCase() + left_goal.slice(1)}</div>
      <div id="${right_goal}-button" class="w-1/12 py-1 text-slate-50 ${right_colour}">${right_goal.charAt(0).toUpperCase() + right_goal.slice(1)}</div>
      </div>`;

      const left_goal_button = document.getElementById(`${left_goal}-button`);
      const right_goal_button = document.getElementById(`${right_goal}-button`);

      start_time = Date.now();

      left_goal_button.addEventListener('click', () => {
        choice = left_goal;
        handle_choice_made(left_goal_button,right_goal_button);
      });

      right_goal_button.addEventListener('click', () => {
        choice = right_goal;
        handle_choice_made(left_goal_button,right_goal_button);
      });
    }

    function handle_choice_made(left_goal_button,right_goal_button){
      left_goal_button.removeEventListener('click', handle_choice_made);
      right_goal_button.removeEventListener('click', handle_choice_made);
      left_goal_button.remove();
      right_goal_button.remove();
      clear_boxes();
      display_go();
      response_time = Date.now() - start_time;
      if (choice === 'together') {
        initiate_partner_action();
      }
    }

    function initiate_partner_action(){
      const go_delay = trial.selector === 'participant' ? 1200 : 800
      const partner_go_delay = jsPsych.randomization.sampleExGaussian(go_delay, 300, 1/100, true);
      const partner_teleport_delay = jsPsych.randomization.sampleExGaussian(1200, 200, 1/100, true);
      
      setTimeout(() => {
        change_object_colour(object_partner);
        partner_choice_made = true;
      }, partner_go_delay);

      setTimeout(() => {
        teleport_object(object_partner);
        partner_finished = true;
        check_finished();
      }, partner_teleport_delay + partner_go_delay);
    }

    function clear_boxes() {
      if (choice === 'together') {
        return;
      }
      if (trial.selector === 'participant') {
        object_partner.remove();
      } else {
        object_participant.remove();
      }
    }

    let go_button;

    function display_go() {
      if (choice === 'alone' && trial.selector === 'partner') {
        return;
      }
      info_box.innerHTML = html`<div id="go-button" class="mx-auto font-semi-bold ${colourMap.get('gobg')} text-slate-50 text-xl w-1/20 p-2">Go</div>`;
      go_button = document.getElementById('go-button');
      object_participant.addEventListener('click', () => issue_alert('early_click_go'));
      go_button.addEventListener('click', () => handle_go_click(go_button));
    }
    
    function handle_go_click() {
      go_button.removeEventListener('click', handle_go_click);
      go_button.removeEventListener('click', () => issue_alert('early_click_go'));
      go_clicked = true;
      go_button.remove();
      change_object_colour(object_participant);
      object_participant.addEventListener('click', () => handle_teleport_click());

    }

    function handle_teleport_click(){
      teleport_object(object_participant);
      participant_finished = true;
      check_finished();
    }


  function change_object_colour(object){
    object.classList.remove(colourMap.get('object-disabled'));
    object.classList.add(colourMap.get('object-enabled'));
  }

  function teleport_object(object){
      let goal_side = 'left';
      if (choice === 'together' && trial.together_side === 'right') {
        goal_side = 'right';
      }
      if (choice === 'alone' && trial.together_side === 'left') {
        goal_side = 'right';
      }
      const mid_goal_offset = viewport_width * (1/24);
      const new_left_offset = goal_side === 'left' ? mid_goal_offset - box_width/2 : viewport_width - mid_goal_offset - box_width/2;
      object.style.transition = 'left 0.35s';  
      object.style.left = `${new_left_offset}px`;
  }

    function check_finished(){
      let finished = false;
      if (choice === 'together') {
        if (partner_finished && participant_finished) {
            finished = true;
          }
        }
        if (choice === 'alone') {
          if (partner_finished || participant_finished) {
            finished = true;
        }
      }
      if (finished) {
        object_partner.removeEventListener('click', () => issue_alert('partner_click'));
        object_participant.removeEventListener('click', () => issue_alert('early_click_choice'));

        const save_data = {
          choice: choice,
          selector: trial.selector,
          together_side: trial.together_side,
          response_time: response_time,
        }
        

        setTimeout(() => {
          jsPsych.finishTrial(save_data);
        }, 500);
      }
    }

    async function show_alert(message) {
      const dialog = document.createElement("dialog");
      document.body.appendChild(dialog);
      dialog.className = "z-20 fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 p-4 bg-slate-100 text-red-700 rounded-lg shadow-lg";
      dialog.innerText = message;
      dialog.show();
      setTimeout(function () {
        dialog.close();
      }, 2000);
    }

    function issue_alert(issue){
      if (issue === 'partner_click'){
        show_alert(`That is your partner's object. Please click the lower object.`)
      }
      if (issue === 'early_click_go' && !go_clicked){
        show_alert(`You need to click 'Go' before clicking your object.`)
      }
      if (issue === 'early_click_choice'){
        if (!partner_choice_made && trial.selector === 'partner'){
          show_alert(`Please wait for your partner to make a choice.`)
        }
        if (!choice && trial.selector === 'participant'){
          show_alert(`Please make a choice using the buttons below before clicking your object.`)
        }
      }
    }

  }
}

export default jsPsychObjectMoving;


    