package com.style24.admin.biz.service;

import java.util.Collection;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.style24.admin.biz.dao.TsaSystemDao;
import com.style24.admin.support.security.session.TsaSession;
import com.style24.core.support.message.TscMessageByLocale;
import com.style24.persistence.domain.Alarm;
import com.style24.persistence.domain.AlarmReceiver;
import com.style24.persistence.domain.Batch;
import com.style24.persistence.domain.BatchLog;
import com.style24.persistence.domain.CommonCode;
import com.style24.persistence.domain.Menu;
import com.style24.persistence.domain.MenuAccessHst;
import com.style24.persistence.domain.MenuRole;
import com.style24.persistence.domain.SampleFile;
import com.style24.persistence.domain.User;
import com.style24.persistence.domain.UserHst;
import com.style24.persistence.domain.UserMenu;

import lombok.extern.slf4j.Slf4j;

/**
 * 시스템 Service
 *
 * @author gagamel
 * @since 2020. 10. 7
 */
@Service
@Slf4j
public class TsaSystemService {

	@Autowired
	private TscMessageByLocale message;

	@Autowired
	private TsaSystemDao systemDao;

	/**
	 * 사용자 목록
	 * @param user - 사용자 정보
	 * @return
	 * @author gagamel
	 * @since 2020. 10. 7
	 */
	public Collection<User> getUserList(User user) {
		return systemDao.getUserList(user);
	}

	/**
	 * 사용자 목록 삭제 처리
	 * @param userList - 사용자 목록
	 * @author gagamel
	 * @since 2020. 10. 7
	 */
	@Transactional("shopTxnManager")
	public void deleteUserList(Collection<User> userList) {
		for (User user : userList) {
			user.setUpdNo(TsaSession.getInfo().getUserNo());
			systemDao.deleteUser(user);
			this.deleteUserAccount(user); // 계정말소
		}
	}

	/**
	 * 사용자 정보 조회
	 * @param userNo - 사용자번호
	 * @return
	 * @author gagamel
	 * @since 2020. 10. 7
	 */
	public User getUser(Integer userNo) {
		return systemDao.getUser(userNo);
	}

	/**
	 * 사용자ID 건수 조회
	 * @param userId - 사용자ID
	 * @return
	 * @author gagamel
	 * @since 2020. 10. 7
	 */
	public int getUserIdCount(String userId) {
		return systemDao.getUserIdCount(userId);
	}

	/**
	 * 사용자 정보 저장 처리
	 * @param user - 사용자 정보
	 * @author gagamel
	 * @since 2020. 10. 7
	 */
	@Transactional("shopTxnManager")
	public void saveUser(User user) {
		user.setRegNo(TsaSession.getInfo().getUserNo());
		user.setUpdNo(TsaSession.getInfo().getUserNo());

		// 사용자 저장 처리
		systemDao.saveUser(user);

		// 등록된 사용자번호 값 가져오기
		Integer userNo = user.getUserNo();
		log.info("userNo: {}", userNo);
		user.setUserNo(userNo);

		if (user.getMode().equals("N")) {
			this.createUserAccount(user); // 계정생성
		} else if (user.getMode().equals("U")) {
			if (user.getUseYn().equals("N")) {
				this.deleteUserAccount(user); // 계정말소
			} else {
				this.restoreUserAccount(user); // 계정복원
			}
		}

		// 권한이 변경되었으면
		if (user.getRoleChangeYn().equals("Y")) {
			// 사용자 전체메뉴 삭제
			systemDao.deleteUserAllMenu(user.getUserNo());

			// 사용자 전체메뉴 생성
			systemDao.createUserAllMenu(user);

			if (user.getMode().equals("U")) {
				this.createUserRoleChange(user); // 권한변경
			}
		}
	}

	/**
	 * 사용자정보변경이력 생성 - 계정생성
	 * @param user - 사용자 정보
	 * @author gagamel
	 * @since 2020. 10. 8
	 */
	private void createUserAccount(User user) {
		UserHst userHst = new UserHst();
		userHst.setUserNo(user.getUserNo());
		userHst.setChgGb("G049_10"); // 계정생성
		userHst.setRegNo(TsaSession.getInfo().getUserNo());
		systemDao.createUserInfoChangeHistory(userHst);
	}

