const tb_custom_editor = {
  // 기초 코드용 에디터: 새로추가한(STATUS = I) ROW의 기초코드만 수정가능
  pkCode: function (cell, onRendered, success, cancel, editorParams) {
    const input = document.createElement("input");
    const format = editorParams.format ? editorParams.format : "text";

    if (cell.getData()._STATUS_ == "I") {
      input.setAttribute("type", format);
      input.style.width = "100%";
      input.value = cell.getValue() ? cell.getValue() : "";

      if (editorParams.type === "upper") {
        // 입력값이 변경될 때 대문자로 변환
        input.addEventListener("input", function () {
          this.value = this.value.toUpperCase();
        });
      }

      onRendered(function () {
        input.focus();
        input.style.height = "100%";
      });

      function successFunc() {
        success(input.value);
      }

      input.addEventListener("change", successFunc);
      input.addEventListener("blur", successFunc);
      return input;

    } else {

      return false;
    }
  },

  // 팝업이 열리는 셀의 에디터: 수정되지 않는다(READONLY)
  pop: function(cell,onRendered,success,cancel,editorParams){
    const input = document.createElement("input");
    const format = editorParams.format ? editorParams.format : "text";
      input.setAttribute("type", format);
      input.setAttribute("readonly", true);
      input.style.width = "100%";
      input.value = cell.getValue() ? cell.getValue() : "";
  
      onRendered(function () {
        input.focus();
        input.style.height = "100%";
      });
  
      function successFunc() {
        success(input.value);
      }
  
      input.addEventListener("change", successFunc);
      input.addEventListener("blur", successFunc);
      return input;
  },

  // item 에서 없애고 pop으로 대체하기
  clickShow: function(cell,onRendered,success,cancel,editorParams){
  const input = document.createElement("input");
  const format = editorParams.format ? editorParams.format : "text";
    input.setAttribute("type", format);
    input.setAttribute("readonly", true);
    input.style.width = "100%";
    input.value = cell.getValue() ? cell.getValue() : "";

    onRendered(function () {
      input.focus();
      input.style.height = "100%";
    });

    function successFunc() {
      success(input.value);
    }

    input.addEventListener("change", successFunc);
    input.addEventListener("blur", successFunc);
    return input;
  },

  // select 박스 에디터
  editorSelect: function(cell, onRendered, success, cancel, editorParams){
    let edSelect = document.createElement("select");
    let params = editorParams.values;
    params = params || {};

    Object.keys(params).forEach(key => {
      let edOption = document.createElement("option");
      edOption.value = key;
      edOption.text = params[key];
      edSelect.append(edOption);
    });

    edSelect.className = 'form-select form-select-sm';
    edSelect.value = cell._cell.value;
    onRendered(function() {
      edSelect.focus();
    });

    let cback = function(){
      success( edSelect.value);
    }

    edSelect.addEventListener("change", cback);
    edSelect.addEventListener("blur", cback);

    return edSelect;
  },


  // 다른 셀의 체크 상태에 따라 input / select 에디터
  inputOrSelect: function (cell, onRendered, success, cancel, editorParams) {
    const rowData = cell.getData();
    const checkPoint = rowData[editorParams.checkPoint];
    const cellValue = cell.getValue() ? cell.getValue() : ""; // 현재 셀의 값을 가져옵니다.
    let input; // 조건에 따라 생성될 입력 요소

    if (checkPoint === "Y") {
      let options = [{ idx:1, val: "OK" }, { idx:0, val: "NG" }, { idx: "", val: "없음" } ];
      input = document.createElement("select");

      input.style.width = "100%";

      options.forEach((temp)=>{
        var optionElement = document.createElement("option");
        optionElement.value = temp.idx;
        optionElement.text = temp.val;
        input.appendChild(optionElement);

      })

    } else {
      input = document.createElement("input");
      input.setAttribute("type", "text");
      input.value = cellValue;
      input.style.width = "100%";
      // input.className = 'form-control form-control-sm'; // 부트스트랩 클래스 적용
    }

    onRendered(function () {
      input.focus();
      input.style.height = "100%";
    });

    function successFunc() {
      success(input.value); // 성공 콜백에 값을 전달하여 셀을 업데이트합니다.
    }

    input?.addEventListener("change", successFunc);
    input?.addEventListener("blur", successFunc);

    return input;
  },

  // inputOrSelect: function (cell, onRendered, success, cancel, editorParams) {
  //   const rowData = cell.getData();
  //   const checkPoint = rowData[editorParams.checkPoint];
  //   const cellValue = cell.getValue() ? cell.getValue() : ""; // 현재 셀의 값을 가져옵니다.
  //   let input; // 조건에 따라 생성될 입력 요소

  //   if (checkPoint === "Y") {
  //     input = document.createElement("select");
  //     const options = ["OK", "NG"];

  //     options.forEach(function (option, idx) {
  //       const optionElement = document.createElement("option");
  //       optionElement.value = idx;
  //       optionElement.textContent = option;

  //       if (option === cellValue) {
  //         optionElement.selected = true;
  //         input.value = idx;
  //         console.log(input.value)
  //       }

  //       input.append(optionElement);
  //     });
  //     console.log(cell._cell.value)
  //     input.value = cell._cell.value;

  //     input.style.width = "100%";
  //   } else {
  //     input = document.createElement("input");
  //     input.setAttribute("type", "text");
  //     input.value = cellValue;
  //     input.style.width = "100%";
  //   }

  //   onRendered(function () {
  //     input.focus();
  //     input.style.height = "100%";
  //   });

  //   function successFunc() {
  //     if (checkPoint === "Y") {
  //       success(input.value);
  //     } else {
  //       success(input.value);
  //     }
  //   }

  //   input.addEventListener("change", successFunc);
  //   input.addEventListener("blur", successFunc);

  //   return input;
  // },





  // 생산계획: 다른 셀의 값에 따라 input[type=num] / select
  regPlan: function (cell, onRendered, success, cancel, editorParams) {
    const rowData = cell.getData();
    const checkPoint = rowData[editorParams.checkPoint];
    let cellValue = cell.getValue() ? cell.getValue() : ""; // 현재 셀의 값을 가져옵니다.
    let input; // 조건에 따라 생성될 입력 요소

    if (checkPoint === "그룹") {

      // div 
      // let options = editorParams.values
      // input = document.createElement("select");
      // input.style.width = "100%";

      let options = editorParams.values;
      input = document.createElement("input");
      input.style.width = "100%";
      input.style.height = "100%";

      // Autocomplete 기능 추가
      $(input).autocomplete({
        source: Object.values(options),
        select: function(event, ui) {
          success(ui.item.value); // 선택된 값을 성공 콜백에 전달
        },

      });

      input.value = cellValue;

      for(let temp in options){

          var optionElement = document.createElement("option");
          optionElement.value = temp;
          optionElement.text = options[temp];
          if(temp === cellValue){
            optionElement.selected = true;
          }
          input.appendChild(optionElement);
      }
      input.addEventListener("keydown", function(e) {
        if (['ArrowUp', 'ArrowDown'].includes(e.key)) {
          e.stopPropagation();
        }
      });


      // let options = editorParams.values
      // input = document.createElement("select");
      // input.style.width = "100%";

      // for(let temp in options){
      //     var optionElement = document.createElement("option");
      //     optionElement.value = temp;
      //     optionElement.text = options[temp];
      //     if(temp === cellValue){
      //       optionElement.selected = true;
      //     }
      //     input.appendChild(optionElement);
      // }

    }else{
      input = document.createElement("input");
      input.setAttribute("type", "number");
      input.setAttribute("min", 0);
      input.value = cellValue;
      input.style.width = "100%";

      input.addEventListener("input", function () {
        this.value = this.value < 0 ? 0 : this.value;
      });
    }

    onRendered(function () {
      input.focus();
      input.style.height = "100%";
    });

    function successFunc() {
      success(input.value);
      // if (checkPoint === "Y") {
      // } else {
      //   success(input.value);
      // }
    }

    input.addEventListener("change", successFunc);
    input.addEventListener("blur", successFunc);

    return input;
  },

  // 현장작업자 팝업: 이전양품수량 초과 안되게 리미트
  limitQty: function (cell, onRendered, success, cancel, editorParams) {
    const input = document.createElement("input");
    const curSum = cell.getTable().getCalcResults().bottom[editorParams.qty];
    const vsNum = editorParams.vsNum.formData[editorParams.formQty];

    input.setAttribute("type", "number");
    input.setAttribute("min", 0);
    input.style.width = "100%";
    input.value = cell.getValue() ? parseInt(cell.getValue()) : "";

    onRendered(function () {
      input.focus();
      input.style.height = "100%";
    });

    function successFunc() {
      if (parseInt(vsNum) < parseInt(curSum) + parseInt(input.value)) {
        input.value = parseInt(vsNum) - parseInt(curSum);
        kuls_alert("이전양품수량을 초과할 수 없습니다.");
      }
      success(input.value);
    }

    input.addEventListener("change", successFunc);
    input.addEventListener("input", function () {
      this.value = this.value < 0 ? 0 : this.value;
    });
    // input.addEventListener("blur", successFunc);
    return input;
  },

  // 양수만 입력가능한 number 에디터
  minNumber: function (cell, onRendered, success, cancel, editorParams) {
    const input = document.createElement("input");
    const minVal = editorParams.min;

    input.setAttribute("type", "number");
    input.setAttribute("min", 0);
    input.style.width = "100%";
    input.value = cell.getValue() ? parseInt(cell.getValue()) : "";

    onRendered(function () {
      input.focus();
      input.style.height = "100%";
    });

    input.addEventListener("input", function () {
      this.value = this.value < minVal ? minVal : this.value;
    });

    // 값 변경 완료 시
    function onChange() {
      if (input.value != cell.getValue()) {
        success(input.value);
      } else {
        cancel();
      }
    }

    // 이벤트 리스너 등록
    input.addEventListener("blur", onChange);
    input.addEventListener("keydown", function (e) {
      if (e.keyCode == 13) {
        onChange(); // 엔터 키를 누를 때
      }
      if (e.keyCode == 27) {
        cancel(); // ESC 키를 누를 때
      }
    });

    return input;
  },

  // 대문자로 변경되는 에디터
  upper: function (cell, onRendered, success, cancel) {
    // input 요소 생성
    const input = document.createElement("input");
    input.setAttribute("type", "text");
    input.style.width = "100%";
    input.value = cell.getValue() ? cell.getValue() : "";

    // 입력값이 변경될 때 대문자로 변환
    input.addEventListener("input", function () {
      this.value = this.value.toUpperCase();
    });

    // 에디터가 렌더링된 후 실행될 콜백
    onRendered(function () {
      input.focus();
      input.style.height = "100%";
      input.select();
    });

    // 값 변경 완료 시
    function onChange() {
      if (input.value != cell.getValue()) {
        success(input.value);
      } else {
        cancel();
      }
    }

    // 이벤트 리스너 등록
    input.addEventListener("blur", onChange);
    input.addEventListener("keydown", function (e) {
      if (e.keyCode == 13) {
        onChange(); // 엔터 키를 누를 때
      }
      if (e.keyCode == 27) {
        cancel(); // ESC 키를 누를 때
      }
    });

    return input;
  },

  // 숫자만 입력 가능한 에디터
  onlyNumber: function (cell, onRendered, success, cancel) {
    // 입력 요소 생성
    const input = document.createElement("input");
    input.setAttribute("type", "text");
    input.style.width = "100%";
    input.value = cell.getValue() ? cell.getValue() : "";

    onRendered(function () {
      input.focus();
      input.style.height = "100%";
    });

    function onChange() {
      if (input.value.match(/^\d*$/)) {
        // 숫자만 허용
        success(input.value);
      } else {
        input.value = input.value.replace(/[^0-9]/g, "");
      }
    }

    input.addEventListener("blur", onChange);
    input.addEventListener("keydown", function (e) {
      if (e.keyCode == 13) {
        onChange();
      }
      if (e.keyCode == 27) {
        cancel();
      }
    });

    return input;
  },

  // 숫자 최대 4자리(문자x) -> 00:00
  time: function (cell, onRendered, success, cancel) {
    // 입력 요소 생성
    const input = document.createElement("input");
    input.setAttribute("type", "text");
    input.style.width = "100%";
    input.value = cell.getValue() ? cell.getValue() : "";

    onRendered(function () {
      input.focus();
      input.select();
      input.style.height = "100%";
    });

    // 변경사항이 완료되면 호출될 함수
    function onChange() {
      if (input.value.length === 5) {
        // 'HH:mm' 형식 확인
        success(input.value);
        console.log(cell.getValue());
      } else {
        cancel();
      }
    }

    // 입력 이벤트 처리
    input.addEventListener("input", function () {
      var value = input.value.replace(/[^0-9]/g, ""); // 숫자만 입력 받음

      if (value.length > 2) {
        value = value.substring(0, 4); // 최대 4자리
        input.value = value.replace(/(\d{2})(\d{1})/, "$1:$2");
      }
    });
    input.addEventListener("blur", onChange);
    input.addEventListener("keydown", function (e) {
      if (e.keyCode == 13) {
        onChange();
      }
      if (e.keyCode == 27) {
        cancel();
      }
    });

    return input;
  },
};
// 키-값 저장 클래스
const rowClickeventMap = new WeakMap();

