<template>
  <div class="table-zone">
    <table class="form-table">
      <colgroup>
        <col style="width: 10%" />
        <col style="width: 40%" />
      </colgroup>
      <tbody>
        <tr>
          <th>제목</th>
          <td>
            <input
              type="text"
              name=""
              id="inputid"
              class="full-input"
              v-model="title"
            />
          </td>
        </tr>
        <tr>
          <th>내용</th>
          <td><textarea rows="4" v-model="dc"></textarea></td>
        </tr>
        <tr>
          <th>작업타입</th>
          <td>
            <div class="input-container flex">
              <label class="radio-label">
                <input
                  type="radio"
                  name="radio2"
                  :value="false"
                  class="custom-radiobox"
                  v-model="isUsehighClassOption"
                />
                <span>일반 방식</span>
              </label>
              <label class="radio-label">
                <input
                  type="radio"
                  name="radio2"
                  :value="true"
                  class="custom-radiobox"
                  v-model="isUsehighClassOption"
                />
                <span>커스텀 방식</span>
              </label>
            </div>
          </td>
        </tr>
        <tr>
          <th>작업타입 설정</th>
          <td>
            <div class="input-container flex">
              <label class="radio-label">
                <input
                  type="radio"
                  name="Cyclical"
                  :value="true"
                  class="custom-radiobox"
                  v-model="isCyclical"
                />
                <span>반복작업(반복주기 설정)</span>
              </label>
            </div>
          </td>
        </tr>
        <tr>
          <th>반복주기 설정</th>
          <td>
            <div
              class="flex justify-start"
              v-show="isUsehighClassOption == false"
            >
              <select
                name="cycle"
                v-model="cronItem"
                :disabled="isUsehighClassOption == true"
                style="margin-left: 5px; margin-bottom: 5px"
              >
                <option
                  v-for="(value, key, i) in cronItems"
                  :key="i"
                  :value="key"
                >
                  매 {{ value.title }}
                </option>
                <option value="ALL">전체</option>
              </select>
              <select
                name="year"
                v-model="cronMap.YEAR"
                v-if="isUsehighClassOption == false"
                v-show="cronItem == 'YEAR' || cronItem == 'ALL'"
                style="margin-left: 5px; margin-bottom: 5px"
              >
                <option value="*">매년</option>
                <option
                  v-for="(item, idx) in cronItems.YEAR.values"
                  :key="idx"
                  :value="item"
                >
                  {{ item }}년
                </option>
              </select>
              <select
                name="months"
                v-model="cronMap.MONTHS"
                v-show="
                  cronItem == 'MONTHS' ||
                  cronItem == 'YEAR' ||
                  cronItem == 'ALL'
                "
                style="margin-left: 5px; margin-bottom: 5px"
              >
                <option value="*">매월</option>
                <option
                  v-for="(item, idx) in cronItems.MONTHS.values"
                  :key="idx"
                  :value="item"
                >
                  {{ item }}월
                </option>
              </select>
              <select
                name="weeks"
                v-model="cronMap.WEEKS"
                v-show="cronItem == 'WEEKS' || cronItem == 'ALL'"
                style="margin-left: 5px; margin-bottom: 5px"
              >
                <option
                  v-for="(item, idx) in cronItems.WEEKS.values"
                  :key="idx"
                  :value="idx + ''"
                >
                  {{ item }}요일
                </option>
                <option value="1,2,3,4,5">평일</option>
                <option value="0,6">주말(토,일)</option>
                <option value="?" v-show="cronItem != 'WEEKS'">없음</option>
              </select>
              <select
                name="days"
                v-model="cronMap.DAYS"
                v-show="
                  cronItem == 'DAYS' ||
                  cronItem == 'MONTHS' ||
                  cronItem == 'YEAR' ||
                  cronItem == 'ALL'
                "
                style="margin-left: 5px; margin-bottom: 5px"
              >
                <option value="*" v-show="cronItem == 'DAYS'">매일</option>
                <option
                  v-for="(item, idx) in cronItems.DAYS.values"
                  :key="idx"
                  :value="item"
                >
                  {{ item }}일
                </option>
                <option value="L">말일</option>
              </select>
              <select
                name="hours"
                v-model="cronMap.HOURS"
                v-show="
                  cronItem == 'HOURS' ||
                  cronItem == 'DAYS' ||
                  cronItem == 'WEEKS' ||
                  cronItem == 'MONTHS' ||
                  cronItem == 'YEAR' ||
                  cronItem == 'ALL'
                "
                style="margin-left: 5px; margin-bottom: 5px"
              >
                <option
                  v-for="(item, idx) in cronItems.HOURS.values"
                  :key="idx"
                  :value="item"
                >
                  {{ item }}시
                </option>
              </select>
              <select
                name="minute"
                v-model="cronMap.MINUTES"
                v-show="
                  cronItem == 'MINUTES' ||
                  cronItem == 'HOURS' ||
                  cronItem == 'DAYS' ||
                  cronItem == 'WEEKS' ||
                  cronItem == 'MONTHS' ||
                  cronItem == 'YEAR' ||
                  cronItem == 'ALL'
                "
                style="margin-left: 5px; margin-bottom: 5px"
              >
                <option
                  v-for="(item, idx) in cronItems.MINUTES.values"
                  :key="idx"
                  :value="item"
                >
                  {{ item }}분
                </option>
              </select>
              <select
                name="seconds"
                v-model="cronMap.SECONDS"
                v-show="
                  cronItem == 'SECONDS' ||
                  'MINUTES' ||
                  cronItem == 'HOURS' ||
                  cronItem == 'DAYS' ||
                  cronItem == 'WEEKS' ||
                  cronItem == 'MONTHS' ||
                  cronItem == 'YEAR' ||
                  cronItem == 'ALL'
                "
                style="margin-left: 5px; margin-bottom: 5px"
              >
                <option
                  v-for="(item, idx) in cronItems.SECONDS.values"
                  :key="idx"
                  :value="item"
                >
                  {{ item }}초
                </option>
              </select>
            </div>
            <div class="flex justify-start" v-show="isUsehighClassOption">
              <select
                name="cycle"
                v-model="cronItem"
                :disabled="isUsehighClassOption == true"
                style="width: 100px; margin-left: 5px; margin-bottom: 5px"
              >
                <option
                  v-for="(value, key, i) in cronItems"
                  :key="i"
                  :value="key"
                >
                  매 {{ value.title }}
                </option>
                <option value="ALL">전체 주기</option>
              </select>
              <label for="year">
                <input
                  type="text"
                  id="year"
                  name="year"
                  v-model="cronMap.YEAR"
                  style="margin-bottom: 5px; width: 100px"
                />
              </label>
              <label for="months">
                <input
                  type="text"
                  id="months"
                  name="months"
                  v-model="cronMap.MONTHS"
                  style="width: 100px; margin-bottom: 5px"
                />
              </label>
              <label for="weeks">
                <input
                  type="text"
                  id="weeks"
                  name="weeks"
                  v-model="cronMap.WEEKS"
                  style="width: 100px; margin-bottom: 5px"
                />
              </label>
              <label for="days">
                <input
                  type="text"
                  id="days"
                  name="days"
                  v-model="cronMap.DAYS"
                  style="width: 100px; margin-bottom: 5px"
                />
              </label>
              <label for="hours">
                <input
                  type="text"
                  id="hours"
                  name="hours"
                  v-model="cronMap.HOURS"
                  style="width: 100px; margin-bottom: 5px"
                />
              </label>
              <label for="minutes">
                <input
                  type="text"
                  id="minutes"
                  name="minutes"
                  v-model="cronMap.MINUTES"
                  style="width: 100px; margin-bottom: 5px"
                />
              </label>
              <label for="seconds">
                <input
                  type="text"
                  id="seconds"
                  name="seconds"
                  v-model="cronMap.SECONDS"
                  style="width: 100px; margin-bottom: 5px"
                />
              </label>
            </div>
          </td>
        </tr>
        <tr v-show="isCyclical">
          <th>작업타입 설정</th>
          <td>
            <div class="input-container flex">
              <p>
                <b> {{ getCronStr }} </b><br />(표현식:{{ getCron }})
              </p>
            </div>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
