package incheon.res.mng.danga.web;

import incheon.com.cmm.ComDefaultVO;
import incheon.com.cmm.ResponseCode;
import incheon.com.cmm.api.DefaultApiResponse;
import incheon.com.security.vo.LoginVO;
import incheon.res.mng.danga.service.MngDangaService;
import incheon.res.mng.danga.vo.MngDangaVO;
import incheon.res.rdm.com.code.service.RdmComCodeService;
import incheon.res.rdm.com.code.vo.RdmComCodeVO;
import org.egovframe.rte.psl.dataaccess.util.EgovMap;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import static incheon.res.com.util.ComStringUtil.isEmpty;

/**
*
* @Description : 처리로직 - 기초자료관리-단가조회(복구비, 점용료, 면허세, 최소굴착면적/폭조회) Controller
*/
@Controller
@SessionAttributes(types = ComDefaultVO.class)
@RequestMapping("${api.rcs-path}")
public class MngDangaController {
	
	@Resource
	private MngDangaService mngDangaService;

	@Resource
	private RdmComCodeService rdmComCodeService;

	/**
	 * @MethodDESC : 복구비 상세 조회.
	 */
	@RequestMapping(value = "/MngDangaR010.do")
	public String selectDangaViewGUPT(@ModelAttribute("rdmOeDangaVO") MngDangaVO vo, ModelMap model) throws Exception{

		vo.setMngInstCd("3490000");

		List resultList = mngDangaService.selectDangaViewGUPT(vo);
		
		model.addAttribute("resultList", resultList);
		model.addAttribute("searchVo", vo);
		
		return "res/mng/danga/MngDangaR010";
	}

	/**
	 * @MethodDESC : 복구비 수정화면 이동.
	 */
	@RequestMapping(value = "/MngDangaU010.do")
	public String insertGuptView(@ModelAttribute("rdmOeDangaVO") MngDangaVO vo, ModelMap model) throws Exception{

		vo.setMngInstCd("3490000");

		List resultList = mngDangaService.selectDangaViewGUPT(vo);
		model.addAttribute("resultList", resultList);
		return "res/mng/danga/MngDangaU010";
	}

	/**
	 * @MethodDESC : 복구비  등록.
	 */
	@Transactional
	@RequestMapping(value = "MngDangaC010.do")
	public ResponseEntity<DefaultApiResponse<Map<String, Object>>> insertGupt(@ModelAttribute("loginUser") LoginVO loginVO,
			 																  @RequestParam String regYmd, @RequestParam String gupSn, @RequestParam List<String> addCdeList,
																			  @RequestParam List<String> dirSucList, @RequestParam List<String> dirSncList,
																			  @RequestParam List<String> dirLucList, @RequestParam List<String> dirLncList,
																			  @RequestParam List<String> outCosList, @RequestParam List<String> covCosList) throws Exception{

		Map<String, Object> resultMap = new HashMap<String, Object>();

		List<EgovMap> guifCodeList = mngDangaService.selectGuifList();

		for (int i = 0; i < addCdeList.size(); i++) {

			// 개별 값들
			String suc  = dirSucList.get(i);
			String snc  = dirSncList.get(i);
			String luc  = dirLucList.get(i);
			String lnc  = dirLncList.get(i);
			String outc = outCosList.get(i);
			String covc = covCosList.get(i);

			if (isEmpty(suc)) throw new RuntimeException("주간/잔토있음 값 누락");
			if (isEmpty(snc)) throw new RuntimeException("주간/잔토없음 값 누락");
			if (isEmpty(luc)) throw new RuntimeException("야간/잔토있음 값 누락");
			if (isEmpty(lnc)) throw new RuntimeException("야간/잔토없음 값 누락");
			if (isEmpty(outc)) throw new RuntimeException("표층/중층 값 누락");
			if (isEmpty(covc)) throw new RuntimeException("덧씌우기 값 누락");

			validateNumeric(suc);
			validateNumeric(snc);
			validateNumeric(luc);
			validateNumeric(lnc);
			validateNumeric(outc);
			validateNumeric(covc);

		}

		int result = 0;
		regYmd = regYmd.replace("-", "");
		int nGupSn = Integer.parseInt(gupSn) +1;
		for(int i = 0; i < addCdeList.size(); i++){
			for(EgovMap map : guifCodeList){
				MngDangaVO vo = new MngDangaVO();
				vo.setGcsRegYmd(regYmd);
				vo.setMngInstCd((String) map.get("mngInstCd"));
				vo.setPackngKnd(addCdeList.get(i));
				vo.setGupSn(nGupSn);
				vo.setUserAcntMngNo(loginVO.getUserUnqId());
				vo.setWikDrctRexpExisSuoi(dirSucList.get(i));
				vo.setWikDrctRexpNthgSuoi(dirSncList.get(i));
				vo.setNightDrctRexpExisSuoi(dirLucList.get(i));
				vo.setNightDrctRexpNthgSuoi(dirLncList.get(i));
				vo.setIdrtRexpSulyTms(outCosList.get(i));
				vo.setIdrtRexpCoai(covCosList.get(i));
				result += mngDangaService.insertGupt(vo);
			}
		}
		resultMap.put("result", result);
		return ResponseEntity.ok(DefaultApiResponse.success(resultMap));
	}
	
