package kcg.faics.report.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.annotation.Resource;

import kcg.faics.cmmn.vo.CodeVO;
import kcg.faics.member.Duty;
import kcg.faics.member.vo.MemberVO;
import kcg.faics.report.service.ReportCategoryService;
import kcg.faics.report.service.ReportJudgeService;
import kcg.faics.report.service.ReportService;
import kcg.faics.report.vo.ReportJudgeVO;
import kcg.faics.report.vo.ReportSearchVO;
import kcg.faics.report.vo.ReportVO;
import kcg.faics.report.web.ReportCommon;
import kcg.faics.sec.LoginUserVO;
import kcg.faics.sec.UserUtil;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import egovframework.rte.fdl.cmmn.EgovAbstractServiceImpl;

/**
 * 견문 평가 서비스
 * 
 * @author 하영지
 * @since 2016. 10. 6.
 */
@Service("reportJudgeService")
public class ReportJudgeServiceImpl extends EgovAbstractServiceImpl implements ReportJudgeService {

	/**
	 * 견문 분류 인터페이스
	 */
	@Resource(name = "reportCategoryService")
	private ReportCategoryService cateService;

	/**
	 * 견문 관련 인터페이스
	 */
	@Resource(name = "reportService")
	private ReportService reportService;

	/**
	 * 견문 평가 맵퍼
	 */
	@Resource(name = "reportJudgeMapper")
	private ReportJudgeMapper reportJudgeMapper;

	/**
	 * 견문 평가 종류를 검색한다.
	 */
	@Override
	public List<CodeVO> selectJudgeCode() throws Exception {
		return reportJudgeMapper.selectJudgeCode();
	}
	
	/**
	 * 견문 평가 정보를 반환한다.
	 */
	@Override
	public ReportJudgeVO selectOne(final int juseq) throws Exception {
		return reportJudgeMapper.selectOne(juseq);
	}

	@Override
	public String getJudgeStr(final int judgeCode) throws Exception {
		return reportJudgeMapper.getJudgeName(judgeCode);
	}