const tb_custom_formatter = {
  // 기초코드 셀에 조건에 따라 클래스 추가 
  pkCode: function (tgt, params) {
    if (tgt.getData()._STATUS_ == "I") {
      tgt.getElement().classList.add("editable-cell");
    } else {
      tgt.getElement().classList.remove("tabulator-editable");

      let rowClickevent = rowClickeventMap.get(tgt.getElement());

      if (!rowClickevent) {
        rowClickevent = function (e) {
          params.tableClass.rowClick(e, tgt.getRow());
        };
        rowClickeventMap.set(tgt.getElement(), rowClickevent);
        tgt.getElement().addEventListener("click", rowClickevent);
      }
    }

    return tgt.getValue();
  },

  // 재사용x 생산계획 구분선
  rowspan_3: function (tgt, params) {
    if (tgt.getData().SEPER === "계획") {
      return tgt.getValue();
    } else if(tgt.getData().SEPER === "실적"){
      tgt.getElement().classList.add("border-bottom")
      return "";
    }else{
      return "";
    }

  },

  // 값에 따라 배경색 바꾸기(클래스 추가)
  status: function (cell, formatterParams, onRendered) {
    const cellStats = cell.getValue()?.split(" / ")[1];
    const cellVar = cell.getValue()?.split(" / ")[0];

    if (
      formatterParams["selectValue"] === cellVar &&
      formatterParams["selectValue"]
    ) {
      cell.getElement().classList.add("red-font");
    }
    switch (cellStats) {
      case "R":
        cell.getElement().classList.add("yellow-back");
        break;
      case "F":
        cell.getElement().classList.add("blue-back");
        break;
      case "D":
        cell.getElement().classList.add("orange-back");
        break;
      case "P":
        cell.getElement().classList.add("gray-back");
        cell.getElement().classList.add("white-font");
        break;
      case "S":
        cell.getElement().classList.add("red-back");
        break;
    }

    return cellVar;
  },

  // 값에 따라 붉은 글씨
  stopStatus: function (tgt, formatterParams) {
    var cell = tgt._cell;
    let div = document.createElement("div");
    // const cellStats = tgt.getValue()?.split(" / ")[1];
    const cellVar = tgt.getValue();
    if(formatterParams.class) div.className = formatterParams.class;
    let nval = cell.value || formatterParams.default;
    div.innerHTML = formatterParams.values[nval] || (formatterParams.defaultValue || '');
  
    if (cellVar === 'S') {
      tgt.getElement().classList.add("red-font");
    }
    return div;
  },

  //토글버튼 출력 red
  formatterToggleboxRedIcon: function (tgt, params) {
    let cell = tgt._cell;
    let span = document.createElement("span");

    if(tgt.getData()[params.field] !== params.value){
      tgt.getElement().classList.add('tabulator-editable');
    }

    if ( params.checkval && cell.value == params.checkval || !params.checkval && cell.value == true) {
      span.className = "bi bi-toggle-on tb_toggle red";
    } else {
      span.className = "bi bi-toggle-off tb_toggle red";
    }
    return span;
  },

  selectOrNum: function (cell, formatterParams) {
    const rowData = cell.getData();
    const checkPoint = rowData[formatterParams.checkPoint];
    const value = cell.getValue() || "";
    const field = cell.getField();

    if (checkPoint === "그룹") {
      return value;
    }
    else if(checkPoint === "계획"){
      
      const nextRow = cell.getRow().getNextRow();
      const nextRowData = nextRow.getData();
      const nextValue = nextRowData[field]  || 0
      
      const valueFormat = value === "" ? 0 : value;
      
      if(parseInt(valueFormat)>parseInt(nextValue)){
        const rsltCell = nextRow.getCell(field);
        rsltCell.getElement().classList.add("red-back");
      }else{
        const rsltCell = nextRow.getCell(field);
        rsltCell.getElement().classList.remove("red-back")
      }
      return value;
    }
    else if(checkPoint === "실적"){
      const prevRow = cell.getRow().getPrevRow();
      const prevRowData = prevRow.getData();
      const prevValue = prevRowData[field]  || 0
      
      const valueFormat = value === "" ? 0 : value;
      
      if(parseInt(prevValue)>parseInt(valueFormat)){
        cell.getElement().classList.add("red-back");
      }else{
        cell.getElement().classList.remove("red-back")
      }
      return value;
    }
  },

  // 0000 -> 00:00
  time: function (cell, formatterParams, onRendered) {
    return cell
      .getValue()
      .padStart(4, "0")
      .replace(/(\d{2})(\d{2})/, "$1:$2");
  },


  datetime: function (cell, formatterParams) {
    const datetime = cell.getValue();
    return (
      (datetime.getHours() < 10
        ? "0" + datetime.getHours()
        : datetime.getHours()) +
      ":" +
      (datetime.getMinutes() < 10
        ? "0" + datetime.getMinutes()
        : datetime.getMinutes()) +
      ":" +
      (datetime.getSeconds() < 10
        ? "0" + datetime.getSeconds()
        : datetime.getSeconds())
    );
  },

  // 시간 차 계산
  diffTitme: function (cell, formatterParams, onRendered) {
    let startTime = cell.getRow().getCell("OPER_ST_TM").getValue();
    let endTime = cell.getRow().getCell("OPER_ED_TM").getValue();
    if (startTime && endTime) {
      let start = luxon.DateTime.fromFormat(startTime, "HH:mm");
      let end = luxon.DateTime.fromFormat(endTime, "HH:mm");
      // 날짜가 반전되는 경우를 처리 (예: 밤샘)
      if (end < start) {
        end = end.plus({ days: 1 });
      }
      // 시간 차이 계산
      let duration = end.diff(start, "minutes");
      return duration.minutes; // 분 단위로 반환
    } else {
      return ""; // Return empty string if either time is missing
    }
  },

  deleteIcon: function (cell, formatterParams) {
    const tgt = cell.getElement();
    const isExit = cell.getData()["_STATUS_"];
    if(!formatterParams['icon']){
      if (isExit !== "I") {
        let span = document.createElement("span");
        span.className = "bi bi-x-square";
        tgt.addEventListener("mouseenter", () => {
          span.className = "bi bi-x-square-fill";
        });
        tgt.addEventListener("mouseleave", () => {
          span.className = "bi bi-x-square";
        });
        return span;
      }
      return "";
    }else{
      let span = document.createElement("span");
      span.className = "bi bi-x-square";
      tgt.addEventListener("mouseenter", () => {
        span.className = "bi bi-x-square-fill";
      });
      tgt.addEventListener("mouseleave", () => {
        span.className = "bi bi-x-square";
      });
      return span;
    }
  },

  checkInspValue: function (cell, formatterParams) {
    const rowData = cell.getData();
    const checkPoint = formatterParams["checkPoint"];
    const upValue = parseFloat(rowData.TOL_UPPER);
    const lowValue = parseFloat(rowData.TOL_LOWER);
    const value = cell.getValue();

    // 셀 DOM 요소 가져오기

    // let cell = tgt._cell;

    // if ( params.checkval && cell.value == params.checkval || !params.checkval && cell.value == true) {
    // } else {
    // }

    const cellElement = cell.getElement();

    // 클래스 추가/제거
    if (rowData[checkPoint] === "Y") {
      // let span = document.createElement("span");
      switch (parseInt(value)) {
        case 1:
          cellElement.classList.add("green-back");
          cellElement.classList.remove("red-back");
          return "OK";
        case 0:
          cellElement.classList.add("red-back");
          cellElement.classList.remove("green-back");
          return "NG";
        default:
          cellElement.classList.remove("green-back");
          cellElement.classList.remove("red-back");
          return "";
      }

    } else {
      if (value) {
        const valueNum = parseFloat(value) ? parseFloat(value) : "";
        if (valueNum > upValue || valueNum < lowValue) {
          cellElement.classList.add("red-back");
          cellElement.classList.remove("green-back");
        } else {
          cellElement.classList.add("green-back");
          cellElement.classList.remove("red-back");
        }
        // 소수점 3자리까지 표시
        return valueNum ? valueNum.toFixed(0) : 0;
      } else {
        return value;
      }
    }
  },
  limitValue: function (cell, formatterParams) {
    const rowData = cell.getData();
    const checkPoint = formatterParams["checkPoint"];
    const decimal = formatterParams["decimal"] ? formatterParams["decimal"] : 0;
    const value = cell.getValue() ? cell.getValue() : 0;


    // 클래스 추가/제거
    if (rowData[checkPoint] === "Y") {
      if (value !== "") {
        // cell.setValue(""); // 셀 값을 빈 문자열로 설정
      }
      return "";
    } else {
      if(value !== "" ){
        return parseFloat(value).toFixed(decimal);
      }
      // if(decimal){
      //   const valuesFormat = parseFloat(value).toFixed(decimal);
      //   console.log(cell)
      //   // cell.setValue(`${valuesFormat}`);
      // }else{
      //   return value;
      // }

    }


  },
};