	/**
	 *
	 * @MethodDESC : 점용료 상세 조회.
	 */
	@RequestMapping(value = "/MngDangaR020.do")
	public String selectDangaViewGUFE(@ModelAttribute("rdmOeDangaVO") MngDangaVO vo, ModelMap model) throws Exception{

		List guifCodeList = rdmComCodeService.selectGuifList("N");
		model.addAttribute("guifCodeList", guifCodeList);

		if ((vo.getMngInstCd() == null || vo.getMngInstCd().isEmpty())
				&& guifCodeList != null && !guifCodeList.isEmpty()) {

			Object first = guifCodeList.get(1);

			if (first instanceof org.egovframe.rte.psl.dataaccess.util.EgovMap egovMap) {
				vo.setMngInstCd((String) egovMap.get("mngInstCd"));
			}
			else if (first instanceof RdmComCodeVO codeVo) {
				vo.setMngInstCd(codeVo.getMngInstCd());
			}
		}

		List resultList = mngDangaService.selectDangaViewGUFE(vo);
		List resultListGUPP = mngDangaService.selectDangaViewGUPP(vo);

		model.addAttribute("resultList", resultList);
		model.addAttribute("resultListGUPP", resultListGUPP);
		
		model.addAttribute("searchVo", vo);
		
		return "res/mng/danga/MngDangaR020";
	}

	/**
	 * @MethodDESC : 점용료 수정화면 이동.
	 */
	@RequestMapping(value = "/MngDangaU020.do")
	public String insertGufeView(@ModelAttribute("rdmOeDangaVO") MngDangaVO vo, ModelMap model) throws Exception{

		List resultList = mngDangaService.selectDangaViewGUFE(vo);
		List resultListGUPP = mngDangaService.selectDangaViewGUPP(vo);
		model.addAttribute("resultList", resultList);
		model.addAttribute("resultListGUPP", resultListGUPP);
		return "res/mng/danga/MngDangaU020";
	}

