package com.eactive.eai.rms.onl.manage.control.control;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

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

import com.eactive.eai.common.util.DatetimeUtil;
import com.eactive.eai.data.entity.onl.restrict.RestrictInfo;
import com.eactive.eai.data.entity.onl.restrict.RestrictInfoHistory;
import com.eactive.eai.data.entity.onl.restrict.RestrictInfoHistoryId;
import com.eactive.eai.rms.common.base.BaseService;
import com.eactive.eai.rms.common.combo.ComboService;
import com.eactive.eai.rms.common.combo.ComboVo;
import com.eactive.eai.rms.common.datasource.DataSourceContextHolder;
import com.eactive.eai.rms.data.entity.onl.eaimsg.EAIMessageService;
import com.eactive.eai.rms.data.entity.onl.restrict.RestrictInfoService;
import com.eactive.eai.rms.onl.manage.control.history.ControlHistoryService;

@Service
public class ControlManService extends BaseService {

	@Autowired
	public ComboService comboService;

	@Autowired
	private RestrictInfoService service;

	@Autowired
	private ControlHistoryService historyService;

	@Autowired
	private ControlManMapper mapper;

	@Autowired
	private EAIMessageService eaiMessageService;

	public Map<String, Object> selectList(ControlManUISearch uiSearch) {
		List<ControlServiceDto> dtoList = this.findAll(uiSearch);

		HashMap<String, Object> map = new HashMap<>();
		if (dtoList != null && !dtoList.isEmpty()) {
			List<ComboVo> businessTypeList = comboService.getFromBusinessType();
			List<ControlManUI> uiList = dtoList.stream().map(mapper::toVo).map(this::setStatus)
					.map(ui -> setBzwkdsticname(ui, businessTypeList)).collect(Collectors.toList());
			map.put("list", uiList);
		}

		return map;
	}

	public Map<String, List<?>> selectListToExcel(ControlManUISearch uiSearch) {
		List<ControlServiceDto> dtoList = this.findAll(uiSearch);

		ArrayList<HashMap<String, Object>> list = new ArrayList<>();
		if (dtoList != null && !dtoList.isEmpty()) {
			List<ComboVo> businessTypeList = comboService.getFromBusinessType();
			List<ControlManUI> uiList = dtoList.stream().map(mapper::toVo).map(this::setStatus)
					.map(ui -> setBzwkdsticname(ui, businessTypeList)).collect(Collectors.toList());
			for (ControlManUI item : uiList) {
				HashMap<String, Object> row = new HashMap<>();
				row.put("eaibzwkdstcd", item.getEaibzwkdstcd());
				row.put("bzwkdsticname", item.getBzwkdsticname());
				row.put("eaisvcname", item.getEaisvcname());
				row.put("eaisvcdesc", item.getEaisvcdesc());
				row.put("eaictrldsticctnt", extractStartTimeWithSplit(item.getEaictrldsticctnt(), 2));
				row.put("eaictrldsticctnt2", extractStartTimeWithSplit(item.getEaictrldsticctnt2(), 1));
				row.put("status", item.getStatus());
				list.add(row);
			}
		}
		HashMap<String, List<?>> map = new HashMap<>();
		map.put("list", list);

		return map;
	}

	private String extractStartTimeWithSplit(String ctnt, int reverseIndex) {
		if (ctnt != null) {
			String[] parts = ctnt.split("\\|");
			if (parts.length >= 2) {
				return formatTime(parts[parts.length - reverseIndex]);
			}
		}
		return "";
	}

	private static String formatTime(String time) {
		return String.format("%02d", Integer.parseInt(time.substring(0, 2))) + ":"
				+ String.format("%02d", Integer.parseInt(time.substring(2)));
	}

	private List<ControlServiceDto> findAll(ControlManUISearch uiSearch) {
		List<ControlServiceDto> list = null;
		String searchControlType = uiSearch.getSearchControlType();
		if ("S".equals(searchControlType)) { // 서비스코드
			list = service.findAllForService(uiSearch);
		} else if ("I".equals(searchControlType)) { // 대외기관코드
			list = service.findAllForInsti(uiSearch);
		}
		return list;
	}

