<template>
  <section class="message">
    <!-- Collapse시 padding 0 -->
    <div
      class="message-header level"
      :class="{'collapse-message': isCollapse}"
    >
      <!-- Collapse시 버튼 및 텍스트 세로 배치 -->
      <div
        class="level-left"
        :class="{'collapse-item': isCollapse}"
      >
        <!-- Collapse 버튼 -->
        <!-- prop_collapse가 true일때만 랜더링 -->
        <!-- @click 이벤트 : collapse 유무를 부모로 전달 -->
        <!-- collapse-btn : 버튼 테두리 제거 css -->
        <b-button
          v-if="collapse"
          class="collapse-btn"
          @click="toggleCollapse"
        >
          {{ isCollapse ? '▼' : '▶' }}
        </b-button>
        <p v-show="!isCollapse">
          편집
        </p>
      </div>
      <!-- Collapse시 화면에서 숨김 -->
      <div
        v-show="!isCollapse"
        class="level-right"
      >
        <b-button
          v-if="!disableAdd"
          class="btn_primary"
          @click="createData"
        >
          <span>
            <img
              class="icon_prop"
              src="../assets/icon/icon_add.png"
            >추가
          </span>
        </b-button>
        <b-button
          v-if="!disableModify"
          class="btn_primary"
          @click="modifyData"
        >
          <span>
            <img
              class="icon_prop"
              src="../assets/icon/icon_modify.png"
            >수정
          </span>
        </b-button>
        <b-button
          v-if="!disableDelete"
          class="btn_primary"
          @click="deleteData"
        >
          <span>
            <img
              class="icon_prop"
              src="../assets/icon/icon_delete.png"
            >삭제
          </span>
        </b-button>
      </div>
    </div>
    <!-- Collapse시 화면에서 숨김 -->
    <div
      v-show="!isCollapse"
      class="message-body"
    >
      <form
        v-if="nextTickFlag"
        method="post"
        name="form"
      >
        <b-field
          v-for="(item, index) in this.property.params"
          :key="index"
          :label="item.label"
          custom-class="is-small"
        >
          <b-input
            v-if="item.fieldType == 'textbox'"
            v-model="search[item.field]"
            type="search"
            custom-class="is-small"
            :disabled="item.readonly"
          />
          <b-input
            v-if="item.fieldType == 'writer'"
            v-model="userId"
            type="search"
            custom-class="is-small"
            :disabled="item.readonly"
          />
          <b-autocomplete
            v-if="item.fieldType == 'autocomplete'"
            v-model="name[item.field]"
            :data="item.comboData"
            custom-class="is-small"
            @focus="selectAutoData(item)"
            @typing="option(item)"
          >
            <template slot="empty">
              No results found
            </template>
          </b-autocomplete>

          <b-select
            v-if="item.fieldType == 'combobox'"
            v-model="search[item.field]"
            :placeholder="item.label"
            expanded
            size="is-small"
            :disabled="item.readonly"
          >
            <option
              v-for="option in item.comboData"
              :key="option.description"
              :value="option.value"
            >
              {{ option.description }}
            </option>
          </b-select>

          <b-datepicker
            v-if="item.fieldType == 'datetime'"
            v-model="datePick[item.field]"
            size="is-small"
            placeholder="Click to select..."
            :month-names="month"
            :day-names="day"
            :min-date="item.endDate == true ? datePick['startDate'] : null"
            @input="dataPick($event, item.field)"
          >
            <button
              class="button is-primary"
              @click="datePick[item.field] = new Date()"
            >
              <span>Today</span>
            </button>

            <button
              class="button is-danger"
              @click.prevent="
                (datePick[item.field] = null), (search[item.field] = null)
              "
            >
              <b-icon icon="times-circle" />
              <span>Clear</span>
            </button>
          </b-datepicker>

          <b-input
            v-if="item.fieldType == 'textarea'"
            v-model="search[item.field]"
            type="textarea"
            minlength="0"
            maxlength="400"
            size="is-small"
            :disabled="item.readonly"
          />

          <b-input
            v-if="item.fieldType == 'dashboardtext'"
            v-model="search[item.field]"
            type="textarea"
            minlength="0"
            maxlength="5000"
            size="is-small"
            :disabled="item.readonly"
          />

          <b-numberinput
            v-if="item.fieldType == 'numberinput'"
            v-model="numberInputs[item.field]"
            :step="item.step"
            :min="item.min"
            :max="item.max"
            size="is-small"
            type="button"
            :disabled="item.readonly"
            @keyup.native="checkNumberkey($event, item.field)"
            @keydown.native="preventExponential"
            @input="setNumberParam($event, item.field)"
            @blur="setDefaultNum($event, item.field)"
          />

          <b-checkbox
            v-if="item.fieldType == 'checkbox'"
            v-model="search[item.field]"
            true-value="true"
            false-value="false"
            :disabled="item.readonly"
          />
        </b-field>
      </form>
    </div>
  </section>