const tb_custom_validator = {
  onlyString: function (cell, value, parameters) {
    const regex = /^[가-힣A-Za-z\s]+$/;

    return regex.test(value);
  },

  onlyEnglish: function (cell, value, parameters) {
    const regex = /^[A-Za-z\s]+$/;

    return regex.test(value);
  },

  stringNumeric: function (cell, value, parameters) {
    const regex = /^[가-힣ㄱ-ㅎㅏ-ㅣA-Za-z0-9\/\-\_\s]+$/;

    return regex.test(value);
  },
};

const tb_custom_edited = {
  // checkInspValue: function(cell){
  //   // 셀 값 가져오기
  //   const rowData = cell.getData();
  //   const upValue = parseFloat(rowData.SPEC_VAL) + parseFloat(rowData.TOL_UPPER) * 0.001;
  //   const lowValue = parseFloat(rowData.SPEC_VAL) - parseFloat(rowData.TOL_LOWER) * 0.001;
  //   const value = parseFloat(cell.getValue());
  //   // 셀 DOM 요소 가져오기
  //   const cellElement = cell.getElement();
  //   // 클래스 추가/제거
  //   if(value > upValue || value < lowValue){
  //     cellElement.classList.add("red-back");
  //     cellElement.classList.remove("green-back");
  //   } else {
  //       cellElement.classList.remove("red-back");
  //       cellElement.classList.add("green-back");
  //   }
  // }
};