	private ControlManUI setStatus(ControlManUI ui) {
		if (StringUtils.isNotBlank(ui.getEaictrlname()))
			ui.setStatus("통제");
		else
			ui.setStatus("정상");
		return ui;
	}

	private ControlManUI setBzwkdsticname(ControlManUI ui, List<ComboVo> businessTypeList) {
		for (ComboVo comboVo : businessTypeList) {
			if (comboVo.getCode().equals(ui.getEaibzwkdstcd())) {
				ui.setBzwkdsticname(comboVo.getCodename());
			}
		}
		return ui;
	}

	public void insert(ControlManUIDetail uiDetail, String userId) {
		String eaiCtrlDsticCtnt = createEaiCtrlDsticCtnt(uiDetail);
		String eaiCtrlNameDstcd = "S".equals(uiDetail.getSearchControlType()) ? "1" : "2";
		String ctrlPrcssYMS = DatetimeUtil.getCurrentTimeMillis();

		for (String eaiSvcName : uiDetail.arrEaiSvcName) {
			insertOne(eaiSvcName, userId, eaiCtrlDsticCtnt, eaiCtrlNameDstcd, ctrlPrcssYMS);
		}
	}

	public void insertServiceType(String eaiSvcName, String userId) {
		ControlManUIDetail uiDetail = new ControlManUIDetail();
		uiDetail.setSearchControlType("S");
		String eaiCtrlDsticCtnt = createEaiCtrlDsticCtnt(uiDetail);
		String eaiCtrlNameDstcd = "1";
		String ctrlPrcssYMS = DatetimeUtil.getCurrentTimeMillis();

		insertOne(eaiSvcName, userId, eaiCtrlDsticCtnt, eaiCtrlNameDstcd, ctrlPrcssYMS);
	}

	public void insertAll(ControlManUIDetail uiDetail, String userId) {
		String eaiCtrlDsticCtnt = createEaiCtrlDsticCtnt(uiDetail);
		String eaiCtrlNameDstcd = "S".equals(uiDetail.getSearchControlType()) ? "1" : "2";
		String ctrlPrcssYMS = DatetimeUtil.getCurrentTimeMillis();

		List<ControlServiceDto> allControlService = this.findAll(uiDetail);

		for (ControlServiceDto dto : allControlService) {
			insertOne(dto.getEaisvcname(), userId, eaiCtrlDsticCtnt, eaiCtrlNameDstcd, ctrlPrcssYMS);
		}
	}

	private void insertOne(String eaiSvcName, String userId, String eaiCtrlDsticCtnt, String eaiCtrlNameDstcd,
			String ctrlPrcssYMS) {
		deleteOne(eaiSvcName, userId, ctrlPrcssYMS);
		// 신규 insert
		RestrictInfo info = new RestrictInfo();
		info.setEaictrlname(eaiSvcName);
		info.setEaictrlnamedstcd(eaiCtrlNameDstcd);
		info.setEaictrldsticctnt(eaiCtrlDsticCtnt);
		info.setCtrlprcssyms(ctrlPrcssYMS);
		info.setTranctrlprcssname(userId);
		service.save(info);
		// 이력 insert
		saveHistoryOne(info, userId);
	}

	private void saveHistoryOne(RestrictInfo info, String userId) {
		// 이전 기록이 있으면, 삭제 및 삭제이력 남긴다.
		RestrictInfoHistoryId id = new RestrictInfoHistoryId();
		id.setEaictrlname(info.getEaictrlname());
		id.setCtrlprcssyms(info.getCtrlprcssyms());
		Optional<RestrictInfoHistory> optionalHistory = historyService.findById(id);
		RestrictInfoHistory history = null;
		if (optionalHistory.isPresent()) {
			history = optionalHistory.get();
		} else {
			history = mapper.toHistoryEntity(info);
		}
		history.setCtrlprcssname(userId);
		history.setCtrlrevocyms("");
		history.setRevocprcssname("");
		historyService.save(history);
	}