	/**
	 * 맵으로 변환 
	 * @return ("코드명", "코드") 형식으로 리턴
	 */	
	public HashMap<String, String> judgeList() {

		HashMap<String, String> map = new HashMap<String, String>();
		List<CodeVO> list;
		try {
			list = selectJudgeCode();
			
			Iterator<CodeVO> itr = list.iterator();
			while (itr.hasNext()) {
				CodeVO code = itr.next();
				map.put(code.getCode2(), code.getCodenm());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return map;
	}

	@Override
	public int insert(final ReportJudgeVO reportJudgeVO) throws Exception {
		return reportJudgeMapper.insert(reportJudgeVO);
	}
	
	
	@Override
	public MemberVO selectApprove() throws Exception {
		LoginUserVO loginUserVO = UserUtil.getMemberInfo(); 
		return reportJudgeMapper.selectApprove(loginUserVO);
	}

	@Override
	public HashMap<String, Object> approve(final ReportVO reportVO) throws Exception {
		HashMap<String, Object> map = new HashMap<String, Object>();
		String errorMsg = "";
		try {
			List<ReportVO> list = new ArrayList<ReportVO>(); 
			if (reportVO.getReportList() == null && reportVO.getInSeq() > 0) {
				list.add(0, reportVO);
			} else if (reportVO.getReportList() != null && reportVO.getReportList().size() > 0) {
				list = reportVO.getReportList();
			} else {
				map.put("result", -1);
				map.put("msg", "결재할 견문이 없습니다.");
				return map;
			}
			
			MemberVO reportApproveVO = selectApprove();
	
			LoginUserVO loginUserVO = UserUtil.getMemberInfo();
			int myGroupCode = ReportCommon.getMyGroupCode();
			int myDutiesCode = ReportCommon.getDutiesCodeForApprove(loginUserVO.getDuties());
			
			if (myDutiesCode == 2 && reportApproveVO == null) {
				map.put("result", -1);
				map.put("msg", "계장 정보가 없습니다. 권한 설정에서 계장을 선택하십시오.");
				return map;
			} else if (reportApproveVO == null && myDutiesCode == 3) {
				map.put("result", -1);
				map.put("msg", "과장 정보가 없습니다. 권한 설정에서 과장을 선택하십시오.");
				return map;
			}
			
			int cnt = 1;
			int mgcHead = 0;
			int mgcSection = 0;
			int mgcReport = 0;
			ReportVO tempVO = new ReportVO();
			for (ReportVO vo : list) {
				if (vo.getInSeq() <= 0) {
					continue;
				}
				tempVO = reportService.select(vo);
				
				if (StringUtils.isNotBlank(vo.getInStateCode())) {
					tempVO.setInCategory1(vo.getInCategory1()); 
					tempVO.setInCategory2(vo.getInCategory2());
					tempVO.setInCategory3(vo.getInCategory3());
					tempVO.setInCategory4(vo.getInCategory4());
					tempVO.setInSubject(vo.getInSubject());
					
					String infoDate = vo.getStrInfodate().toString();
					tempVO.setInInfoYear(Integer.valueOf(infoDate.split("-")[0]));
					tempVO.setInInfoMonth(Integer.valueOf(infoDate.split("-")[1]));
					tempVO.setInInfoDay(Integer.valueOf(infoDate.split("-")[2]));
					
					tempVO.setInStateCode(vo.getInStateCode());
				}
				
				if (vo.getInJudge() > 0) {
					tempVO.setInJudge(vo.getInJudge());
				}
				if (vo.getInJudge4() > 0) {
					tempVO.setInJudge4(vo.getInJudge4());
				}
				if (vo.getInJudge5() > 0) {
					tempVO.setInJudge5(vo.getInJudge5());
				}
				if (vo.getInJudge6() > 0) {
					tempVO.setInJudge6(vo.getInJudge6());
				}
			
				if (vo.getInReport() > 0) {
					tempVO.setInReport(vo.getInReport());
				}
				if (vo.getInReport4() > 0) {
					tempVO.setInReport4(vo.getInReport4());
				}
				if (vo.getInReport5() > 0) {
					tempVO.setInReport5(vo.getInReport5());
				}
				if (vo.getInReport6() > 0) {
					tempVO.setInReport6(vo.getInReport6());	
				}
	
				tempVO.setJuMsg(vo.getJuMsg());
				
				if (tempVO.equals(null)) {
					 errorMsg += String.valueOf(cnt) + "번째 견문은 이미 삭제된 견문입니다.\n";
					 continue;
				} else {
					if (Character.getNumericValue(tempVO.getInStateCode().charAt(0)) != myGroupCode) {
						 errorMsg += String.valueOf(cnt) + "번째 견문은 이미 결재된 견문입니다.\n";
						 continue;
					} 
					if (vo.getInReport() > 0 && myGroupCode == 3) {
						 errorMsg += String.valueOf(cnt) + "번째 견문은 본청에서는 상보처리 할 수 없습니다.\n";
						 continue;
					}
					
					switch (myGroupCode) {
					case 1:
						mgcHead = tempVO.getInJuseq1Head();
						mgcSection = tempVO.getInJuseq1Section();
						mgcReport = tempVO.getInReport1();
						break;
					case 2:
						mgcHead = tempVO.getInJuseq2Head();
						mgcSection = tempVO.getInJuseq2Section();
						mgcReport = tempVO.getInReport2();
						break;
					case 3:
						mgcHead = tempVO.getInJuseq3Head();
						mgcSection = tempVO.getInJuseq3Section();
						mgcReport = tempVO.getInReport3();
					default:
						break;
					}
					
					if (mgcHead > 0 && mgcSection > 0) {
						errorMsg += String.valueOf(cnt) + "번째 견문은 이미 결재된 견문입니다.\n";
						continue;
					}
					if (myDutiesCode == 2 && mgcSection > 0) {
						errorMsg += String.valueOf(cnt) + "번째 견문은 이미 결재된 견문입니다.\n";
						continue;
					}
					if (myDutiesCode == 3 && mgcHead > 0) {
						errorMsg += String.valueOf(cnt) + "번째 견문은 이미 결재된 견문입니다.\n";
						continue;
					}
					if (vo.getInReport() > 0 && mgcReport > 0) {
						errorMsg += String.valueOf(cnt) + "번째 견문은 이미 결재된 견문입니다.\n";
						continue;
					}
				}
				String postState = "";
				if ((myDutiesCode == 2 && mgcHead > 0) || (myDutiesCode == 3 && mgcSection > 0) || loginUserVO.getAuthProxyHead() > 0) {
					postState = "4";
				} else {
					postState = String.valueOf(myDutiesCode);
				}
				
				// 상태코드 설정
				String newStateCode = String.valueOf(myGroupCode) + postState;
				
				if (postState.equals("4") && (vo.getInReport() > 0 || mgcReport > 0)) {
					//상보처리
					newStateCode = String.valueOf(myGroupCode + 1) + "1";
				}
				
				tempVO.setInStateCode(newStateCode);
				if (Character.getNumericValue(newStateCode.charAt(1)) == 4) {
					tempVO.setInComplete("1");
				}
				
				// 견문 평가 객체를 생성한다.
				ReportJudgeVO reportJudgeVO = new ReportJudgeVO();
				reportJudgeVO.setJuInseq(vo.getInSeq());
				reportJudgeVO.setJuGroupCode(myGroupCode);
				reportJudgeVO.setJuJudge(vo.getInJudge());
				reportJudgeVO.setJuReport(vo.getInReport());
				reportJudgeVO.setJuPlace1(reportApproveVO.getPlace1Str());
				reportJudgeVO.setJuPlace2(reportApproveVO.getPlace2Str());
				reportJudgeVO.setJuPosition(reportApproveVO.getPositionStr());
				reportJudgeVO.setJuName(reportApproveVO.getName());
				reportJudgeVO.setJuUserid(reportApproveVO.getUserid());
				reportJudgeVO.setJuProxyId(loginUserVO.getUserid());
				reportJudgeVO.setJuDutiesCode(String.valueOf(myDutiesCode));
				reportJudgeVO.setJuMessage(tempVO.getJuMsg());
				
				int juSeq = insert(reportJudgeVO);
				
				if (myDutiesCode == 2) {
					if (myGroupCode == 1) {
						tempVO.setInJuseq1Section(juSeq);
					} else if (myGroupCode == 2) {
						tempVO.setInJuseq2Section(juSeq);
					} else if (myGroupCode == 3) {
						tempVO.setInJuseq3Section(juSeq);
					}
				} else {
					if (myGroupCode != 3) {
						tempVO.setInReport(vo.getInReport());
						if (myGroupCode == 1) {
							tempVO.setInReport1(vo.getInReport());
						} else if (myGroupCode == 2) {
							tempVO.setInReport2(vo.getInReport());
						} else if (myGroupCode == 3) {
							tempVO.setInReport3(vo.getInReport());
						}
					}
					
					tempVO.setInJudge(vo.getInJudge());
					if (vo.getInJudge4() > 0) {
						tempVO.setInJudge4(vo.getInJudge4());
					}
					if (vo.getInJudge5() > 0) {
						tempVO.setInJudge5(vo.getInJudge5());
					}
					if (vo.getInJudge6() > 0) {
						tempVO.setInJudge6(vo.getInJudge6());
					}
					
					if (myGroupCode == 1) {
						tempVO.setInJudge1(vo.getInJudge());
						tempVO.setInJuseq1Head(juSeq);
					} else if (myGroupCode == 2) {
						tempVO.setInJudge2(vo.getInJudge());
						tempVO.setInJuseq2Head(juSeq);
					} else if (myGroupCode == 3) {
						tempVO.setInJudge3(vo.getInJudge());
						tempVO.setInJuseq3Head(juSeq);
					}
				}
				
				HashMap<String, Object> result = reportService.update(tempVO, null, null);

				if (Integer.parseInt(result.get("result").toString()) > 0) {
					errorMsg = "";
				}
				
				cnt++;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		map.put("msg", errorMsg);
		
		return map;
	}
	
	@Override
	public int update(final ReportJudgeVO reportJudgeVO) throws Exception {
		return reportJudgeMapper.update(reportJudgeVO);
	}

	@Override
	public List<ReportVO> selectWaitList(final ReportSearchVO reportSearchVO) {
		return reportJudgeMapper.selectWaitList(reportSearchVO);
	}

	@Override
	public List<ReportVO> selectWaitListAll(final ReportSearchVO reportSearchVO) {
		return reportJudgeMapper.selectWaitListAll(reportSearchVO);
	}

	@Override
	public int selectWaitListCnt(final ReportSearchVO reportSearchVO) {
		return reportJudgeMapper.selectWaitListCnt(reportSearchVO);
	}
	
	@Override
	public List<ReportVO> selectApproveList(final ReportSearchVO reportSearchVO) throws Exception {
		return reportJudgeMapper.selectApproveList(reportSearchVO);
	}
	
	@Override
	public int selectApproveListCnt(final ReportSearchVO reportSearchVO) throws Exception {
		return reportJudgeMapper.selectApproveListCnt(reportSearchVO);
	}

	@Override
	public List<ReportVO> selectApproveListAll(final ReportSearchVO reportSearchVO) throws Exception {
		return reportJudgeMapper.selectApproveListAll(reportSearchVO);
	}

	@Override
	public List<ReportVO> selectMyList(final ReportSearchVO reportSearchVO) throws Exception {
		return reportJudgeMapper.selectMyList(reportSearchVO);
	}
	
	@Override
	public int selectMyListCnt(final ReportSearchVO reportSearchVO) throws Exception {
		return reportJudgeMapper.selectMyListCnt(reportSearchVO);
	}

	@Override
	public List<ReportVO> selectMyListAll(final ReportSearchVO reportSearchVO) throws Exception {
		return reportJudgeMapper.selectMyListAll(reportSearchVO);
	}

	@Override
	public List<HashMap<String, String>> statsCategory(final ReportSearchVO reportSearchVO) throws Exception {
		List<HashMap<String, String>> cateMap = new ArrayList<HashMap<String, String>>();
		
		int idx = 0;
		if (reportSearchVO.isSearchCate1()) {
			reportSearchVO.setCategoryType(1);
			for (HashMap<String, String> newMap : reportJudgeMapper.statsCategory(reportSearchVO)) {				
				
				HashMap<String, String> ttt = new HashMap<String, String>();
				for (String mapKey : newMap.keySet()) {
					if (!mapKey.equals("total") && !mapKey.equals("placename") && !mapKey.equals("placecode")) {
						ttt.put(mapKey + "_1", newMap.get(mapKey));
					}
				}
				ttt.put("placename", newMap.get("placename"));

				if (cateMap.size() > idx && cateMap.get(idx) != null) {
					cateMap.get(idx).putAll(ttt);
					cateMap.get(idx).put("total", String.valueOf(Integer.parseInt(cateMap.get(idx).get("total").toString()) + Integer.parseInt(newMap.get("total").toString())));
				} else {
					ttt.put("total", newMap.get("total"));
					cateMap.add(idx, ttt);
				}
				idx++;
				
			}
		}
		
		idx = 0;
		if (reportSearchVO.isSearchCate2()) {
			reportSearchVO.setCategoryType(2);
			for (HashMap<String, String> newMap : reportJudgeMapper.statsCategory(reportSearchVO)) {
				
				HashMap<String, String> ttt = new HashMap<String, String>();
				
				for (String mapKey : newMap.keySet()) {
					if (!mapKey.equals("total") && !mapKey.equals("placename") && !mapKey.equals("placecode")) {
						ttt.put(mapKey + "_2", newMap.get(mapKey));
					}
					ttt.put("placename", newMap.get("placename"));
				}
				
				if (cateMap.size() > idx && cateMap.get(idx) != null) {
					cateMap.get(idx).putAll(ttt);
					cateMap.get(idx).put("total", String.valueOf((Integer.parseInt(String.valueOf(cateMap.get(idx).get("total"))) + Integer.parseInt(String.valueOf(newMap.get("total"))))));
				} else {
					ttt.put("total", newMap.get("total"));
					cateMap.add(idx, ttt);
				}
				idx++;
			}
		}
		
		idx = 0;
		if (reportSearchVO.isSearchCate3()) {
			reportSearchVO.setCategoryType(3);
			for (HashMap<String, String> newMap : reportJudgeMapper.statsCategory(reportSearchVO)) {
				
				HashMap<String, String> ttt = new HashMap<String, String>();
				
				for (String mapKey : newMap.keySet()) {
					if (!mapKey.equals("total") && !mapKey.equals("placename") && !mapKey.equals("placecode")) {
						ttt.put(mapKey + "_3", newMap.get(mapKey));
					}
					ttt.put("placename", newMap.get("placename"));
				}

				if (cateMap.size() > idx && cateMap.get(idx) != null) {
					cateMap.get(idx).putAll(ttt);
					cateMap.get(idx).put("total", String.valueOf(Integer.parseInt(String.valueOf(cateMap.get(idx).get("total"))) + Integer.parseInt(String.valueOf(newMap.get("total")))));
				} else {
					ttt.put("total", newMap.get("total"));
					cateMap.add(idx, ttt);
				}
				idx++;
			}
		}

		idx = 0;
		if (reportSearchVO.isSearchCate4()) {
			reportSearchVO.setCategoryType(4);
			for (HashMap<String, String> newMap : reportJudgeMapper.statsCategory(reportSearchVO)) {
				
				HashMap<String, String> ttt = new HashMap<String, String>();
				
				for (String mapKey : newMap.keySet()) {
					if (!mapKey.equals("total") && !mapKey.equals("placename") && !mapKey.equals("placecode")) {
						ttt.put(mapKey + "_4", newMap.get(mapKey));
					}
					ttt.put("placename", newMap.get("placename"));
				}

				if (cateMap.size() > idx && cateMap.get(idx) != null) {
					cateMap.get(idx).putAll(ttt);
					cateMap.get(idx).put("total", String.valueOf(Integer.parseInt(String.valueOf(cateMap.get(idx).get("total"))) + Integer.parseInt(String.valueOf(newMap.get("total")))));
				} else {
					ttt.put("total", newMap.get("total"));
					cateMap.add(idx, ttt);
				}
				idx++;
			}
		}
		
		if (cateMap.size() > 0) {
			HashMap<String, String> totalMap = new HashMap<String, String>();
			totalMap.put("placename", "누계");
			
			for (String key : cateMap.get(0).keySet()) {
				if (key.equals("placename")) {
					continue;
				}
				int tt = 0;
				for (HashMap<String, String> hashMap : cateMap) {
					tt = tt + Integer.parseInt(String.valueOf(hashMap.get(key)));
				}
				totalMap.put(key, String.valueOf(tt));
			}
			
			cateMap.add(cateMap.size(), totalMap);	
		}

		return cateMap;
	}

	@Override
	public List<HashMap<String, String>> statsJudge(final ReportSearchVO reportSearchVO) throws Exception {
		List<HashMap<String, String>> list = reportJudgeMapper.statsJudge(reportSearchVO);
		
		HashMap<String, String> map = new HashMap<String, String>();
		map.put("placename", "누계");
		
		if (list.size() > 0) {
			for (String key : list.get(0).keySet()) {
				if (key.equals("placename")) {
					continue;
				}
				int total = 0;
				for (HashMap<String, String> item : list) {
					total = total + Integer.parseInt(item.get(key));
				}
				map.put(key, String.valueOf(total));
			}
		} else {
			map.put("REPORT1", "0");
			map.put("REPORT2", "0");
			map.put("JU1", "0");
			map.put("JU2", "0");
			map.put("JU3", "0");
			map.put("JU4", "0");
			map.put("JU5", "0");
			map.put("JU6", "0");
			map.put("JU7", "0");
			map.put("AG", "0");
			map.put("BG", "0");
			map.put("CG", "0");
			map.put("DG", "0");
		}
		
		list.add(list.size(), map);
		
		return list;
	}
	
}
