package cokr.xit.fims.base.web;

import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import cokr.xit.base.code.CommonCode;
import cokr.xit.base.code.service.CodeQuery;
import cokr.xit.base.code.service.CodeService;
import cokr.xit.base.code.service.bean.CodeBean;
import cokr.xit.base.security.Authority;
import cokr.xit.base.security.SecuredUserInfo;
import cokr.xit.base.security.access.service.AuthorityService;
import cokr.xit.base.user.UserQuery;
import cokr.xit.base.user.service.UserService;
import cokr.xit.fims.base.FimsUser;
import cokr.xit.fims.base.service.bean.OgdpBean;
import cokr.xit.fims.cmmn.service.bean.StngBean;
import cokr.xit.foundation.data.DataObject;

@Controller
public class UserController extends cokr.xit.base.user.web.UserController<FimsUser> {
	@Resource(name="userService")
	private UserService userService;
	@Resource(name = "codeBean")
	private CodeBean codeBean;
	@Resource(name="codeService")
	private CodeService codeService;
	@Resource(name="authorityService")
	private AuthorityService authorityService;
	@Resource(name="ogdpBean")
	private OgdpBean ogdpBean;
	@Resource(name = "stngBean")
	private StngBean stngBean;

	@Override
	public ModelAndView main() {
		ModelAndView mav = super.main();
		Map<String, List<CommonCode>> commonCodes = codeService.getCodesOf("CMN009");
		return mav.addObject("CMN009List", commonCodes.get("CMN009"));
	}

	@Override
	public ModelAndView getInfo(String userID) {
		boolean json = !isEmpty(userID) && jsonResponse();
		ModelAndView mav = new ModelAndView(json ? "jsonView" : "base/user/user-info");

		if (!isEmpty(userID)) {
			DataObject userInfo = userService.getUserInfo(userID);
			mav.addObject("userInfo", json ? userInfo : toJson(userInfo));
		}

		mav.addObject("allOgdpList", ogdpBean.selectAllOgdpList());

		List<DataObject> ableOgdpList =  ogdpBean.selectAbleOgdpList(false, currentUser().getOrgID());
		mav.addObject("ableOgdpList", ableOgdpList);

		Map<String, List<CommonCode>> commonCodes = codeService.getCodesOf("CMN008");
		mav.addObject("CMN008List", commonCodes.get("CMN008"));

		return mav;
	}

	@Override
	public ModelAndView create(FimsUser user) {
		user.setAccount(user.getAccount().toUpperCase());
		return super.create(user);
	}

	@Override
	public ModelAndView isDuplicate(String account, String institute) {
		return super.isDuplicate(account.toUpperCase(), institute);
	}

	@Override
	public ModelAndView getUserList(UserQuery req) {
		if(req.getBy() != null && req.getTerm() != null && req.getBy().equals("userAccount")) {
			req.setTerm(req.getTerm().toUpperCase());
		}
		return super.getUserList(req);
	}

	@RequestMapping(name="내 정보 조회",value="/myInfo.do")
	public ModelAndView myInfo() {
		SecuredUserInfo userInfo = currentUser();
		//시군구,기관,부서
		ogdpBean.initUserInfo(userInfo);

		//관리자여부,내부망사용자여부,업무권한여부
		boolean isAdmin = userInfo.isAdmin();
		userInfo.getInfo().put("isAdmin", isAdmin);

		FimsUser fimsUser = (FimsUser)userInfo.getUser();
		boolean isPublicOfficer = fimsUser.getCntnSeCd().equals("01");
		userInfo.getInfo().put("isPublicOfficer", isPublicOfficer);

		List<String> user_auths = userInfo.getAuthorities().stream()
			.map(Authority::getAuthority)
			.toList();
		List<String> user_taskList = codeBean.getCodeList(new CodeQuery().setGroupIDs("FIM054")).stream()
			.map(row -> row.string("CODE"))
			.filter(task -> {
				for (String auth: user_auths)
					if (auth.contains(task))
						return true;
					return false;
			})
			.toList();
		boolean hasTaskAuth = !user_taskList.isEmpty();
		if(userInfo.hasAuthorities("ROLE_TASK_ADMIN")) {
			hasTaskAuth = true;
		}
		userInfo.getInfo().put("hasTaskAuth", hasTaskAuth);


		//사용자별 업무 및 기본업무
		stngBean.initUserInfo(userInfo);

		//지자체 로고(시군구 설정)
		DataObject sggStng = stngBean.getStng("sgg");
		userInfo.getInfo().put("sggLogoPath", sggStng.string("LOGO_FILE_PATH"));
		userInfo.getInfo().put("sggSymbolPath", sggStng.string("SYMBOL_FILE_PATH"));

		return new ModelAndView("jsonView").addObject("myInfo", userInfo);
	}

