<template>
  <div class="container">
    <div class="page-titleZone flex justify-between align-center">
      <p class="main-title flex80">사용자 관리</p>
      <PageNavigation />
    </div>
    <div class="content-wrap">
      <div class="content content-box flex100">
        <div class="column-list">
          <div class="content-titleZone flex justify-between align-center">
            <p class="box-title">사용자 목록</p>
            <div class="search-bar">
              <div class="flex justify-end align-center">
                <select class="square-select" v-model="search_data.key">
                  <option :value="null">선택</option>
                  <option value="ui.user_id">아이디</option>
                  <option value="ui.user_nm">이름</option>
                  <option value="orgnzt_info.dept_nm">부서</option>
                </select>
                <div class="search-square">
                  <div class="flex justify-end align-center no-gutter">
                    <input type="text" class="square-input flex90" placeholder="검색어를 입력해 주세요." v-model="search_data.value" @keyup.enter="fnSelectUserList" />
                    <button class="square-button blue-btn flex10" @click="fnSelectUserList">
                      <svg-icon type="mdi" :path="searchPath" class="square-icon"></svg-icon>
                    </button>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <div class="flex justify-between align-center">
            <div class="count-zone">
              <p>총 <span>{{ userList.length }}</span>건 중 <span>{{ userSelectList.length }}</span>건 선택</p>
            </div>
            <div class="cunt-selectZone">
              <select v-model="search.perPage" @change="fnSelectUserList">
                <option value="10">10개 보기</option>
                <option value="20">20개 보기</option>
              </select>
            </div>
          </div>
          <div class="table-zone">
            <table class="list-table">
              <colgroup>
                <col style="width: 5%" />
                <col style="width: 5%" />
                <col style="width: 17%" />
                <col style="width: 17%" />
                <col style="width: 17%" />
                <col style="width: 17%" />
                <col style="width: 17%" />
                <col style="width: 5%" />
              </colgroup>
              <thead>
                <tr>
                  <th>
                    <input type="checkbox" v-model="isChkAll" @change="fnChkAll()" />
                  </th>
                  <th>번호</th>
                  <th>아이디</th>
                  <th>이름</th>
                  <th>이메일</th>
                  <th>부서</th>
                  <th>등록날짜</th>
                  <th>잠김여부</th>
                </tr>
              </thead>
              <tbody>
                <template v-if="userList.length > 0">
                  <tr v-for="(item, idx) in userList" :key="idx" @click="fnSelectUser(item.userId)">
                    <td>
                      <input type="checkbox" :value="item" v-model="userSelectList" @click.stop="" @change="fnChangeChk" />
                    </td>
                    <td>{{ search.totalRows - idx - (search.currentPage - 1) * search.perPage }}</td>
                    <td>{{ item.userId }}</td>
                    <td>{{ item.userNm }}</td>
                    <td>{{ item.userEmail }}</td>
                    <td>{{ item.deptNm }}</td>
                    <td>{{ $filters.dateTime(item.creatDt) }}</td>
                    <td>{{ item.lockAt ? "잠금" : "-" }}</td>
                  </tr>
                </template>
                <tr v-else>
                  <td colspan="8">등록된 데이터가 없습니다.</td>
                </tr>
              </tbody>
            </table>
          </div>
          <div class="flex justify-end">
            <button class="red-border-btn small-btn" @click="fnDeleteUser">선택 삭제</button>
          </div>
          <PaginationButton v-model:currentPage="search.currentPage" :perPage="search.perPage" :totalCount="search.totalRows" :maxRange="5" :click="fetchMemberList" />
        </div>
        <div class="data-set">
          <div class="form-box">
            <div class="content-titleZone">
              <p class="box-title" v-if="editMode == 'create'">사용자 등록</p>
              <p class="box-title" v-else>사용자 수정</p>
            </div>
            <div class="table-zone">
              <table class="form-table2">
                <colgroup>
                  <col style="width: 10%" />
                  <col style="width: 40%" />
                  <col style="width: 10%" />
                  <col style="width: 40%" />
                </colgroup>
                <tbody>
                  <tr>
                    <th>아이디</th>
                    <td style="display: flex">
                      <input type="text" class="full-input" v-model="currentUser.userId" :disabled="editMode == 'update'" />
                      <button class="small-btn blue-border-btn" style="flex-grow: 1" v-if="editMode == 'create'" @click="fnDuplicateChk('id')">중복확인</button>
                    </td>
                    <th>이름</th>
                    <td>
                      <input type="text" class="full-input" v-model="currentUser.userNm" />
                    </td>
                  </tr>
                  <tr v-if="editMode == 'create'">
                    <th>비밀번호</th>
                    <td>
                      <input type="password" class="full-input" style="width: 100%" v-model="currentUser.userPassword" />
                    </td>
                    <th>비밀번호 확인</th>
                    <td>
                      <input type="password" class="full-input" style="width: 100%" v-model="userPasswordConfirm" />
                    </td>
                  </tr>
                  <tr>
                    <th>이메일</th>
                    <td style="display: flex">
                      <input type="text" class="full-input" v-model="currentUser.userEmail" />
                      <button class="small-btn blue-border-btn" style="flex-grow: 1" @click="fnDuplicateChk('email')">중복확인</button>
                    </td>
                    <th>부서</th>
                    <td>
                      <select class="full-select" v-model="currentUser.dept_code">
                        <option :value="null" disabled>부서를 선택해주세요.</option>
                        <option v-for="(item, idx) in deptList" :key="idx" :value="item.dept_code"> {{ item.dept_nm }} </option>
                      </select>
                    </td>
                  </tr>
                  <tr v-if="editMode == 'update'">
                    <th>잠김여부</th>
                    <td style="display: flex">
                      <input type="text" class="full-input" :value="currentUser.lockAt ? '잠금 (사용불가)' : '미잠금 (사용가능)'" readonly>
                      <button class="blue-border-btn small-btn" style="flex-grow: 1" v-if="currentUser.lockAt" @click="fnUpdateUserLockAt">잠금해제</button>
                    </td>
                    <th></th>
                    <td></td>
                  </tr>
                </tbody>
              </table>
            </div>
            <div class="flex justify-end">
              <button class="blue-border-btn small-btn" v-if="editMode == 'update'" @click="fnOpenModal">비밀번호 변경</button>
              <button class="blue-btn small-btn" v-if="editMode == 'create'" @click="fnInsertUser">등록</button>
              <button class="blue-btn small-btn" v-else @click="fnUpdateUser">수정</button>
              <button class="blue-border-btn small-btn" @click="fnCancel">취소</button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <!-- 비밀번호 변경 모달 -->
  <div v-show="modalOpen" class="modal-wrapper">
    <div class="modal-container small-modal">
      <div class="modal-title">
        <div class="flex justify-between align-center">
          <h2>비밀번호 변경</h2>
          <button class="close-btn" @click="fnCloseModal">X</button>
        </div>
      </div>
      <div class="modal-content-monthly">
        <div class="table-zone">
          <table class="form-table">
            <colgroup>
              <col style="width: 40%" />
              <col style="width: 60%" />
            </colgroup>
            <tbody>
              <tr>
                <th>새 비밀번호</th>
                <td>
                  <input type="password" class="full-input" v-model="userPassword" />
                </td>
              </tr>
              <tr>
                <th>새 비밀번호 확인</th>
                <td>
                  <input type="password" class="full-input" v-model="userPasswordConfirm" />
                </td>
              </tr>
            </tbody>
          </table>
          <div class="modal-end flex justify-between" style="flex-wrap: nowrap;">
            <button class="blue-btn large-btn" @click="fnUpdateUserPassword">수정</button>
            <button class="blue-border-btn small-btn" @click="fnCancel"><span v-if="editMode == 'create'">초기화</span><span v-else>취소</span></button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import axios from "axios";
