package com.eactive.eai.rms.onl.manage.comm.codeMan;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import javax.persistence.EntityNotFoundException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.eactive.eai.rms.common.base.OnlBaseService;
import com.eactive.eai.rms.common.spring.LocaleMessage;
import com.eactive.eai.rms.data.entity.onl.code.Code;
import com.eactive.eai.rms.data.entity.onl.code.CodeGroup;
import com.eactive.eai.rms.data.entity.onl.code.CodeGroupService;
import com.eactive.eai.rms.data.entity.onl.code.CodeService;
import com.eactive.eai.rms.onl.common.exception.BizException;

@Service
@Transactional
public class CodeManService extends OnlBaseService {

	@Autowired
	private CodeMapper codeMapper;

	@Autowired
	private CodeGroupMapper codeGroupMapper;

	@Autowired
	private CodeService codeService;

	@Autowired
	private CodeGroupService codeGroupService;

	@Autowired
	private LocaleMessage localeMessage;

	public List<CodeGroupUI> selectCodeGroupList(String searchName) {
		List<CodeGroup> codeGroups = codeGroupService.selectCodeGroupList(searchName);
		return codeGroups.stream().map(codeGroupMapper::toVo).collect(Collectors.toList());
	}

	/* CODE TREE LIST */
	public List<CodeUI> selectCodeTreeList(String searchCodeGroup) {
		CodeGroup group = codeGroupService.getById(searchCodeGroup);
		List<CodeUI> codeTreeList = new ArrayList<>();

		if (searchCodeGroup.equals(group.getCodegroup())) {
			codeTreeList.add(createRootCodeUI(group));
		}

		List<Code> codeList = codeService.findByCodeGroup(searchCodeGroup);
		codeList.forEach(code -> codeTreeList.add(createCodeUI(code, 1)));
		return codeTreeList;
	}

	private CodeUI createRootCodeUI(CodeGroup group) {
		CodeUI codeUI = new CodeUI();
		codeUI.setCode(group.getCodegroup());
		codeUI.setLevel(0);
		codeUI.setId(group.getCodegroup());
		codeUI.setCodeGroup(group.getCodegroup());
		codeUI.setCode(group.getCodegroup());
		codeUI.setCodeName("");
		codeUI.setCodeName_En("");
		codeUI.setSeq(BigDecimal.ZERO);
		codeUI.setUseYn("");
		codeUI.setUseYnName("");
		return codeUI;
	}

	private CodeUI createCodeUI(Code code, int level) {
		CodeUI codeUI = new CodeUI(code, level);
		codeUI.setUseYnName("Y".equals(code.getUseyn()) ? localeMessage.getString("combo.usey")
				: localeMessage.getString("combo.usen"));
		return codeUI;
	}

	/* Start CODEGROUP */
	public void insertGroup(CodeGroupUI codeGroupUI) {
		if (codeGroupService.existsById(codeGroupUI.getCdGroup())) { // 중복체크
			throw new BizException(localeMessage.getString("monitoringCode.codeGroupExists"));
		}
		CodeGroup codeGroup = codeGroupMapper.toEntity(codeGroupUI);
		codeGroupService.save(codeGroup);
	}

	public void updateGroup(CodeGroupUI codeGroupUI) {
		CodeGroup codeGroup = codeGroupService.getById(codeGroupUI.getCdGroup());
		codeGroupMapper.updateToEntity(codeGroupUI, codeGroup);
		codeGroupService.save(codeGroup);
	}

	public void deleteGroup(CodeGroupUI codeGroupUI) {
		CodeGroup codeGroup = codeGroupService.findById(codeGroupUI.getCdGroup())
				.orElseThrow(() -> new EntityNotFoundException("CodeGroup not found: " + codeGroupUI.getCdGroup()));
		List<Code> codes = codeService.findByCodeGroup(codeGroup.getCodegroup());
		codes.forEach(code -> codeService.deleteById(code.getId()));
		codeGroupService.deleteById(codeGroup.getCodegroup());
	}
	/* End CODEGROUP */

	/* Start CODE */
	public void insert(CodeUI codeUI) {
		if (codeService.existsById(codeMapper.toId(codeUI))) {
			throw new BizException(localeMessage.getString("monitoringCode.codeExists"));
		}
		Code code = codeMapper.toEntity(codeUI);
		codeService.save(code);
	}

	public void update(CodeUI codeUI) {
		Code code = codeService.getById(codeMapper.toId(codeUI));
		codeMapper.updateToEntity(codeUI, code);
		codeService.save(code);
	}

	public void delete(CodeUI codeUI) {
		Code code = codeService.findById(codeMapper.toId(codeUI))
				.orElseThrow(() -> new EntityNotFoundException("Code not found"));
		CodeGroup codeGroup = code.getCodegroups();
		if (codeGroup != null && codeUI.getLevel() > 0) {
			codeGroup.getCodes().remove(code);
			codeGroupService.save(codeGroup);
		}
		codeService.delete(code);
	}
	/* End CODE */
}