const formFormat = {
  telInput: function (input) {
    let formattedNumber = input.value.replace(/[^0-9]/g, ""); // 숫자만 추출
    // 자동 포맷팅 로직 구현 예시: "123-456-7890" 형식
    if (formattedNumber.length > 10) {
      formattedNumber =
        formattedNumber.slice(0, 3) +
        "-" +
        formattedNumber.slice(3, 7) +
        "-" +
        formattedNumber.slice(7);
    } else {
      formattedNumber =
        formattedNumber.slice(0, 3) +
        "-" +
        formattedNumber.slice(3, 6) +
        "-" +
        formattedNumber.slice(6);
    }
    input.value = formattedNumber; // 포맷팅된 번호를 입력 필드에 다시 설정
  },

  inNumInput: function (input) {
    let formattedNumber = input.value.replace(/[^0-9]/g, ""); // 숫자만 추출
    // 자동 포맷팅 로직 구현 예시: "123-456-7890" 형식
    formattedNumber =
      formattedNumber.slice(0, 6) + "-" + formattedNumber.slice(6, 13);
    input.value = formattedNumber; // 포맷팅된 번호를 입력 필드에 다시 설정
  },

  alphanumeric: function (input) {
    input.value = input.value.toUpperCase().replace(/[^A-Z0-9]/g, "");
  },

  submitValidate: function () {
    let isValid = true;

    return isValid;
  },
};
