package cokr.xit.fims.stat.service.bean;

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

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import cokr.xit.base.code.CommonCode;
import cokr.xit.fims.cmmn.CmmnUtil;
import cokr.xit.fims.cmmn.CrdnSttsHstryQuery;
import cokr.xit.fims.cmmn.service.CrdnSttsHstryService;
import cokr.xit.fims.crdn.CrdnQuery;
import cokr.xit.fims.crdn.service.CrdnService;
import cokr.xit.fims.crdn.service.bean.CrdnStngBean;
import cokr.xit.fims.excl.LevyExclQuery;
import cokr.xit.fims.excl.service.OpnnSbmsnService;
import cokr.xit.fims.sndb.SndbQuery;
import cokr.xit.fims.sndb.service.SndngService;
import cokr.xit.fims.stat.NumberValueInfo;
import cokr.xit.fims.stat.Stat;
import cokr.xit.fims.stat.StatQuery;
import cokr.xit.fims.stat.service.StatService;
import cokr.xit.foundation.component.AbstractServiceBean;
import cokr.xit.foundation.data.DataObject;

@Service("statService")
public class StatServiceBean extends AbstractServiceBean implements StatService {
	@Resource(name = "crdnService")
	private CrdnService crdnService;
	@Resource(name = "crdnSttsHstryService")
	private CrdnSttsHstryService crdnSttsHstryService;
	@Resource(name = "opnnSbmsnService")
	private OpnnSbmsnService opnnSbmsnService;
	@Resource(name = "sndngService")
	private SndngService sndngService;
	@Resource(name = "statBean")
	private StatBean statBean;
	@Resource(name = "crdnStngBean")
	private CrdnStngBean crdnStngBean;