</template>

<script>
export default {
  props: {
    data: {
      type: Array,
    },
    primaryKey: {
      type: Array,
    },
    methodName: {
      type: String,
    },
    serviceName: {
      type: String,
    },
    autoComMethod: {
      type: String,
    },
    // collapse 버튼 추가 설정 유무
    collapse: {
      type: Boolean,
    },
    disableAdd: {
      type: Boolean,
      default: false,
    },
    disableModify: {
      type: Boolean,
      default: false,
    },
    disableDelete: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      search: {},
      month: [
        '1월',
        '2월',
        '3월',
        '4월',
        '5월',
        '6월',
        '7월',
        '8월',
        '9월',
        '10월',
        '11월',
        '12월',
      ],
      day: ['일', '월', '화', '수', '목', '금', '토'],
      datePick: {},
      property: { params: [] },
      searchParam: {},
      nextTickFlag: true,
      selectedData: [],
      autoComData: [''],
      name: {},
      selected: null,
      numberInputs: {},
      // collapse 유무 flag
      isCollapse: false,
      userId: this.$user.id,
    };
  },
  mounted() {
    this.init();
  },
  methods: {
    init() {
      this.property.params = this.data.filter((datum) => !datum.hidden);
      const servicePath = `/${this.serviceName}/${this.methodName}`;
      this.property.params
        .filter((combo) => combo.fieldType === 'combobox')
        .forEach((combo) => {
          const param = { where: combo.where };
          return this.$service.read(servicePath, param).then(({ data }) => {
            combo.comboData = data;
            combo.comboData.unshift({
              value: null,
              description: ' -- 선택 -- ',
            });
            return combo;
          });
        });
    },
    gridClick(params) {
      this.selectedData = params;
      this.nextTickFlag = false;
      Object.keys(params).forEach((key) => {
        this.search[key] = params[key];
        this.name[key] = params[key];
        if (typeof params[key] === 'number') {
          this.numberInputs[key] = params[key];
        }
      });
      this.$nextTick(() => {
        this.nextTickFlag = true;
      });
    },
    searchDo() {
      const dateCheck = this.checkDate();
      if (!dateCheck) {
        alert('시작일이 종료일보다 큽니다.');
        // this.$buefy.dialog.alert({
        //     message: '코드값은 필수입력입니다.',
        //   });
        return;
      }
      this.$emit('searchAction', { search: this.search });
    },
    checkDate() {
      let dateFlag = true;
      if (new Date(this.search.startDate) > new Date(this.search.endDate)) {
        dateFlag = false;
      }

      return dateFlag;
    },
    dataPick($event, field) {
      if ($event == null) return;
      let date = $event.toLocaleDateString('ko-KR');
      date = date.replace(/\s/gi, '');
      date = date.split('.');
      if (date[1] < 10) {
        date[1] = `0${date[1]}`;
      }
      if (date[2] < 10) {
        date[2] = `0${date[2]}`;
      }
      const newDate = `${date[0]}-${date[1]}-${date[2]}`;
      this.search[field] = newDate;
    },
    createData() {
      this.search.createUser = this.$user.id;
      if (
        this.search[this.primaryKey] == null
        || this.search[this.primaryKey] === ''
      ) {
        if (
          this.search[this.primaryKey] == null
          || this.search[this.primaryKey] === ''
        ) {
          this.search[this.primaryKey] = this.primaryKey;
          this.$buefy.dialog.confirm({
            message: '추가하시겠습니까?',
            onConfirm: () => {
              this.$emit('grid-create', this.search);
            },
          });
        } else {
          this.$buefy.dialog.alert({
            message: '코드값은 필수입력입니다.',
          });
        }
      } else {
        this.$buefy.dialog.confirm({
          message: '추가하시겠습니까?',
          onConfirm: () => {
            this.$emit('grid-create', this.search);
          },
        });
      }
    },
    modifyData() {
      this.search.updateUser = this.$user.id;
      let keyFlag = true;
      for (let i = 0; i < this.primaryKey.length; i += 1) {
        if (
          this.search[this.primaryKey[i]]
          !== this.selectedData[this.primaryKey[i]]
        ) {
          keyFlag = false;
        }
      }
      if (!keyFlag) {
        this.$buefy.dialog.confirm({
          message: '코드값은 수정 될 수 없습니다. 새로 추가 하시겠습니까?',
          onConfirm: () => {
            this.$emit('grid-create', this.search);
          },
        });
      } else {
        this.$buefy.dialog.confirm({
          message: '수정하시겠습니까?',
          onConfirm: () => {
            this.$emit('grid-modify', this.search);
          },
        });
      }
    },
    deleteData() {
      this.search.deleteUser = this.$user.id;
      const value = {};
      for (let i = 0; i < this.primaryKey.length; i += 1) {
        value[this.primaryKey[i]] = this.selectedData[this.primaryKey[i]];
      }
      this.$buefy.dialog.confirm({
        message: '삭제하시겠습니까?',
        onConfirm: () => {
          this.$emit('grid-delete', value);
        },
      });
    },
    editSuccess() {
      this.search = {};
    },
    selectAutoData(item) {
      const param = { where: item.field };
      const autoComPath = `/${this.serviceName}/${this.autoComMethod}`;
      this.$service.read(autoComPath, param).then(({ data }) => {
        for (let i = 0; i < data.length; i += 1) {
          this.autoComData[i] = data[i][item.field];
        }
      });
    },
    option(value) {
      const item = value;
      this.search = this.name;
      item.comboData = this.autoComData.filter(
        (option) => option
          .toString()
          .toLowerCase()
          .indexOf(this.search[item.field]) >= 0,
      );
    },
    checkNumberkey(e, field) {
      if (!(e.keyCode >= 48 && e.keyCode <= 57)
        && !(e.keyCode >= 96 && e.keyCode <= 105)
        && !(e.keyCode === 8 || e.keyCode === 13)
        && !(e.keyCode === 37 || e.keyCode === 39)) {
        e.target.value = this.search[field];
      }
    },
    preventExponential(e) {
      if (e.keyCode === 69) {
        e.preventDefault();
      }
    },
    setNumberParam(e, field) {
      if (this.search[field] === undefined) {
        this.search[field] = 0;
      }
      if (typeof e === 'number') {
        this.search[field] = e;
      }
      this.$set(this.numberInputs, field, this.search[field]);
    },
    setDefaultNum(e, field) {
      if (e.target.value === '') {
        this.search[field] = 0;
        this.$set(this.numberInputs, field, 0);
        e.target.value = 0;
      }
    },
    // isCollapse(collapse 유무) 토글 이벤트, 그 값을 부모컴포넌트에 전달
    toggleCollapse() {
      this.isCollapse = !this.isCollapse;
      this.$emit('toggle-collapse', this.isCollapse);
    },
  },
};
</script>

<style>
.textarea {
  width: 100%;
}
/* Collapse 버튼 테두리 제거 */
.collapse-btn {
  border: none;
}
/* Collapse일때 버튼 및 텍스트를 세로로 배치 */
.collapse-item {
  flex-direction: column;
}
/* Collapse일때 padding 0 */
.collapse-message {
  padding: 0;
}
/* Collapse일때 접히는 부분 너비를 컨텐츠 크기에 맞게 변경 */
.class-collapse {
  flex: none !important;
  width: auto !important;
}
/* Collapse일때 가운데 메인 컨텐츠부분이 남은 영역 차지하게 변경 */
.mainItem {
  flex: auto !important;
}
</style>