	/**
	 * @MethodDESC : 점용료  등록.
	 */
	@Transactional
	@RequestMapping(value = "MngDangaC020.do")
	public ResponseEntity<DefaultApiResponse<Map<String, Object>>> insertGufe(@ModelAttribute MngDangaVO mngDangaVO, @RequestParam List<String> occAmtList,
																			  @RequestParam String litSn, @RequestParam List<String> dirCs1List,
																			  @RequestParam List<String> dirCs2List, @RequestParam String guppSn,
																			  @RequestParam String regYmd, @RequestParam String srtpdCrtrFndgYmd,
																			  @ModelAttribute("loginUser") LoginVO loginVO,@RequestParam List<String> cosCdeList) throws Exception{

		Map<String, Object> resultMap = new HashMap<String, Object>();

		String mngCde = mngDangaVO.getMngInstCd();

		for (int i = 0; i < occAmtList.size(); i++) {

			if (isEmpty(occAmtList.get(i)))
				throw new RuntimeException("점용료 값 누락");
			validateNumeric(occAmtList.get(i));
		}

		for (int j = 0; j < cosCdeList.size(); j++) {

			if (isEmpty(dirCs1List.get(j)))
				throw new RuntimeException("외곽점용료 누락");

			if (isEmpty(dirCs2List.get(j)))
				throw new RuntimeException("중심부점용료 누락");

			validateNumeric(dirCs1List.get(j));
			validateNumeric(dirCs2List.get(j));
		}

		int result = 0;
		regYmd = regYmd.replace("-", "");
		srtpdCrtrFndgYmd = srtpdCrtrFndgYmd.replace("-", "");
		int nGuppSn = Integer.parseInt(guppSn) + 1;
		int nLitSn = Integer.parseInt(litSn) + 1;
		for(int i = 0; i < occAmtList.size(); i++){
			MngDangaVO vo = new MngDangaVO();
			vo.setMngInstCd(mngCde);
			vo.setLitSn(nLitSn);
			vo.setUserAcntMngNo(loginVO.getUserUnqId());
			vo.setSrtpdCrtrFndgYmd(srtpdCrtrFndgYmd);
			vo.setOauf(occAmtList.get(i));
			result += mngDangaService.insertGufe(vo);
		}

		for(int j = 0; j < cosCdeList.size(); j++){
			MngDangaVO dvo = new MngDangaVO();
			dvo.setMngInstCd(mngCde);
			dvo.setGupSn(nGuppSn);
			dvo.setGcsRegYmd(regYmd);
			dvo.setUserAcntMngNo(loginVO.getUserUnqId());
			dvo.setDggCd(cosCdeList.get(j));
			dvo.setSubuOauf(dirCs1List.get(j));
			dvo.setCoreOauf(dirCs2List.get(j));
			result += mngDangaService.insertGupp(dvo);
		}
		resultMap.put("result", result);
		return ResponseEntity.ok(DefaultApiResponse.success(resultMap));
	}
	
	/**
	 * @MethodDESC : 면허세 상세 조회.
	 */
	@RequestMapping(value = "/MngDangaR030.do")
	public String selectDangaViewLITX(@ModelAttribute("rdmOeDangaVO") MngDangaVO vo, ModelMap model) throws Exception{
		
		List resultList = mngDangaService.selectDangaViewLITX(vo);
		
		model.addAttribute("resultList", resultList);
		model.addAttribute("searchVo", vo);
		
		return "res/mng/danga/MngDangaR030";
	}

	/**
	 * @MethodDESC : 면허세 수정화면 이동.
	 */
	@RequestMapping(value = "/MngDangaU030.do")
	public String insertLitxView(@ModelAttribute("rdmOeDangaVO") MngDangaVO vo, ModelMap model) throws Exception{

		List resultList = mngDangaService.selectDangaViewLITX(vo);
		model.addAttribute("resultList", resultList);
		return "res/mng/danga/MngDangaU030";
	}

	/**
	 * @MethodDESC : 면허세  등록.
	 */
	@Transactional
	@RequestMapping(value = "MngDangaC030.do")
	public ResponseEntity<DefaultApiResponse<Map<String, Object>>> insertLitx(@RequestParam List<String> jngGbnList, @RequestParam String lixSn,
																			  @RequestParam List<String> lixAmtList, @RequestParam List<String> lixAreList,
																			  @RequestParam List<String> lixDesList, @RequestParam String regYmd) throws Exception{

		Map<String, Object> resultMap = new HashMap<String, Object>();
		for (int i = 0; i < jngGbnList.size(); i++) {
			if (isEmpty(lixAmtList.get(i)))
				throw new RuntimeException("면허세 값 누락");
			validateNumeric(lixAmtList.get(i));
		}

		int result = 0;
		regYmd = regYmd.replace("-", "");
		int nLixSn = Integer.parseInt(lixSn) + 1;
		for(int i = 0; i < jngGbnList.size(); i++){
			MngDangaVO vo = new MngDangaVO();
			vo.setSe(jngGbnList.get(i));
			vo.setLixSn(nLixSn);
			vo.setLnx(lixAmtList.get(i));
			vo.setAreaInfo(lixAreList.get(i));
			vo.setRmrk(lixDesList.get(i));
			vo.setRegYmd(regYmd);
			result += mngDangaService.insertLitx(vo);
		}
		resultMap.put("result", result);
		return ResponseEntity.ok(DefaultApiResponse.success(resultMap));
	}
	
