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

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.SortDefault;
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 org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.eactive.eai.agent.command.CommonCommand;
import com.eactive.eai.agent.encryption.ReloadEncryptionYNCommand;
import com.eactive.eai.agent.property.ReloadPropertyCommand;
import com.eactive.eai.rms.common.base.OnlBaseAnnotationController;
import com.eactive.eai.rms.common.vo.GridResponse;
import com.eactive.ext.djb.DamoManager;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.openbanking.eai.agent.token.ReloadAccessTokenCommand;

@Controller
public class PropertyController extends OnlBaseAnnotationController {

	private PropertyManService propertyManService;

	private ObjectMapper objectMapper;

	@Autowired
	public PropertyController(PropertyManService propertyManService, ObjectMapper objectMapper) {
		this.propertyManService = propertyManService; 
		this.objectMapper = objectMapper; 
	}
	
	@GetMapping(value = "/onl/admin/common/propertyMan.view")
	public void view() {
		// view
	}

	@GetMapping(value = "/onl/admin/common/propertyMan.view", params = "cmd=DETAIL")
	public String detailView() {
		return "/onl/admin/common/propertyManDetail";
	}

	@PostMapping(value = "/onl/admin/common/propertyMan.json", params = "cmd=LIST")
	public ResponseEntity<GridResponse<PropertyGroupUI>> selectList(@SortDefault("prptygroupname") Pageable pageable,
			PropertyGroupUI propertyGroupUI) {
		Page<PropertyGroupUI> page = propertyManService.selectList(pageable, propertyGroupUI);
		return ResponseEntity.ok(new GridResponse<>(page));
	}

	@PostMapping(value = "/onl/admin/common/propertyMan.json", params = "cmd=DETAIL")
	public ResponseEntity<PropertyGroupUI> selectDetail(String prptyGroupName) {
		PropertyGroupUI propertyGroupUI = propertyManService.selectDetail(prptyGroupName);
		return ResponseEntity.ok(propertyGroupUI);
	}

	@PostMapping(value = "/onl/admin/common/propertyMan.json", params = "cmd=INSERT")
	public ResponseEntity<Void> insert(PropertyGroupUI propertyGroupUI) throws Exception {
		propertyManService.insert(propertyGroupUI);

		CommonCommand command = new CommonCommand(ReloadPropertyCommand.class.getName(),
				propertyGroupUI.getPrptyGroupName());
		agentUtilService.broadcast(command);
		reloadEncryptionInfo(propertyGroupUI.getPrptyGroupName());
		reloadOAuthInfo(propertyGroupUI.getPrptyGroupName());
		return ResponseEntity.ok().build();
	}

	@PostMapping(value = "/onl/admin/common/propertyMan.json", params = "cmd=UPDATE")
	public ResponseEntity<Void> update(PropertyGroupUI propertyGroupForm) throws Exception {
		propertyManService.update(propertyGroupForm);

		CommonCommand command = new CommonCommand(ReloadPropertyCommand.class.getName(),
				propertyGroupForm.getPrptyGroupName());
		agentUtilService.broadcast(command);
		reloadEncryptionInfo(propertyGroupForm.getPrptyGroupName());
		reloadOAuthInfo(propertyGroupForm.getPrptyGroupName());
		return ResponseEntity.ok().build();
	}

	@PostMapping(value = "/onl/admin/common/propertyMan.json", params = "cmd=DELETE")
	public ResponseEntity<Void> delete(PropertyGroupUI propertyGroupForm) throws Exception {
		propertyManService.delete(propertyGroupForm.getPrptyGroupName());

		CommonCommand command = new CommonCommand(ReloadPropertyCommand.class.getName(),
				propertyGroupForm.getPrptyGroupName());
		agentUtilService.broadcast(command);
		reloadEncryptionInfo(propertyGroupForm.getPrptyGroupName());
		reloadOAuthInfo(propertyGroupForm.getPrptyGroupName());
		return ResponseEntity.ok().build();
	}

	private boolean reloadEncryptionInfo(String propertyGroupName) {
		if ("ENCRYPTION".equals(propertyGroupName)) {
			logger.warn("ReloadEncryptionYNCommand " + propertyGroupName);
			CommonCommand command = new CommonCommand(ReloadEncryptionYNCommand.class.getName(), "ENC");
			try {
				// 소스코드점검 수정 20201027
				agentUtilService.broadcast(command);
			} catch (Exception e) {
				logger.warn("ReloadEncryptionYNCommand error", e);
				return false;
			}
			return true;
		} else {
			return false;
		}
	}

	private boolean reloadOAuthInfo(String propertyGroupName) {
		if ("OAuthInfo".equals(propertyGroupName)) {
			logger.warn("ReloadAccessTokenCommand " + propertyGroupName);
			CommonCommand command = new CommonCommand(ReloadAccessTokenCommand.class.getName());
			try {
				agentUtilService.broadcast(command);
			} catch (Exception e) {
				logger.warn("ReloadAccessTokenCommand error", e);
				return false;
			}
			return true;
		} else {
			return false;
		}
	}

	@PostMapping(value = "/onl/admin/common/propertyMan.excel", params = "cmd=LIST_GRID_TO_EXCEL")
	public ModelAndView listGridToExcel(@RequestParam Map<String, Object> paramMap) throws JsonProcessingException {
		Map<String, Object> resultMap = new HashMap<>();

		String[] headers = objectMapper.readValue((String) paramMap.get("header"), String[].class);
		String[] headerTitles = objectMapper.readValue((String) paramMap.get("headerTitle"), String[].class);

		Map<String, Object>[] datas = propertyManService.selectListToExcel();
		Map<String, Object>[] lmerge = null;
		String merge = (String) paramMap.get("merge");

		if (merge != null) {
			lmerge = objectMapper.readValue(merge, new TypeReference<HashMap<String, Object>[]>() {
			});
		}
		resultMap.put("headers", headers);
		resultMap.put("headerTitles", headerTitles);
		resultMap.put("datas", datas);
		resultMap.put("fileName", paramMap.get("fileName"));
		resultMap.put("merge", lmerge);
		return new ModelAndView("excelView", resultMap);
	}
	
	
	@PostMapping(value = "/onl/admin/common/propertyMan.json", params = "cmd=ENCRYPT")
	public ResponseEntity<String> encrypt(PropertyUI propertyForm) throws Exception {
		String encrypted = DamoManager.getInstance().encrypt(propertyForm.getPrpty2Val());
		return ResponseEntity.ok(encrypted);
	}

}