	/**
	 * 사용자정보변경이력 생성 - 계정말소
	 * @param user - 사용자 정보
	 * @author gagamel
	 * @since 2020. 10. 8
	 */
	private void deleteUserAccount(User user) {
		UserHst userHst = new UserHst();
		userHst.setUserNo(user.getUserNo());
		userHst.setChgGb("G049_11"); // 계정말소
		userHst.setRegNo(TsaSession.getInfo().getUserNo());
		systemDao.createUserInfoChangeHistory(userHst);
	}

	/**
	 * 사용자정보변경이력 생성 - 계정복원
	 * @param user - 사용자 정보
	 * @author gagamel
	 * @since 2020. 10. 8
	 */
	private void restoreUserAccount(User user) {
		UserHst userHst = new UserHst();
		userHst.setUserNo(user.getUserNo());
		userHst.setChgGb("G049_12"); // 계정복원
		userHst.setRegNo(TsaSession.getInfo().getUserNo());
		systemDao.createUserInfoChangeHistory(userHst);
	}

	/**
	 * 사용자정보변경이력 생성 - 권한변경
	 * @param user - 사용자 정보
	 * @author gagamel
	 * @since 2020. 10. 8
	 */
	private void createUserRoleChange(User user) {
		UserHst userHst = new UserHst();
		userHst.setUserNo(user.getUserNo());
		userHst.setChgGb("G049_20"); // 권한변경
		userHst.setOrgRoleCd(TsaSession.getInfo().getRoleCd());
		userHst.setRoleCd(user.getRoleCd());
		userHst.setRegNo(TsaSession.getInfo().getUserNo());
		systemDao.createUserInfoChangeHistory(userHst);
	}

	/**
	 * 임시비밀번호 조회
	 * @param length - 비밀번호 자릿수
	 * @return 임시비밀번호
	 * @author gagamel
	 * @since 2020. 10. 7
	 */
	public String getTemporaryPassword(int length) {
		return systemDao.getTemporaryPassword(length);
	}

	/**
	 * 사용자 비밀번호 수정
	 * @param user - 사용자 정보
	 * @since 2020. 10. 7
	 */
	@Transactional("shopTxnManager")
	public void updateUserPassword(User user) {
		systemDao.updateUserPassword(user);

		// 사용자정보변경이력 생성 - 비밀번호변경
		UserHst userHst = new UserHst();
		userHst.setUserNo(user.getUserNo());
		userHst.setChgGb("G049_30"); // 비밀번호변경
		userHst.setRegNo(TsaSession.getInfo().getUserNo());
		systemDao.createUserInfoChangeHistory(userHst);
	}

	/**
	 * 사용자 메뉴 목록
	 * @param userNo - 사용자번호
	 * @return
	 * @author gagamel
	 * @since 2020. 10. 7
	 */
	public Collection<UserMenu> getUserMenuList(Integer userNo) {
		return systemDao.getUserMenuList(userNo);
	}

	/**
	 * 사용자 메뉴 목록 저장 처리
	 * @param userMenuList - 사용자 메뉴 목록
	 * @author gagamel
	 * @since 2020. 10. 7
	 */
	@Transactional("shopTxnManager")
	public void saveUserMenuList(Collection<UserMenu> userMenuList) {
		if (userMenuList == null || userMenuList.isEmpty())
			throw new IllegalStateException(message.getMessage("FAIL_1001"));

		int cnt = 0;
		log.info("saveUserMenuList userMenuList={}", userMenuList);

		for (UserMenu adminMenu : userMenuList) {
			if (cnt++ == 0) {
				// 사용자 전체메뉴 삭제
				systemDao.deleteUserAllMenu(adminMenu.getUserNo());
			}

			adminMenu.setRegNo(TsaSession.getInfo().getUserNo());
			adminMenu.setUpdNo(TsaSession.getInfo().getUserNo());
			adminMenu.setUseRole("RCUD");

			// 사용자 메뉴 생성
			systemDao.createUserMenu(adminMenu);
		}
	}

	/**
	 * 메뉴 목록
	 * @param pmenuId - 상위메뉴ID
	 * @return
	 * @author gagamel
	 * @since 2020. 10. 7
	 */
	public Collection<Menu> getMenuList(String pmenuId) {
		Menu menu = new Menu();
		menu.setPmenuId(pmenuId);
		return systemDao.getMenuList(menu);
	}

	/**
	 * 메뉴 목록 저장 처리
	 * @param menuList - 메뉴 목록
	 * @author gagamel
	 * @since 2020. 10. 7
	 */
	@Transactional("shopTxnManager")
	public void saveMenuList(Collection<Menu> menuList) {
		if (menuList == null || menuList.isEmpty())
			throw new IllegalStateException(message.getMessage("FAIL_1001"));

		for (Menu menu : menuList) {
			menu.setRegNo(TsaSession.getInfo().getUserNo());
			menu.setUpdNo(TsaSession.getInfo().getUserNo());
			systemDao.saveMenu(menu);
		}
	}