	private String createEaiCtrlDsticCtnt(ControlManUIDetail uiDetail) {
		String serviceNm = DataSourceContextHolder.getDataSourceType().getName();
		StringBuilder sbEaiCtrlDsticCtnt = new StringBuilder(
				uiDetail.getSearchControlType() != null ? uiDetail.getSearchControlType() : "").append(serviceNm)
				.append("|").append("A").append("|")
				.append(uiDetail.getSearchIo() != null ? uiDetail.getSearchIo() : "A").append("|")
				.append(uiDetail.getSearchEaiBzwkDstcd() != null ? uiDetail.getSearchEaiBzwkDstcd() : "A").append("|")
				.append(uiDetail.getSearchControlSelectType() != null ? uiDetail.getSearchControlSelectType() : "A")
				.append("|").append(uiDetail.getStartTime() != null ? uiDetail.getStartTime() : "0000").append("|")
				.append(uiDetail.getEndTime() != null ? uiDetail.getEndTime() : "2400");
		return sbEaiCtrlDsticCtnt.toString();
	}

	public void delete(ControlManUIDetail uiDetail, String userId) {
		String ctrlPrcssYMS = DatetimeUtil.getCurrentTimeMillis();
		for (String eaiSvcName : uiDetail.arrEaiSvcName) {
			deleteOne(eaiSvcName, userId, ctrlPrcssYMS);
		}
	}

	public void delete(String eaiSvcName, String userId) {
		deleteOne(eaiSvcName, userId, DatetimeUtil.getCurrentTimeMillis());
	}

	public void deleteAll(ControlManUIDetail uiDetail, String userId) {
		List<ControlServiceDto> allControlService = this.findAll(uiDetail);

		String ctrlPrcssYMS = DatetimeUtil.getCurrentTimeMillis();
		for (ControlServiceDto dto : allControlService) {
			deleteOne(dto.getEaisvcname(), userId, ctrlPrcssYMS);
		}
	}

	private void deleteOne(String eaiSvcName, String userId, String ctrlPrcssYMS) {
		// 이전 기록이 있으면, 삭제 및 삭제이력 남긴다.
		Optional<RestrictInfo> optionalInfo = service.findById(eaiSvcName);
		if (optionalInfo.isPresent()) {
			service.deleteById(eaiSvcName);

			RestrictInfoHistoryId hId = new RestrictInfoHistoryId();
			hId.setEaictrlname(eaiSvcName);
			hId.setCtrlprcssyms(optionalInfo.get().getCtrlprcssyms());

			Optional<RestrictInfoHistory> optionalHistory = historyService.findById(hId);
			RestrictInfoHistory history = null;
			if (optionalHistory.isPresent()) {
				history = optionalHistory.get();
			} else {
				history = new RestrictInfoHistory();
				history.setId(hId);
				history.setEaictrlnamedstcd(optionalInfo.get().getEaictrlnamedstcd());
			}
			history.setCtrlrevocyms(ctrlPrcssYMS);
			history.setRevocprcssname(userId);
			historyService.save(history);
		}
	}

	public Map<String, List<ComboVo>> selectListInitCombo() {
		List<ComboVo> controlList = comboService.getFromCode("CONTROL_TYPE");// control 구분코드
		List<ComboVo> ioList = comboService.getFromCode("IO_OLD_TYPE");// 당발/타발
		List<ComboVo> bizList = comboService.getFromBusinessType();
		List<ComboVo> controlSelectList = comboService.getFromCode("CONTROL_SELECT_TYPE");// 당타발 구분코드

		HashMap<String, List<ComboVo>> map = new HashMap<>();
		map.put("controlList", controlList);
		map.put("ioList", ioList);
		map.put("bizList", bizList);
		map.put("controlSelectList", controlSelectList);

		return map;
	}

	public boolean existEaiSvcName(String eaiSvcName) {
		return this.eaiMessageService.findById(eaiSvcName).isPresent();
	}

}
