package com.eactive.eai.rms.onl.manage.authserver.scope;

import java.util.List;

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 com.eactive.eai.agent.authserver.ReloadApiScopeCommand;
import com.eactive.eai.agent.command.CommonCommand;
import com.eactive.eai.rms.common.base.OnlBaseAnnotationController;
import com.eactive.eai.rms.common.vo.GridResponse;
import com.eactive.eai.rms.data.entity.onl.authserver.ScopeSearch;
import com.eactive.eai.rms.data.entity.onl.eaimsg.ApiScopeSearch;
import com.eactive.eai.rms.onl.common.exception.BizException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

@Controller
public class ScopeController extends OnlBaseAnnotationController {

	private ScopeManService scopeManService;

	private ApiScopeManService apiScopeManService;

	@Autowired
	public ScopeController(ScopeManService scopeManService, ApiScopeManService apiScopeManService) {
		this.scopeManService = scopeManService;
		this.apiScopeManService = apiScopeManService;
	}

	@GetMapping(value = "/onl/admin/authserver/scopeMan.view")
	public void view() {
		// view
	}

	@GetMapping(value = "/onl/admin/authserver/scopeMan.view", params = "cmd=DETAIL")
	public String viewList() {
		return "/onl/admin/authserver/scopeManDetail";
	}

	@PostMapping(value = "/onl/admin/authserver/scopeMan.json", params = "cmd=LIST")
	public ResponseEntity<GridResponse<ScopeUI>> selectList(@SortDefault("scopeName") Pageable pageable, ScopeSearch scopeSearch) {
		Page<ScopeUI> page = scopeManService.selectList(pageable, scopeSearch);
		return ResponseEntity.ok(new GridResponse<>(page));
	}

	@PostMapping(value = "/onl/admin/authserver/scopeMan.json", params = "cmd=API_LIST")
	public ResponseEntity<GridResponse<ApiScopeUI>> selectApiList(Pageable pageable, ApiScopeSearch apiScopeSearch) {
		Page<ApiScopeUI> page = apiScopeManService.selectApiScopeRelationsList(pageable, apiScopeSearch);
		return ResponseEntity.ok(new GridResponse<>(page));
	}

	@PostMapping(value = "/onl/admin/authserver/scopeMan.json", params = "cmd=DETAIL")
	public ResponseEntity<ScopeUI> selectDetail(String scopeId) {
		ScopeUI scopeUI = scopeManService.selectDetail(scopeId);
		return ResponseEntity.ok(scopeUI);
	}

	@PostMapping(value = "/onl/admin/authserver/scopeMan.json", params = "cmd=INSERT")
	public ResponseEntity<Void> insert(ScopeUI scopeUI, @RequestParam(value = "apiList", required = false) String apiListJson) {
		scopeManService.insert(scopeUI);
		saveApiScopeRelations(scopeUI.getScopeId(), apiListJson);
		return ResponseEntity.ok().build();
	}

	@PostMapping(value = "/onl/admin/authserver/scopeMan.json", params = "cmd=UPDATE")
	public ResponseEntity<Void> update(ScopeUI scopeUI, @RequestParam(value = "apiList", required = false) String apiListJson) {
		scopeManService.update(scopeUI);
		saveApiScopeRelations(scopeUI.getScopeId(), apiListJson);
		return ResponseEntity.ok().build();
	}

	@PostMapping(value = "/onl/admin/authserver/scopeMan.json", params = "cmd=DELETE")
	public ResponseEntity<Void> delete(String scopeId) {
		scopeManService.delete(scopeId);
		scopeManService.deleteApiScopeRelationsByScopeId(scopeId);

		CommonCommand.builder()
								.name(CommonCommand.RELOAD_API_SCOPE_COMMAND)
								.args(new String[] {ReloadApiScopeCommand.COMMAND_TYPE_SCOPE, "", scopeId})
								.build()
								.broadcast(agentUtilService);

		return ResponseEntity.ok().build();
	}

	private void saveApiScopeRelations(String scopeId, String apiListJson) {
		if (apiListJson == null || apiListJson.isEmpty()) {
			return;
		}

		List<ApiScopeUI> apiScopeList;
		try {
			apiScopeList = new ObjectMapper().readValue(apiListJson, new TypeReference<List<ApiScopeUI>>() {});
		} catch (Exception e) {
			throw new BizException("데이터 변환 중 오류가 발생했습니다.");
		}

		scopeManService.updateApiScopeRelations(apiScopeList, scopeId);

		CommonCommand.builder()
								.name(CommonCommand.RELOAD_API_SCOPE_COMMAND)
								.args(new String[] {ReloadApiScopeCommand.COMMAND_TYPE_SCOPE, "", scopeId})
								.build()
								.broadcast(agentUtilService);
	}

}