	@Override
	public Stat getStatistics(StatQuery statQuery, Map<String, List<CommonCode>> commonCodes) {
		Stat stat = new Stat();
		List<DataObject> queryResult = new ArrayList<>();
		String today = dateFormats.format("yyyyMMdd", System.currentTimeMillis());
		boolean daySetting = false;

		if (statQuery.getStructureType().equals("aggregate")) {
			String dayColumn = blankIfEmpty(statQuery.getDayColumn());
			String lastDay = blankIfEmpty(statQuery.getLastDay());
			String firstDay = blankIfEmpty(statQuery.getFirstDay());

			if (!dayColumn.isEmpty()) {
				daySetting = true;
			}

			String[] numberValueLabel = null;
			String namedNumberValueSeperator = ifEmpty(statQuery.getNamedNumberValueSeperator(), () -> "");

			if (namedNumberValueSeperator.equals("completeAndTotal")) { //완료자료 및 전체자료
				String globalAggregate = statQuery.getGlobalAggregate();
				String globalSumRefCol = ifEmpty(statQuery.getGlobalSumRefCol(), () -> "") ;

				List<NumberValueInfo> numberValueInfoList = new ArrayList<NumberValueInfo>();
				NumberValueInfo col1 = new NumberValueInfo();
				col1.setSeperatorRefCol("COMPLETE_YN");
				col1.setConditionValue("Y");
				col1.setAggregateType(globalAggregate);
				col1.setSumRefCol(globalSumRefCol);
				numberValueInfoList.add(col1);
				NumberValueInfo col2 = new NumberValueInfo();
				col2.setAggregateType(globalAggregate);
				col2.setSumRefCol(globalSumRefCol);
				numberValueInfoList.add(col2);
				statQuery.setNumberValueInfoList(numberValueInfoList);

				numberValueLabel = new String[] {"처리","전체"};

				daySetting = true;

			} else if (namedNumberValueSeperator.equals("lastFewDays")) {
				daySetting = true;

				int dayRange = statQuery.getDayRange() == 0 ? 15 : statQuery.getDayRange();

				if (isEmpty(dayColumn)) {
					dayColumn = "REG_DT";
				}

				lastDay = today;
				firstDay = CmmnUtil.addDay(lastDay, (-1 * (dayRange-1)));

				String globalAggregate = statQuery.getGlobalAggregate();

				List<NumberValueInfo> numberValueInfoList = new ArrayList<NumberValueInfo>();

				for (int i =0; i < dayRange; i++) {
					NumberValueInfo numberValueInfo = new NumberValueInfo();
					numberValueInfo.setSeperatorRefCol(dayColumn);
					numberValueInfo.setConditionValue(CmmnUtil.addDay(firstDay,i));
					numberValueInfo.setSeperatorCtgrType("date");
					numberValueInfo.setSeperatorCtgrType("YYYYMMDD");
					numberValueInfo.setAggregateType(globalAggregate);
					numberValueInfoList.add(numberValueInfo);
				}
				statQuery.setNumberValueInfoList(numberValueInfoList);

				numberValueLabel = new String[dayRange];
				for (int i =0; i < dayRange; i++) {
					if (i == (dayRange-1)) {
						numberValueLabel[i] = "금일";
					} else {
						numberValueLabel[i] = Integer.toString((dayRange - (i+1)));
					}
				}

			}

			String domain = statQuery.getStatDomain();
			if (isEmpty(domain))
				throw new RuntimeException("통계 유형 확인 오류");

			String domainKey = "";
			if (domain.equals("crdn")) {
				domainKey = "CRDN_ID";

				CrdnQuery crdnQuery = new CrdnQuery()
					.setSggCd(statQuery.getSggCd())
					.setTaskSeCd(statQuery.getTaskSeCd());

				if (daySetting) {
					statBean.daySetting(crdnQuery, crdnQuery.getClass().getSimpleName(), dayColumn, firstDay, lastDay);
				}

				queryResult = crdnService.getCrackdownList(crdnQuery);
			} else if (domain.equals("crdnSttsHstry")) {
				domainKey = "CRDN_ID";

				CrdnSttsHstryQuery crdnSttsHstryQuery = new CrdnSttsHstryQuery()
					.setSggCd(statQuery.getSggCd())
					.setTaskSeCd(statQuery.getTaskSeCd())
					.setUseYn("Y");

				if (daySetting) {
					statBean.daySetting(crdnSttsHstryQuery, crdnSttsHstryQuery.getClass().getSimpleName(), dayColumn, firstDay, lastDay);
				}

				queryResult = crdnSttsHstryService.getCrdnSttsHstryList(crdnSttsHstryQuery);
			} else if (domain.equals("sndb")) {
				SndbQuery sndbQuery = new SndbQuery();
				sndbQuery.setSggCd(statQuery.getSggCd());
				sndbQuery.setTaskSeCd(statQuery.getTaskSeCd());

				if (daySetting) {
					statBean.daySetting(sndbQuery, sndbQuery.getClass().getSimpleName(), dayColumn, firstDay, lastDay);
				}
				queryResult = sndngService.getSndngList(sndbQuery);
			} else if (domain.equals("excl")) {
				LevyExclQuery levyExclQuery = new LevyExclQuery()
					.setSggCd(statQuery.getSggCd())
					.setTaskSeCd(statQuery.getTaskSeCd());

				if (daySetting) {
					statBean.daySetting(levyExclQuery, levyExclQuery.getClass().getSimpleName(), dayColumn, firstDay, lastDay);
				}

				queryResult = opnnSbmsnService.getOpnnSbmsnList(levyExclQuery);
			} else if (domain.equals("levy")) {
				domainKey = "LEVY_ID";
				//TODO : 부과관련쿼리
			} else if (domain.equals("sprt")) {
				domainKey = "CRDN_ID";
				//TODO : 종합정보쿼리
			} else if (domain.equals("rcvm")) {
				//TODO : 수납관련쿼리
			}

			if (!domainKey.isEmpty()) {
				for (DataObject dataObject: queryResult) {
	        		String dataId = dataObject.string(domainKey);
	        		dataObject.set("DATA_ID", dataId);
				}
			}

			//차량구분 지정
			if (!isEmpty(statQuery.getCarGb())) {
	        	queryResult.removeIf(item -> !(crdnStngBean.getCarGb(item.string("VHRNO")).equals(statQuery.getCarGb())));
			}
			//서손자료 제외
			if (!isEmpty(statQuery.getSchExclEnd())) {
	        	queryResult.removeIf(item -> item.string("CRDN_STTS_CD").equals("81"));
			}
			//렌트카만 조회
			if (!isEmpty(statQuery.getSchOnlyRent())) {
	        	queryResult.removeIf(item -> !crdnStngBean.isRent(item.string("VHRNO")));
			}

			//통계 생성
			stat = statBean.groupByCartegory(queryResult, statQuery);
			//통계 항목명 변환
			statBean.attachItemName(stat.getStatItems(), statQuery, commonCodes);

			//비율 값 계산
			boolean exsistRatioValue = statQuery.getNumberValueInfoList().stream()
				.filter(nvi -> "ratio".equals(nvi.getAggregateType()))
				.count() > 0;
			if (exsistRatioValue){
				statBean.attachRatioValue(stat.getStatItems(), statQuery);
			}

			//수치값 제목(건수, 금액, 비율 등)
			if (numberValueLabel != null) {
				stat.setNumberValueLabel(numberValueLabel);
			}

			//정렬
			statBean.sort(stat);
			stat.setAggregateYn("Y");
		}

		return stat;
	}
}