	/**
	 * @MethodDESC : 최소굴착면적 상세 조회.
	 */
	@RequestMapping(value = "/MngDangaR040.do")
	public String selectDangaViewMDWA(@ModelAttribute("rdmOeDangaVO") MngDangaVO vo, ModelMap model) throws Exception{

		vo.setMngInstCd("3490000");
		
		List resultList = mngDangaService.selectDangaViewMDWA(vo);
		
		model.addAttribute("resultList", resultList);
		model.addAttribute("searchVo", vo);
		
		return "res/mng/danga/MngDangaR040";
	}

	/**
	 * @MethodDESC : 최소굴착면적 수정화면 이동.
	 */
	@RequestMapping(value = "/MngDangaU040.do")
	public String insertMdwaView(@ModelAttribute("rdmOeDangaVO") MngDangaVO vo, ModelMap model) throws Exception{

		vo.setMngInstCd("3490000");

		List resultList = mngDangaService.selectDangaViewMDWA(vo);
		model.addAttribute("resultList", resultList);
		return "res/mng/danga/MngDangaU040";
	}

	/**
	 * @MethodDESC : 최소굴착면적  등록.
	 */
	@RequestMapping(value = "MngDangaC040.do")
	public ResponseEntity<DefaultApiResponse<Map<String, Object>>> insertMdwa(@ModelAttribute MngDangaVO vo) throws Exception{

		Map<String, Object> errors = new HashMap<String, Object>();

		validateNumeric62(vo.getMinDggAreaRodwayPrlg());
		validateNumeric62(vo.getMinDggAreaRodwayBt());
		validateNumeric62(vo.getMinDggAreaBlocTilePrlg());
		validateNumeric62(vo.getMinDggAreaBlocTileBt());
		validateNumeric62(vo.getMinDggAreaAacncrtPrlg());
		validateNumeric62(vo.getMinDggAreaAacncrtBt());
		validateNumeric62(vo.getMinDggRodwayBt());
		validateNumeric62(vo.getMinDggBlocTileBt());
		validateNumeric62(vo.getMinDggApnrtAsphCncrtBt());

		if (!errors.isEmpty()) {
			return ResponseEntity.status(HttpStatus.BAD_REQUEST)
					.body(DefaultApiResponse.<Map<String, Object>>builder()
							.code(ResponseCode.INPUT_ERROR.getCode())
							.message("입력값 형식 오류")
							.data(errors)
							.error("ValidationException")
							.timestamp(java.time.LocalDateTime.now())
							.build()
					);
		}

		List<EgovMap> guifCodeList = mngDangaService.selectGuifList();

		int result = 0;

		for(EgovMap map : guifCodeList){
			vo.setMngInstCd((String) map.get("mngInstCd"));
			if(!vo.getMngInstCd().isEmpty()){
				result += mngDangaService.insertMdwa(vo);
			}
		}
		Map<String, Object> resultMap = new HashMap<>();

		resultMap.put("result", result);
		return ResponseEntity.ok(DefaultApiResponse.success(resultMap));
	}

	private void validateNumeric(String val) {
		if (!val.matches("^[0-9]+$")) {
			throw new RuntimeException("숫자 형식이 아님: " + val);
		}
	}

	private void validateNumeric62(String val) {

		if (val == null || val.trim().isEmpty()) {
			throw new RuntimeException("값이 비어있음");
		}

		if (!val.matches("^\\d{1,4}(\\.\\d{1,2})?$")) {
			throw new RuntimeException("numeric(6,2) 형식이 아님: " + val);
		}
	}
}