// icon용 svg import
import SvgIcon from "@jamescoyle/vue-icon";
import { mdiClose, mdiMagnify } from "@mdi/js";
// 컴포넌트 import
import PageNavigation from "../../component/PageNavigation.vue";
import PaginationButton from "../../component/PaginationButton.vue";

export default {
  components: { SvgIcon, PageNavigation, PaginationButton },

  data() {
    return {
      // icon용 svg path
      closePath: mdiClose,
      searchPath: mdiMagnify,

      // 검색
      search: this.$getDefaultSerchVO(),
      search_data: this.$getDefaultSerchItem(null, "string"),

      // default
      editMode: 'create',

      memberVO: {},
      originUser: {},
      currentUser: {},

      userPassword: null,
      userPasswordConfirm: null,

      isChkAll: false,
      userList: [],
      userSelectList: [],

      deptList: [],

      // 비밀번호 변경
      modalOpen: false,

      // 중복검사
      isIdChk: false,
      isEmailChk: false,
    };
  },

  mounted() {
    this.fnSelectUser(); // 사용자 개별 조회
    this.fnSelectUserList(); // 사용자 목록 조회
    this.fnSelectDeptList(); // 부서 목록 조회
  },

  watch: {
    //아이디 값 변경 시 중복 검사 false로 변경
    "currentUser.userId"() {
      this.isIdChk = false;
    },
    //이메일 값 변경 시 중복 검사 false로 변경
    "currentUser.userEmail"() {
      this.isEmailChk = false;
    },
  },

  methods: {
    // 사용자 목록 조회
    fnSelectUserList() {
      const vm = this;
      // 데이터 세팅
      let data = vm.search;
      data.searchObjectList = []; // 초기화
      data.searchObjectList.push(vm.search_data);
      // 실행
      axios({
        url: "/member/list",
        method: "post",
        headers: { "Content-Type": "application/json; charset=UTF-8" },
        data: data,
      })
        .then(response => {
          if (response.data != null) {
            vm.userList = response.data.resultData.members;
            vm.search = response.data.resultData.searchVO;
          } else {
            this.$showAlert("사용자 관리", "에러가 발생했습니다. 관리자에게 문의해 주세요.");
          }
        })
        .catch(error => {
          vm.$showAlert("사용자 관리", "목록 불러오기 오류, 관리자에게 문의바랍니다.");
        });
    },
    // 사용자 목록 전체 선택
    fnChkAll() {
      if (this.isChkAll) {
        this.userSelectList = this.userList;
      } else {
        this.userSelectList = [];
      }
    },
    // 사용자 목록 개별 선택
    fnChangeChk() {
      if (this.userSelectList.length == this.userList.length) {
        this.isChkAll = true;
      } else {
        this.isChkAll = false;
      }
    },
    // 사용자 선택 삭제
    async fnDeleteUser() {
      const vm = this;
      // 선택 목록 확인
      if (vm.userSelectList.length === 0) {
        vm.$showAlert("사용자 관리", "선택한 사용자가 없습니다.");
        return;
      }
      // 삭제 확인
      if (!(await vm.$showConfirm("사용자 관리", "선택한 사용자를 삭제하시겠습니까?"))) {
        return;
      }

      // 실행
      axios({
        url: "/member",
        method: "delete",
        headers: { "Content-Type": "application/json; charset=UTF-8" },
        data: vm.userSelectList,
      })
        .then(response => {
          if (response.data.checkMessage.status === 200) {
            vm.$showAlert("사용자 관리", "선택한 사용자가 삭제되었습니다.");

            // 삭제 후 작업
            vm.isChkAll = false; // 체크 박스 리셋
            vm.userSelectList = []; // 사용자 선택 목록 초기화
            vm.fnSelectUserList(); // 전체 재조회
          } else {
            vm.$showAlert("사용자 관리", response.data.checkMessage.message);
          }
        })
        .catch(error => {
          vm.$showAlert("사용자 관리", "처리 중 오류가 발생했습니다. 관리자에게 문의바랍니다.");
        });
    },

    // 부서 목록 조회
    fnSelectDeptList() {
      const vm = this;
      // 데이터 세팅팅
      let search = Object.assign({}, this.$getDefaultSerchVO());
      search.currentPage = 0;
      search.perPage = 0;
      // 실행
      axios({
        url: "/department/departments",
        method: "post",
        headers: { "Content-Type": "application/json; charset=UTF-8" },
        data: search,
      })
        .then(response => {
          if (response.data != null) {
            vm.deptList = response.data.resultData.selectDeptList;
          } else {
            this.$showAlert("사용자 관리", "에러가 발생했습니다. 관리자에게 문의해 주세요.");
          }
        })
        .catch(error => {
          vm.$showAlert("사용자 관리", "목록 불러오기 오류, 관리자에게 문의바랍니다.");
        });
    },

    // 사용자 등록
    fnInsertUser() {
      const vm = this;
      // 유효성 검사
      if (!vm.insertValidation()) {
        return;
      }
      // 실행
      axios({
        url: "/member",
        method: "post",
        headers: { "Content-Type": "application/json; charset=UTF-8" },
        data: vm.currentUser,
      })
        .then(response => {
          if (response.data.checkMessage.status === 200) {
            vm.$showAlert("사용자 관리", "사용자 등록이 완료되었습니다.");
            vm.currentUser = Object.assign({}, vm.memberVO); // 초기화
            vm.fnSelectUserList();
          } else {
            vm.$showAlert("사용자 관리", response.data.checkMessage.message);
          }
        })
        .catch(error => {
          vm.$showAlert("사용자 관리", "사용자 등록에 실패했습니다. 다시 시도해주세요.");
        });
    },

    // 사용자 개별 조회
    fnSelectUser(userId) {
      const vm = this;
      // 데이터 세팅
      let url = null;
      if (vm.$isEmpty(userId)) {
        url = "/member/selectUser";
      } else {
        url = "/member/selectUser/" + userId;
      }
      // 실행
      axios({
        url: url,
        method: "post",
        headers: { "Content-Type": "application/json; charset=UTF-8" },
      })
        .then(response => {
          if (vm.$isEmpty(userId)) {
            vm.memberVO = response.data;
          } else {
            vm.editMode = 'update';
            vm.originUser = response.data;
            vm.currentUser = Object.assign({}, response.data);
          }
        })
        .catch(error => {
          vm.$showAlert("사용자 관리", "불러오기 오류, 관리자에게 문의바랍니다.");
        });
    },

    // 사용자 수정
    fnUpdateUser() {
      const vm = this;
      // 유효성 검사
      if (!vm.updateValidation()) {
        return;
      }
      // 실행
      axios({
        url: "/member",
        method: "put",
        headers: { "Content-Type": "application/json; charset=UTF-8" },
        data: vm.currentUser
      })
        .then(response => {
          if (response.data.checkMessage.status === 200) {
            vm.$showAlert("사용자 관리", "사용자 정보가 수정되었습니다.");
            vm.originUser = Object.assign({}, vm.memberVO); // 초기화
            vm.currentUser = Object.assign({}, vm.memberVO); // 초기화
            vm.editMode = 'create';
            vm.fnSelectUserList();
          } else {
            vm.$showAlert("사용자 관리", response.data.checkMessage.message);
          }
        })
        .catch(error => {
          vm.$showAlert("사용자 관리", "수정 오류, 관리자에게 문의해주세요.");
        });
    },

    // 중복확인 버튼 동작
    fnDuplicateChk(type) {
      if (type == 'id') {
        this.idDuplicateChk();
      } else if (type == 'email') {
        this.emailDuplicateChk();
      }
    },
    // 아이디 중복 검사
    idDuplicateChk() {
      const vm = this;
      // 유효성 검사
      if (!vm.$idCheck(vm.currentUser.userId)) {
        vm.$showAlert("사용자 관리", "아이디 형식이 올바르지 않습니다. (5~20자의 영문 소문자, 숫자와 특수기호(_),(-)만 사용가능)");
        return false;
      }
      // 실행
      axios({
        url: "/member/" + vm.currentUser.userId,
        method: "get",
        headers: { "Content-Type": "application/json; charset=UTF-8" },
      })
        .then(response => {
          if (response.data.resultData.checkDuplicateUserId) {
            vm.isIdChk = false;
            vm.$showAlert("사용자 관리", "사용중인 아이디입니다.");
          } else {
            vm.isIdChk = true;
            vm.$showAlert("사용자 관리", "사용할 수 있는 아이디입니다.");
          }
        })
        .catch(error => {
          this.$showAlert("사용자 관리", "에러가 발생했습니다. 관리자에게 문의해 주세요.");
        });
    },
    // 이메일 중복 검사
    emailDuplicateChk() {
      const vm = this;
      // 유효성 검사
      if (!vm.validationEmail()) {
        return;
      }
      // 실행
      axios({
        url: "/member/email",
        method: "get",
        headers: { "Content-Type": "application/json; charset=UTF-8" },
        data: vm.currentUser.userEmail,
      })
        .then(response => {
          if (response.data.resultData.result) {
            vm.$showAlert("사용자 관리", "사용중인 이메일입니다.");
            vm.isEmailChk = false;
          } else {
            vm.$showAlert("사용자 관리", "사용할 수 있는 이메일입니다.");
            vm.isEmailChk = true;
          }
        })
        .catch(error => {
          this.$showAlert("사용자 관리", "에러가 발생했습니다. 관리자에게 문의해 주세요.");
        });
    },

    // 사용자 잠금 해제
    fnUpdateUserLockAt() {
      const vm = this;
      // 실행
      axios({
        url: "/member/updateUser/LockAt/" + vm.currentUser.userId,
        method: "post",
        headers: { "Content-Type": "application/json; charset=UTF-8" },
      })
        .then(response => {
          if (response.data.checkMessage.status === 200) {
            vm.$showAlert("사용자 관리", "사용자 잠금이 해제되었습니다.");
            vm.fnSelectUser(vm.currentUser.userId); // 사용자 개별 재조회
          } else {
            vm.$showAlert("사용자 관리", response.data.checkMessage.message);
          }
        })
        .catch(error => {
          vm.$showAlert("사용자 관리", "수정 오류, 관리자에게 문의해주세요.");
        });
    },

    // 사용자 비밀번호 변경 모달 열기
    fnOpenModal() {
      this.userPassword = null;
      this.userPasswordConfirm = null;

      this.modalOpen = true;
    },
    // 사용자 비밀번호 변경 모달 열기
    fnCloseModal() {
      this.modalOpen = false;
    },
    // 사용자 비밀번호 변경
    fnUpdateUserPassword() {
      const vm = this;
      // 유효성 검사
      vm.currentUser.userPassword = vm.userPassword;
      if (!vm.validationPassword()) {
        return;
      }
      // 실행
      axios({
        url: "/member",
        method: "patch",
        headers: {
          "Content-Type": "application/json",
        },
        data: {
          userId: vm.currentUser.userId,
          userPassword: vm.userPassword,
        },
      })
        .then(response => {
          if (response.data.resultData.result) {
            vm.$showAlert("비밀번호 변경", "비밀번호 변경에 성공했습니다.");
            vm.modalOpen = false;
          } else {
            vm.$showAlert("비밀번호 변경", "비밀번호 변경에 실패했습니다. 다시 시도해주세요.");
          }
        })
        .catch(error => {
          vm.$showAlert("비밀번호 변경", "비밀번호 변경에 실패했습니다. 다시 시도해주세요.");
        });
    },

    // 사용자 등록 취소
    fnCancel() {
      if (this.editMode == 'update') {
        this.editMode = 'create';
      }
      // 초기화
      this.userPassword = null;
      this.userPasswordConfirm = null;
      this.currentUser = Object.assign({}, this.memberVO);
    },

    // #유효성 검사
    // 등록용 유효성 검사
    insertValidation() {
      // 아이디 유효성 검사
      if (!this.validationId()) {
        return false;
      }
      // 아이디 중복 검사 여부
      if (!this.isIdChk) {
        this.$showAlert("사용자 관리", "아이디 중복 확인 후 시도해주세요.");
        return false;
      }

      // 이름 유효성 검사
      if (!this.validationName()) {
        return false;
      }

      // 비밀번호 유효성 검사
      if (!this.validationPassword()) {
        return false;
      }

      // 이메일 유효성 검사
      if (!this.validationEmail()) {
        return false;
      }
      // 이메일 중복 검사 여부
      if (!this.isEmailChk) {
        this.$showAlert("사용자 관리", "이메일 중복확인 후 등록해주세요.");
        return false;
      }

      return true;
    },
    // 수정용 유효성 검사
    updateValidation() {
      if (JSON.stringify(this.currentUser) === JSON.stringify(this.originUser)) {
        this.$showAlert("사용자 관리", "수정된 정보가 없습니다.");
        return;
      }

      // 이름 유효성 검사
      if (!this.validationName()) {
        return false;
      }

      // 이메일 유효성 검사
      if (!this.validationEmail()) {
        return false;
      }

      // 이메일 중복 검사 여부
      if (!this.isEmailChk) {
        this.$showAlert("사용자 관리", "이메일 중복확인 후 수정해주세요.");
        return false;
      }

      return true;
    },
    // 아이디 유효성 검사
    validationId() {
      let id = this.currentUser.userId;

      if (this.$isEmpty(id)) {
        this.$showAlert("사용자 관리", "아이디를 입력해주세요.");
        return false;
      }

      if (!this.$idCheck(id)) {
        this.$showAlert("사용자 관리", "아이디 형식이 올바르지 않습니다. (5~20자의 영문 소문자, 숫자와 특수기호(_),(-)만 사용가능)");
        return false;
      }

      return true;
    },
    // 이름 유효성 검사
    validationName() {
      let name = this.currentUser.userNm;

      if (this.$isEmpty(name)) {
        this.$showAlert("사용자 관리", "이름을 입력해주세요.");
        return false;
      }

      let validateName = /^[가-힣A-Za-z\s]+$/;
      if (!validateName.test(name)) {
        this.$showAlert("사용자 관리", "이름에 숫자와 특수문자를 입력할 수 없습니다.");
        return false;
      }

      return true;
    },
    // 비밀번호 유효성 검사
    validationPassword() {
      if (this.$isEmpty(this.currentUser.userPassword)) {
        this.$showAlert("사용자 관리", "비밀번호를 입력해주세요.");
        return false;
      }

      if (!this.$pwCheck(this.currentUser.userPassword)) {
        this.$showAlert("사용자 관리", "비밀번호 형식이 올바르지 않습니다. (8~16자의 영문 대문자, 소문자, 숫자, 특수문자 사용가능)");
        return false;
      }

      if (this.currentUser.userPassword !== this.userPasswordConfirm) {
        this.$showAlert("사용자 관리", "비밀번호가 일치하지 않습니다. 다시 입력해주세요.");
        return false;
      }

      return true;
    },
    // 이메일 유효성 검사
    validationEmail() {
      let email = this.currentUser.userEmail;

      // 1. null검사
      if (this.$isEmpty(email)) {
        this.$showAlert("사용자 관리", "이메일을 입력해주세요.");
        return false;
      }

      // 2. 정규식 검사
      if (!this.$email(email)) {
        this.$showAlert("사용자 관리", "이메일 형식이 올바르지 않습니다.");
        return false;
      }

      return true;
    },
  },
};
</script>