package com.eactive.eai.rms.onl.apim.apigroup;

import com.eactive.apim.portal.portalorg.entity.PortalOrg;
import com.eactive.eai.agent.command.CommonCommand;
import com.eactive.eai.apim.apigroup.command.ReloadApiGroupCommand;
import com.eactive.eai.apim.apigroup.command.RemoveApiGroupCommand;
import com.eactive.eai.rms.common.base.OnlBaseAnnotationController;
import com.eactive.eai.rms.common.util.CommonUtil;
import com.eactive.eai.rms.common.vo.GridResponse;
import com.eactive.eai.rms.common.vo.SimpleResponse;
import com.eactive.eai.rms.onl.apim.apigroup.ui.ApiGroupUI;
import com.eactive.eai.rms.onl.apim.apigroup.ui.ApiGroupUISearch;
import com.eactive.eai.rms.onl.apim.portalorg.PortalOrgManService;
import com.eactive.eai.rms.onl.common.exception.BizException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import java.util.HashMap;
import java.util.Arrays;
import java.util.Optional;
import java.util.stream.Collectors;


@Controller
public class ApiGroupManController extends OnlBaseAnnotationController {

    public static final Log logger = LogFactory.getLog(ApiGroupManController.class);

    public final ApiGroupManService service;

	private final PortalOrgManService portalOrgManService;

	@Autowired
	public ApiGroupManController(ApiGroupManService service, PortalOrgManService portalOrgManService) {
		this.service = service;
		this.portalOrgManService = portalOrgManService;
	}

	@GetMapping(value = "/onl/apim/apigroup/apiGroupMan.view")
	public void view() {
	}

	@GetMapping(value = "/onl/apim/apigroup/apiGroupMan.view", params = "cmd=DETAIL")
	public String viewDetail() {
		return "/onl/apim/apigroup/apiGroupManDetail";
	}

	@GetMapping(value = "/onl/apim/apigroup/apiGroupMan.view", params = "cmd=POPUP")
	public String apiSearchPopup() {
		return "/onl/apim/apigroup/apiGroupManPopup";
	}

	@PostMapping(value= "/onl/apim/apigroup/apiGroupMan.json", params = "cmd=LIST")
	public ResponseEntity<GridResponse<ApiGroupUI>> selectList(ApiGroupUISearch apiGroupUISearch,
															   Pageable pageable) {
		Pageable sortedPageable = PageRequest.of(
				pageable.getPageNumber(),
				pageable.getPageSize(),
				Sort.by(
						Sort.Order.asc("displayOrder"),
						Sort.Order.asc("groupName")
				)
		);
		Page<ApiGroupUI> page = service.selectList(apiGroupUISearch, sortedPageable);
		return ResponseEntity.ok(new GridResponse<>(page));
	}

	@PostMapping(value= "/onl/apim/apigroup/apiGroupMan.json",params = "cmd=DETAIL")
	public ResponseEntity<ApiGroupUI> selectDetail(String apiGroupId) throws Exception {
		ApiGroupUI apiGroupUI = service.selectDetail(apiGroupId);

		if (StringUtils.isNotBlank(apiGroupUI.getDisplayOrg())) {
			String orgNames = Arrays.stream(apiGroupUI.getDisplayOrg().split(","))
					.map(portalOrgManService::findById)
					.filter(Optional::isPresent)
					.map(Optional::get)
					.map(PortalOrg::getOrgName)
					.collect(Collectors.joining(", "));

			apiGroupUI.setDisplayOrgName(orgNames);
		}

		return ResponseEntity.ok(apiGroupUI);
	}

	@PostMapping(value= "/onl/apim/apigroup/apiGroupMan.json",params = "cmd=INSERT")
	public ResponseEntity<SimpleResponse> insert(ApiGroupUI apiGroupUI) throws Exception {
		try {
			service.insert(apiGroupUI);
			CommonCommand command = new CommonCommand(ReloadApiGroupCommand.class.getName(), apiGroupUI.getId());
			HashMap<String, Object> returnMap = agentUtilService.broadcast(command);

			SimpleResponse simpleResponse = SimpleResponse.of(CommonUtil.getMapString(returnMap, true));
			return ResponseEntity.ok(simpleResponse);

		}catch(Exception e) {
			logger.error(e);
			if(e instanceof BizException) {
				throw e;
			}
			throw new BizException("오류가 발생했습니다. 확인바랍니다. error:"+e.getMessage(), e);
		}
	}
	@PostMapping(value= "/onl/apim/apigroup/apiGroupMan.json", params = "cmd=UPDATE")
	public ResponseEntity<SimpleResponse>  update(ApiGroupUI apiGroupUI) throws Exception {
		try {
			service.update(apiGroupUI);
			CommonCommand command = new CommonCommand(ReloadApiGroupCommand.class.getName(), apiGroupUI.getId());
			HashMap<String, Object> returnMap = agentUtilService.broadcast(command);

			SimpleResponse simpleResponse = SimpleResponse.of(CommonUtil.getMapString(returnMap, true));
			return ResponseEntity.ok(simpleResponse);
		}catch(Exception e) {
			if(e instanceof BizException) {
				throw e;
			}
			if(e instanceof DuplicateKeyException) {
				DuplicateKeyException dupEx = (DuplicateKeyException) e;
				Throwable cause = dupEx.getMostSpecificCause();
				throw new BizException("중복 오류가 발생했습니다. 확인바랍니다. 오류메시지: "+cause.getMessage());
			}
			logger.error(e);
			throw new BizException("오류가 발생했습니다. 확인바랍니다. 오류메시지: "+e.getMessage());
		}

	}
	@PostMapping(value= "/onl/apim/apigroup/apiGroupMan.json",params = "cmd=DELETE")
	public ResponseEntity<SimpleResponse>  delete(ApiGroupUI apiGroupUI) throws Exception {
		try {
			service.delete(apiGroupUI);
			CommonCommand command = new CommonCommand(RemoveApiGroupCommand.class.getName(), apiGroupUI.getId());
			HashMap<String, Object> returnMap = agentUtilService.broadcast(command);

			SimpleResponse simpleResponse = SimpleResponse.of(CommonUtil.getMapString(returnMap, true));
			return ResponseEntity.ok(simpleResponse);
		}catch(Exception e) {
			if(e instanceof BizException) {
				throw e;
			}
			throw new BizException("오류가 발생했습니다. 확인바랍니다. error:"+e.getMessage(), e);
		}
	}
}