	/**
	 * 메뉴ID 건수 조회
	 * @param menuId - 메뉴ID
	 * @return
	 * @author gagamel
	 * @since 2021. 7. 16
	 */
	public int getMenuIdCount(String menuId) {
		return systemDao.getMenuIdCount(menuId);
	}

	/**
	 * 메뉴 등록/수정 및 메뉴권한 생성
	 * @param menu - 메뉴 정보
	 * @author gagamel
	 * @since 2020. 10. 7
	 */
	@Transactional("shopTxnManager")
//	@CacheEvict(value = "menu", allEntries = true)
	public void saveMenu(Menu menu) {
		menu.setRegNo(TsaSession.getInfo().getUserNo());
		menu.setUpdNo(TsaSession.getInfo().getUserNo());

		// 메뉴 등록/수정
		systemDao.saveMenu(menu);

		if (StringUtils.isNotBlank(menu.getRoleCds())) {
			// 메뉴권한 삭제
			systemDao.deleteMenuRole(menu.getMenuId());

			String[] roleCds = menu.getRoleCds().split(",");

			for (String roleCd : roleCds) {
				MenuRole menuRole = new MenuRole();
				menuRole.setRoleCd(roleCd);
				menuRole.setMenuId(menu.getMenuId());
				menuRole.setRegNo(TsaSession.getInfo().getUserNo());
				menuRole.setUpdNo(TsaSession.getInfo().getUserNo());

				// 메뉴권한 생성
				systemDao.createMenuRole(menuRole);

				// 전체 어드민사용자 메뉴 생성
				systemDao.deleteAllUserMenu(menuRole);

				// 전체 어드민사용자 메뉴 생성
				systemDao.createAllUserMenu(menuRole);
			}
		}
	}

	/**
	 * 메뉴접속이력 생성
	 * @param menuAccessHst - 메뉴접속 정보
	 * @author gagamel
	 * @since 2020. 10. 7
	 */
	@Transactional("shopTxnManager")
	public void createMenuAccessHistory(String menuId, String reqUrl, String params) {
		MenuAccessHst menuAccessHst = new MenuAccessHst();
		menuAccessHst.setUserNo(TsaSession.getInfo().getUserNo());
		menuAccessHst.setMenuId(menuId);
		menuAccessHst.setReqUrl(reqUrl);

		if (StringUtils.isNotBlank(params)) {
			menuAccessHst.setParams(params);
		}

		menuAccessHst.setRegNo(TsaSession.getInfo().getUserNo());

		systemDao.createMenuAccessHistory(menuAccessHst);
	}

	/**
	 * 공통코드 목록
	 * @return
	 * @author gagamel
	 * @since 2020. 10. 7
	 */
	public Collection<CommonCode> getCommonCodeList() {
		return this.getCommonCodeList(new CommonCode());
	}

	/**
	 * 공통코드 목록
	 * @param commoncode - 공통코드 정보
	 * @return
	 * @author gagamel
	 * @since 2020. 10. 7
	 */
	public Collection<CommonCode> getCommonCodeList(CommonCode commoncode) {
		return systemDao.getCommonCodeList(commoncode);
	}

	/**
	 * 공통코드 목록 저장 처리
	 * @param dataList - 공통코드 목록
	 * @return
	 * @author gagamel
	 * @since 2020. 10. 7
	 */
	@Transactional("shopTxnManager")
	public void saveCommonCodeList(Collection<CommonCode> dataList) {
		if (dataList == null || dataList.isEmpty())
			throw new IllegalStateException(message.getMessage("FAIL_1001"));

		for (CommonCode commoncode : dataList) {
			commoncode.setRegNo(TsaSession.getInfo().getUserNo());
			commoncode.setUpdNo(TsaSession.getInfo().getUserNo());
			commoncode.setCdNm(commoncode.getCdNm().replace("&gt;", ">"));
			systemDao.saveCommonCode(commoncode);
		}
	}

	/**
	 * 공통코드 저장 처리
	 * @param commoncode - 공통코드 정보
	 * @return
	 * @author gagamel
	 * @since 2020. 10. 7
	 */
	@Transactional("shopTxnManager")
	public void saveCommonCode(CommonCode commoncode) {
		commoncode.setRegNo(TsaSession.getInfo().getUserNo());
		commoncode.setUpdNo(TsaSession.getInfo().getUserNo());
		commoncode.setCdNm(commoncode.getCdNm().replace("&gt;", ">"));
		systemDao.saveCommonCode(commoncode);
	}

