class LoadTestModel {
  constructor(loadTest) {
    this.scenarios = [];

    if (loadTest) {
      this.loadTest = loadTest;
    } else {
      this.loadTest = {
        scenarioId: null, threadCount: 1, loopCount: 0, rampUpTime: 0, duration: 0, testData: null
      };
    }
  }

  getScenarioList() {
    return this.scenarios;
  }
}

class LoadTestView {
  constructor(model, controller) {
    this.model = model;
    this.controller = controller;
  }

  renderScenarioList() {
    const scenarioList = this.model.getScenarioList();
    return `<div class="form-floating me-2" style="width: 250px; height: 60px;">
                <select class="form-select" name="scenarioId">
                  <option value="" selected>시나리오 선택</option>
                  ${scenarioList.map(s => `<option value="${s.id}" ${s.id === this.model.loadTest.scenarioId ? 'selected' : ''}>${s.name}</option>`).join('')}
                </select>
                <label for="scenario_list">시나리오 선택</label>
            </div>`;
  }

  render(element) {
    this.element = element;

    // Assuming the container's HTML is defined here as before
    const html = `
            ${this.renderScenarioList()}
            <div class="form-floating me-2" style="width: 100px; height: 60px;">
                <input type="number" class="form-control" name="user_count" min="1" value="${this.model.loadTest.threadCount}">
                <label for="user_count">사용자 수</label>
            </div>
            <div class="form-floating me-2" style="width: 90px; height: 60px;">
                <input type="number" class="form-control" name="repeat_count" min="0" value="${this.model.loadTest.loopCount}">
                <label for="repeat_count">반복 횟수</label>
            </div>
            <div class="form-floating me-2" style="width: 130px; height: 60px;">
                <input type="number" class="form-control" name="ramp_up" min="0" value="${this.model.loadTest.rampUpTime}">
                <label for="ramp_up">ramp-up (ms)</label>
            </div>
            <div class="form-floating me-2" style="width: 120px; height: 60px;">
                <input type="number" class="form-control" name="duration" min="0" value="${this.model.loadTest.duration}">
                <label for="duration">수행 시간(분)</label>
            </div>
            <button type="button" class="btn btn-primary me-2 start_test" style="height: 60px;">시작</button>
            <button type="button" class="btn btn-primary me-2 stop_test" style="height: 60px;">정지</button>
            <button type="button" class="btn btn-primary me-2 save_load_test" style="height: 60px;">저장</button>
            <button type="button" class="btn btn-primary me-2 reset_load_test" style="height: 60px;">초기화</button>
<!--            <button type="button" class="btn btn-primary me-2 show_test_report" style="height: 60px;">통계</button>-->
        `;

    this.element.innerHTML = html;
    console.log('LoadTestView.render() called');
  }

  updateView() {
    document.querySelector('select[name="scenarioId"]').value = this.model.loadTest.scenarioId || '';
    document.querySelector('input[name="user_count"]').value = this.model.loadTest.threadCount || 1;
    document.querySelector('input[name="repeat_count"]').value = this.model.loadTest.loopCount || 0;
    document.querySelector('input[name="ramp_up"]').value = this.model.loadTest.rampUpTime || 0;
    document.querySelector('input[name="duration"]').value = this.model.loadTest.duration || 0;
  }
}


class LoadTestController {
  constructor(contextPath, model) {
    this.contextPath = contextPath || '/';
    this.model = model;
    this.view = new LoadTestView(this.model, this);
  }

  getStartLoadTestUrl() {
    return this.contextPath + 'startLoadTest';
  }

  getStopLoadTestUrl() {
    return this.contextPath + 'stopLoadTest';
  }

  init(element) {
    // Initialize the view
    this.view.render(element);
  }

  startTest() {
    this.updateLoadTest();
    return fetch(this.getStartLoadTestUrl(), {
      method: 'POST',
      body: JSON.stringify(this.model.loadTest),
      headers: {
        'Content-Type': 'application/json',
        'X-XSRF-TOKEN': $('meta[name="_csrf"]').attr('content')
      }
    });
  }

  stopTest() {
    return fetch(this.getStopLoadTestUrl(), {
      method: 'POST',
      body: JSON.stringify(this.model.loadTest),
      headers: {
        'Content-Type': 'application/json',
        'X-XSRF-TOKEN': $('meta[name="_csrf"]').attr('content')
      }
    });
  }

  updateLoadTest() {
    this.model.loadTest.scenarioId = document.querySelector('select[name="scenarioId"]').value;
    this.model.loadTest.threadCount = document.querySelector('input[name="user_count"]').value;
    this.model.loadTest.loopCount = document.querySelector('input[name="repeat_count"]').value;
    this.model.loadTest.rampUpTime = document.querySelector('input[name="ramp_up"]').value;
    this.model.loadTest.duration = document.querySelector('input[name="duration"]').value;
  }

  showLoadTest(loadTest) {
    this.model.loadTest = loadTest;
    this.view.updateView();
  }

}

class LoadTester {
  constructor(contextPath, scenarios) {
    this.contextPath = contextPath || '/';
    this.model = new LoadTestModel();

    if (scenarios) {
      this.model.scenarios = scenarios;
    } else {
      this.model.scenarios = [];
    }
    this.controller = new LoadTestController(this.contextPath, this.model);

  }

  init(element) {
    this.controller.init(element);
    this.bindEvents();
  }

  bindEvents() {
    const events = [
      {type: 'click', selector: '.start_test', action: this.controller.startTest.bind(this.controller)},
      {type: 'click', selector: '.stop_test', action: this.controller.stopTest.bind(this.controller)}
    ];

    for (let event of events) {
      $(document).off(event.type, event.selector).on(event.type, event.selector, event.action);
    }
    console.log('LoadTester.bindEvents() called');
  }

  getLoadTest() {
    //set current value from input
    this.controller.updateLoadTest();
    return this.model.loadTest;
  }

  openLoadTest(loadTest) {
    this.controller.showLoadTest(loadTest);
  }
}

export default LoadTester;