	@RequestMapping(name="시스템 연계 정보",value="/sysLinkInfo.do")
	public ModelAndView sysLinkInfo() {
		DataObject deptStng = ifEmpty(stngBean.getStng("dept"), DataObject::new);
		DataObject sysLinkInfo = new DataObject()
			.set("NXRP_LINK_YN", deptStng.get("NXRP_LINK_YN"))
			.set("CVLCPT_LINK_SE_CD", deptStng.get("CVLCPT_LINK_SE_CD"));

		return new ModelAndView("jsonView")
			.addObject("sysLinkInfo", sysLinkInfo);
	}

	@RequestMapping(name="내 정보 변경 화면", value="/openMyInfo.do")
	public ModelAndView openMyInfo() {
		DataObject userInfo = userService.getUserInfo(currentUser().getId());

		ModelAndView mav = new ModelAndView("fims/user/user01010-main")
			.addObject("userInfo", toJson(userInfo));

		String cntnSeCd = userInfo.string("CNTN_SE_CD");
		if("01".equals(cntnSeCd)) {
			List<DataObject> ableOgdpList =  ogdpBean.selectAbleOgdpList(false, currentUser().getOrgID());
			Map<String, List<CommonCode>> commonCodes = codeService.getCodesOf("CMN008");

			mav.addObject("cntnSeCd", "01")
			   .addObject("allOgdpList", ogdpBean.selectAllOgdpList())
			   .addObject("ableOgdpList", ableOgdpList)
			   .addObject("CMN008List", commonCodes.get("CMN008"));
		} else if(cntnSeCd.equals("02")) {
			mav.addObject("cntnSeCd", "02");
		}

		return mav;
	}

	@RequestMapping(name="내 정보 변경", value="/updateMyInfo.do")
	public ModelAndView updateMyInfo(FimsUser user) {
		return super.update(user);
	}

	@RequestMapping(name="기본업무 저장",value="/saveDefaultTask.do")
	public ModelAndView saveDefaultTask(String taskSeCd) {
		boolean saved = stngBean.saveDefaultTask(taskSeCd);

		return new ModelAndView("jsonView")
			.addObject("saved", saved);
	}

	@RequestMapping(name="설정정보 조회",value="/stngInfo.do")
	public ModelAndView getStngInfo(String type) {
		DataObject stngInfo = stngBean.getStng(type);
		return new ModelAndView("jsonView")
			.addObject("stngInfo",stngInfo);
	}

	@RequestMapping(name="교부 계좌번호 수정",value="/updateDtbnActno.do")
	public ModelAndView updateDtbnActno(String dtbnBankNm, String dtbnActno) {
		boolean saved = stngBean.updateDtbnActno(dtbnBankNm, dtbnActno);

		return new ModelAndView("jsonView")
			.addObject("saved", saved);
	}

	@RequestMapping(name="사용자 검색",value="/user02/010/main.do")
	public ModelAndView findUserMain(HttpServletRequest hReq, String callbackFuncName) {
		FimsUser currentUser = (FimsUser)currentUser().getUser();

		return new ModelAndView("fims/user/user02010-main")
			.addObject("openerPageName", hReq.getParameter("openerPageName"))	// 호출한 Jsp PageName
			.addObject("pageName", "user02010")									// View(jsp)에서 사용할 id 뒤에 붙일 suffix
			.addObject("infoPrefix", "user")									// prefix
			.addObject("infoPrefixUrl", "/user/user02")							// prefixUrl
			.addObject("callbackFuncName", callbackFuncName)					// 콜백함수(callbackFuncName)
			.addObject("sggCd", currentUser.getOrgID())							// 시군구 코드(SGG_CD)
			.addObject("deptCd", currentUser.getDeptCode())						// 부서 코드(DEPT_CD)
			.addObject("userAcnt", currentUser.getAccount())					// 사용자 계정(USER_ACNT)
		;
	}

	@RequestMapping(name="회원탈퇴", value="/cancelAccount.do")
	public ModelAndView cancelAccount() {
		int affected = userService.remove(currentUser().getId());
		return new ModelAndView("jsonView")
			.addObject("affected", affected)
			.addObject("saved", affected > 0);
	}
}