//크론 설정값 초기화
var cronMapInit = {
  SECONDS: "0",
  MINUTES: "0",
  HOURS: "0",
  DAYS: "*",
  WEEKS: "?",
  MONTHS: "*",
  YEAR: "*",
};

export default {
  props: {
    schedule: {
      type: Object,
      default: {},
    },
  },
  data() {
    return {
      //고오급 옵션(개발자용)
      isUsehighClassOption: false,

      //반복작업 여부 : 반복 작업(반복 주기 설정):true, 예약 작업(작업 날짜 설정 - 1회성):false
      isCyclical: true,

      //Cron 표현식에 필요한 요소's
      cronItems: {
        SECONDS: {
          title: "초",
          values: [],
        },
        MINUTES: {
          title: "분",
          values: [],
        },
        HOURS: {
          title: "시",
          values: [],
        },
        DAYS: {
          title: "일",
          values: [],
        },
        WEEKS: {
          title: "요일",
          values: ["일", "월", "화", "수", "목", "금", "토"], //일:0, 월:1, 화:2, 수:3, 목:4, 금:5, 토:6
        },
        MONTHS: {
          title: "월",
          values: [],
        },
        YEAR: {
          title: "년",
          values: [],
        },
      },

      //Cron 표현식에 필요한 요소 중 선택된 요소
      cronItem: "ALL",

      //작업명
      title: "",

      // 설명
      dc: "",

      //설정된 크론값
      cronMap: JSON.parse(JSON.stringify(cronMapInit)),

      //크론 표현식 설명 키워드
      cronKeyWord: {
        "*": "매",
        "?": "",
        L: "마지막",
        "/": "부터 매",
        W: "에 가장 가까운 평일", //DAYS(일)만 사용
        "#": "번째 주", //WEEK(요일)만 사용
      },
    };
  },
  computed: {
    getCron() {
      var c = this.cronMap;
      return (
        c.SECONDS +
        " " +
        c.MINUTES +
        " " +
        c.HOURS +
        " " +
        c.DAYS +
        " " +
        c.WEEKS +
        " " +
        c.MONTHS +
        " " +
        c.YEAR
      );
    },

    getCronStr() {
      var cronStr = "";
      cronStr += this.getCronWord("YEAR", this.cronMap.YEAR);
      cronStr += "  " + this.getCronWord("MONTHS", this.cronMap.MONTHS);
      if (this.cronItem != "DAYS") {
        cronStr += "  " + this.getCronWord("WEEKS", this.cronMap.WEEKS);
      }
      if (this.cronItem != "WEEKS") {
        cronStr += "  " + this.getCronWord("DAYS", this.cronMap.DAYS);
      }
      cronStr += "  " + this.getCronWord("HOURS", this.cronMap.HOURS);
      cronStr += "  " + this.getCronWord("MINUTES", this.cronMap.MINUTES);
      cronStr += "  " + this.getCronWord("SECONDS", this.cronMap.SECONDS);

      return cronStr;
    },
  },
  mounted() {
    this.fnSarchCronItemValue(); // 반복 주기 설정을 위한 selectbox 내부 데이터(최초 1회 실행)
    this.initEvent();
    this.isUsehighClassOption = false;
  },
  methods: {
    // cronItem value
    fnSarchCronItemValue() {
      this.fnValueLoop("SECONDS", 59);
      this.fnValueLoop("MINUTES", 59);
      this.fnValueLoop("HOURS", 23);
      this.fnValueLoop("DAYS", 31);
      this.fnValueLoop("MONTHS", 12);
      this.fnValueLoop("YEAR", 5);
    },
    fnValueLoop(type, number) {
      let flag = number + 1;
      if (type == "YEAR") {
        let now = new Date();
        let year = now.getFullYear();
        for (let i = year; i < year + flag; i++) {
          this.cronItems.YEAR.values.push(i.toString());
        }
      } else {
        for (let i = 0; i < flag; i++) {
          this.cronItems[type].values.push(i.toString());
        }
      }
    },
    // 초기화
    initEvent() {
      if (!this.$isEmpty(this.schedule.schdul_id)) {
        this.cronItem = "ALL";
        this.title = this.schedule.sj;
        this.dc = this.schedule.dc;
        this.isCyclical = this.schedule.cycle_at;

        var tempcron = this.schedule.cron.split(" ");
        this.cronMap.SECONDS = tempcron[0];
        this.cronMap.MINUTES = tempcron[1];
        this.cronMap.HOURS = tempcron[2];
        this.cronMap.DAYS = tempcron[3];
        this.cronMap.WEEKS = tempcron[4];
        this.cronMap.MONTHS = tempcron[5];
        this.cronMap.YEAR = tempcron[6];

        this.fnJoinCronValue();
      }
    },
    fnJoinCronValue() {
      for (let type in this.cronItems) {
        for (let cronItem of this.cronItems[type].values) {
          if (this.cronMap[type] == cronItem) {
            this.cronItem = type;
            break;
          }
        }
      }
    },

    //개발자 옵션 (비밀)
    highClassSetting() {
      if (this.isUsehighClassOption == true) {
        this.cronMap = JSON.parse(JSON.stringify(cronMapInit));
        this.isUsehighClassOption = false;
        this.cronItem = "DAYS";
      } else {
        this.isUsehighClassOption = true;
        this.cronItem = "ALL";
      }
    },

    //Cron 표현 단어 해석
    //cronItem: SECONDS, MINUTES, HOURS, DAYS, WEEKS, MONTHS
    //value: 값 - ex) 3#2
    getCronWord(cronItem, value) {
      if (this.$isEmpty(this.cronItems[cronItem]) == true) {
        /* 오류 발생 여부 */
        return "(Error - cronItem)";
      }

      if (this.$isEmpty(value) == true) {
        /* 오류 발생 여부 */
        return "(Error - 값 없음)";
      }

      //초 or 분 or 시 or 일 or 요일 or 월
      var unit = this.cronItems[cronItem].title;

      /****** value의 값이 cronKeyWord에 포함되어 있는지 검색 ******/
      var isFind = false;
      var findInfo = {
        key: null, //*, ?, L, /, W, #
        index: -1, //key를 찾은 위치
      };
      for (var key in this.cronKeyWord) {
        var index = value.indexOf(key);
        if (index > -1) {
          isFind = true;

          findInfo.key = key;
          findInfo.index = index;

          break;
        }
      }
      /****** value의 값이 cronKeyWord에 포함되어 있는지 검색 ******/

      /************* 단어 만들기 *************/
      var word = "";

      //cronKeyWord의 key(*, ?, L, /, W, #)값 중 value값에 포함된 단어가 있을 때
      if (isFind == true) {
        //value == '*' or '?' or 'L'
        if (this.cronKeyWord[value] != undefined) {
          word = this.cronKeyWord[value];
          if (this.cronKeyWord[value] != "") {
            word += unit;
          }
        }

        //value == '/' or 'W' or '#'
        else {
          var keyowrd = this.cronKeyWord[findInfo.key];
          if (key == "/") {
            var v1 = value.substring(0, findInfo.index);
            var v2 = value.substring(findInfo.index + 1, value.length);

            //getConvertWeek() : cronItem이 'WEEKS' 일때 -> '숫자 요일' 값을 '문자 요일' 값으로 바꿈
            v1 = this.getConvertWeek(cronItem, v1);
            v2 = this.getConvertWeek(cronItem, v2);

            word = v1 + unit + " " + keyowrd + " " + (v2 + unit) + "씩";
          } else if (key == "W" && cronItem == "DAYS") {
            var v = value.replace("W");
            word = v + unit + keyword;
          } else if (key == "#" && cronItem == "WEEKS") {
            var v1 = value.substring(0, findInfo.index);
            var v2 = value.substring(findInfo.index + 1, value.length);

            //getConvertWeek() : cronItem이 'WEEKS' 일때 -> '숫자 요일' 값을 '문자 요일' 값으로 바꿈
            v2 = this.getConvertWeek(cronItem, v2);

            word = v1 + keyowrd + " " + (v2 + unit);
          } else {
            word = "(Error - '" + key + "'의 표현이 잘못됨)";
          }
        }
      }

      //날짜를 나타내는 단어 일 확률이 높음
      else {
        //getConvertWeek() : cronItem이 'WEEKS' 일때 -> '숫자 요일' 값을 '문자 요일' 값으로 바꿈
        value = this.getConvertWeek(cronItem, value);
        word = value + unit;
      }
      /************* 단어 만들기 *************/

      return word;
    },

    //cronItem이 WEEKS 일때 만, index(value)로 '요일' 찾기
    //cronItem이 WEEKS가 아닐 때, value값을 그대로 돌려줌
    getConvertWeek(cronItem, value) {
      if (cronItem == "WEEKS") {
        try {
          if (value.indexOf(",") > -1) {
            var result = "";
            var values = value.split(",");
            for (var i = 0; i < values.length; i++) {
              //문자 형태의 숫자를 -> 숫자 형태로 바꿈
              var index = Number(values[i].trim());
              //'요일'을 가지고 옴
              result += this.cronItems.WEEKS.values[index];
              //마지막 전 까지만 ','를 붙여줌
              if (i < values.length - 1) {
                result += ", ";
              }
            }

            if (result.indexOf("undefined") > -1) {
              result = "(Error - 요일의 값의 '" + value + "' 표현이 잘못됨)";
            } else {
              return result;
            }
          } else if (value.indexOf("-") > -1) {
            var result = "";
            //'-'가 들어간 위치를 가지고옴
            var index = value.indexOf("-");
            //'-' 앞 뒤의 값을 가지고 옴
            var v1 = value.substring(0, index);
            var v2 = value.substring(index + 1, value.length);

            //'-' 앞 뒤의 값을 숫자 형태로 바꿔줌
            v1 = Number(v1.trim());
            v2 = Number(v2.trim());

            result += this.cronItems.WEEKS.values[v1];
            result += "-";
            result += this.cronItems.WEEKS.values[v2];

            if (result.indexOf("undefined") > -1) {
              result = "(Error - 요일의 값의 '" + value + "' 표현이 잘못됨)";
            } else {
              return result;
            }
          } else {
            var result = this.cronItems.WEEKS.values[value];

            if (result.indexOf("undefined") > -1) {
              result = "(Error - 요일의 값의 '" + value + "' 표현이 잘못됨)";
            } else {
              return result;
            }
          }
        } catch (e) {
          return "(Error - 요일의 값의 '" + value + "' 표현이 잘못됨)";
        }
      } else {
        return value;
      }
    },
  },
  watch: {
    schedule(v) {
      this.initEvent();
    },
    cronItem(newValue, oldValue) {
      //전체 주기 설정시
      if (newValue == "ALL") {
        //'월'을 같이 표시해줘야 되기 때문에, '매일'을 뺌
        /* if (this.cronMap.DAYS == '*' || this.cronMap.DAYS == '?') {
                  this.cronMap.DAYS = '1';
              } */
        //'월', '일'이 같이 표시되기 때문에, '요일'을 기본적으로 [설정안함]
        /* if (this.cronMap.WEEKS != '?') {
                  this.cronMap.WEEKS = '?';
              } */
      }
      //'월' 별 주기 설정시
      else if (newValue == "YEAR") {
        //'년'을 같이 표시해줘야 되기 때문에, '매일'을 뺌

        if (this.cronMap.MONTH == "*" || this.cronMap.MONTH == "?") {
          this.cronMap.DAYS = "1";
        }

        if (this.cronMap.DAYS == "*" || this.cronMap.DAYS == "?") {
          this.cronMap.DAYS = "1";
        }

        //혼선을 피하기 위해 '요일'은 [설정안함]
        this.cronMap.WEEKS = "?";
      }

      //'월' 별 주기 설정시
      else if (newValue == "MONTHS") {
        //'월'을 같이 표시해줘야 되기 때문에, '매일'을 뺌
        if (this.cronMap.DAYS == "*" || this.cronMap.DAYS == "?") {
          this.cronMap.DAYS = "1";
        }
        //혼선을 피하기 위해 '요일'은 [설정안함]
        this.cronMap.YEAR = "*";
        this.cronMap.WEEKS = "?";
      }

      //'요일' 별 주기 설정시
      else if (newValue == "WEEKS") {
        //'월'의 기본 세팅 값을 '매월'로 바꿈, '일'은 [설정안함]
        this.cronMap.YEAR = "*";
        this.cronMap.MONTHS = "*";
        this.cronMap.DAYS = "?";

        //'요일'의 설정 값이 [설정안함]으로 되어 있을 때, -> '0:일요일'로 설정
        if (this.cronMap.WEEKS == "?") {
          this.cronMap.WEEKS = "0";
        }
      }

      //'일' 별 주기 설정시
      else if (newValue == "DAYS") {
        //'월'의 기본 세팅 값을 '매월'로 바꿈, '요일'은 [설정안함]
        this.cronMap.YEAR = "*";
        this.cronMap.MONTHS = "*";
        this.cronMap.WEEKS = "?";
        this.cronMap.DAYS = "*";

        //'일'의 설정 값이 [설정안함]으로 되어 있을 때, -> '매일'로 설정
        /* if (this.cronMap.DAYS == '?') {
                  this.cronMap.DAYS = '*';
              } */
      }
      // '시간' 별 주기 설정 시
      else if (newValue == "HOURS") {
        this.cronMap.YEAR = "*";
        this.cronMap.MONTHS = "*";
        this.cronMap.WEEKS = "?";
        this.cronMap.DAYS = "*";
      }
      // '분' 별 주기 설정 시
      else if (newValue == "MINUTES") {
        this.cronMap.YEAR = "*";
        this.cronMap.MONTHS = "*";
        this.cronMap.WEEKS = "?";
        this.cronMap.DAYS = "*";
        this.cronMap.HOURS = "*";
      }
      // '초' 별 주기 설정 시
      else if (newValue == "SECONDS") {
        this.cronMap.YEAR = "*";
        this.cronMap.MONTHS = "*";
        this.cronMap.WEEKS = "?";
        this.cronMap.DAYS = "*";
        this.cronMap.HOURS = "*";
        this.cronMap.MINUTES = "*";
      }
      // 그 외
      else {
        this.cronMap.YEAR = "*";
        this.cronMap.MONTHS = "*";
        this.cronMap.WEEKS = "?";
        this.cronMap.DAYS = "*";
      }
    },

    isCyclical(v) {
      this.$emit(
        "get-edit-scheduling",
        this.title,
        this.dc,
        this.getCronStr,
        this.getCron,
        v
      );
    },

    /* 데이터를 부모 컴포넌트로 전달해주기 위함 */
    title(newValue, oldValue) {
      this.$emit(
        "get-edit-scheduling",
        this.title,
        this.dc,
        this.getCronStr,
        this.getCron,
        this.isCyclical
      );
    },

    dc(newValue, oldValue) {
      this.$emit(
        "get-edit-scheduling",
        this.title,
        this.dc,
        this.getCronStr,
        this.getCron,
        this.isCyclical
      );
    },

    "cronMap.SECONDS"(newValue, oldValue) {
      this.$emit(
        "get-edit-scheduling",
        this.title,
        this.dc,
        this.getCronStr,
        this.getCron,
        this.isCyclical
      );
    },

    "cronMap.MINUTES"(newValue, oldValue) {
      this.$emit(
        "get-edit-scheduling",
        this.title,
        this.dc,
        this.getCronStr,
        this.getCron,
        this.isCyclical
      );
    },

    "cronMap.HOURS"(newValue, oldValue) {
      this.$emit(
        "get-edit-scheduling",
        this.title,
        this.dc,
        this.getCronStr,
        this.getCron,
        this.isCyclical
      );
    },

    "cronMap.DAYS"(newValue, oldValue) {
      this.$emit(
        "get-edit-scheduling",
        this.title,
        this.dc,
        this.getCronStr,
        this.getCron,
        this.isCyclical
      );
    },

    "cronMap.WEEKS"(newValue, oldValue) {
      this.$emit(
        "get-edit-scheduling",
        this.title,
        this.dc,
        this.getCronStr,
        this.getCron,
        this.isCyclical
      );
    },

    "cronMap.MONTHS"(newValue, oldValue) {
      this.$emit(
        "get-edit-scheduling",
        this.title,
        this.dc,
        this.getCronStr,
        this.getCron,
        this.isCyclical
      );
    },

    "cronMap.YEAR"(newValue, oldValue) {
      this.$emit(
        "get-edit-scheduling",
        this.title,
        this.dc,
        this.getCronStr,
        this.getCron,
        this.isCyclical
      );
    },
    /* 데이터를 부모 컴포넌트로 전달해주기 위함 */
  },
};
</script>