	/**
	 * 공통코드 삭제처리
	 * @param commoncode - 공통코드 정보
	 * @return
	 * @author gagamel
	 * @since 2020. 10. 7
	 */
	@Transactional("shopTxnManager")
	public void deleteCommonCode(CommonCode commoncode) {
		systemDao.deleteCommonCode(commoncode);
	}

	/**
	 * 샘플파일 목록
	 * @return
	 * @author gagamel
	 * @since 2020. 11. 3
	 */
	public Collection<SampleFile> getSampleFileList() {
		return systemDao.getSampleFileList();
	}

	/**
	 * 샘플파일 등록/수정
	 * @param sampleFile - 샘플파일 정보
	 * @author gagamel
	 * @since 2020. 11. 3
	 */
	@Transactional("shopTxnManager")
	public void saveSampleFile(SampleFile sampleFile) {
		if (sampleFile.getMode().equals("N")) {
			systemDao.createSampleFile(sampleFile);
		} else {
			systemDao.updateSampleFile(sampleFile);
		}
	}

	/**
	 * 알람 목록
	 * @param alarm - 알람 정보
	 * @return
	 * @author gagamel
	 * @since 2020. 11. 13
	 */
	public Collection<Alarm> getAlarmList(Alarm alarm) {
		return systemDao.getAlarmList(alarm);
	}

	/**
	 * 알람 저장
	 * @param alarm - 알람 정보
	 * @author gagamel
	 * @since 2020. 11. 13
	 */
	@Transactional("shopTxnManager")
	public void saveAlarm(Alarm alarm) {
		if (alarm.getMode().equals("N")) {
			systemDao.createAlarm(alarm);
		} else {
			systemDao.updateAlarm(alarm);
		}
	}

	/**
	 * 알람 삭제
	 * @param alarm - 알람 정보
	 * @author gagamel
	 * @since 2020. 11. 13
	 */
	@Transactional("shopTxnManager")
	public void deleteAlarm(Alarm alarm) {
		systemDao.deleteAlarm(alarm);
	}

	/**
	 * 알람수신자 목록
	 * @param alarmId - 알람ID
	 * @return
	 * @author gagamel
	 * @since 2020. 11. 13
	 */
	public Collection<AlarmReceiver> getAlarmReceiverList(String alarmId) {
		return systemDao.getAlarmReceiverList(alarmId);
	}

	/**
	 * 알람수신자 목록 저장
	 * @param alarmReceiverList - 알람수신자 목록
	 * @author gagamel
	 * @since 2020. 11. 13
	 */
	@Transactional("shopTxnManager")
	public void saveAlarmReceiverList(Collection<AlarmReceiver> alarmReceiverList) {
		for (AlarmReceiver alarmReceiver : alarmReceiverList) {
			alarmReceiver.setRegNo(TsaSession.getInfo().getUserNo());
			alarmReceiver.setUpdNo(TsaSession.getInfo().getUserNo());
			systemDao.saveAlarmReceiver(alarmReceiver);
		}
	}

	/**
	 * 알람수신자 목록 삭제
	 * @param alarmReceiverList - 알람수신자 목록
	 * @author gagamel
	 * @since 2020. 11. 13
	 */
	@Transactional("shopTxnManager")
	public void deleteAlarmReceiverList(Collection<AlarmReceiver> alarmReceiverList) {
		for (AlarmReceiver alarmReceiver : alarmReceiverList) {
			systemDao.deleteAlarmReceiver(alarmReceiver);
		}
	}

	/**
	 * 배치 목록
	 * @param batch - 배치 정보
	 * @return
	 * @author gagamel
	 * @since 2020. 12. 2
	 */
	public Collection<Batch> getBatchList(Batch batch) {
		return systemDao.getBatchList(batch);
	}

	/**
	 * 배치 생성
	 * @param batch - 배치 정보
	 * @author gagamel
	 * @since 2020. 12. 2
	 */
	public void saveBatch(Batch batch) {
		systemDao.saveBatch(batch);
	}

	/**
	 * 배치 로그 목록
	 * @param batch - 배치 정보
	 * @return
	 * @author gagamel
	 * @since 2020. 12. 3
	 */
	public Collection<BatchLog> getBatchLogList(Batch batch) {
		return systemDao.getBatchLogList(batch);
	}

}
