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

import java.util.List;

import javax.annotation.Resource;

import org.assertj.core.util.Arrays;
import org.springframework.stereotype.Component;

import cokr.xit.fims.cmmn.CmmnUtil;
import cokr.xit.fims.crdn.Crdn;
import cokr.xit.fims.crdn.CrdnQuery;
import cokr.xit.fims.crdn.ExmptnVhcl;
import cokr.xit.fims.crdn.Team;
import cokr.xit.fims.crdn.dao.CrdnStngMapper;
import cokr.xit.fims.crdn.dao.CrdnTeamMapper;
import cokr.xit.fims.crdn.dao.ExmptnVhclMapper;
import cokr.xit.fims.mngt.service.bean.TaskProcessor;
import cokr.xit.foundation.component.AbstractBean;
import cokr.xit.foundation.data.DataObject;

/** 단속 설정 Bean
 * @author leebj
 */
@Component("crdnStngBean")
public class CrdnStngBean extends AbstractBean {
	public static String[] SAFE_TAG_AREA = {"03","06","07"}; //안전표지구역

	public static String[] CAR_GROUP1 = {"12","14","15","21"}; //승합자동차등
	public static String[] CAR_GROUP2 = {"11","13"}; //승용자동차등
	public static String[] CAR_GROUP3 = {"31"}; //이륜자동차등

	@Resource(name = "crdnStngMapper")
	private CrdnStngMapper crdnStngMapper;
	@Resource(name = "crdnTeamMapper")
	private CrdnTeamMapper crdnTeamMapper;
	@Resource(name = "exmptnVhclMapper")
	private ExmptnVhclMapper exmptnVhclMapper;

	/**잔액을 계산한다.
	 * @param state 대장 자료 상태
	 * @param advntceAmt 사전통지금액
	 * @param ffnlgAmt 과태료금액
	 * @param minusAmt 감경금액
	 * @param adtnAmt 가산금액
	 * @param rcvmtAmt 수납금액
	 * @return 잔액
	 */
	public int getBalance(String state, int advntceAmt, int ffnlgAmt, int minusAmt, int adtnAmt, int rcvmtAmt) {
		return toInt(state) < toInt("51") ? advntceAmt - rcvmtAmt - minusAmt :
			switch (state) {
			case "71", "72", "73", "74", "75", "76", "80", "81", "82", "83", "84", "85" -> 0;
			default -> ffnlgAmt - rcvmtAmt - minusAmt + adtnAmt;
			};
	}

	/**기본금액을 계산한다.
	 * @param crdn 단속 정보
	 * @return 최초금액, 사전통지금액
	 */
	public int[] getBasicAmt(Crdn crdn) {
		return TaskProcessor.get().getBasicAmt(crdn);
	}

	/** 차량번호로 렌트카 여부를 확인한다.
	 * @param vhrno 차량번호
	 * @return 렌트카 여부
	 */
	public boolean isRent(String vhrno) {
		int len = vhrno.length();
		if (len >= 7) {
			String fifthFromLast = vhrno.substring(len-5, len-4);
			if ("하허호후".contains(fifthFromLast))
				return true;
		}

		return false;
	}

	/** 차종과 차량번호로 영업용 차량 여부를 확인한다.
	 * @param ffnlgCarmdlCd 차종, vhrno 차량번호
	 * @return 영업용 차량 여부 판단 결과
	 */
	public String getBusinessYnOfCar(String ffnlgCarmdlCd, String vhrno) {
		if (isEmpty(vhrno))
			return "차량번호없음";
		if (isEmpty(ffnlgCarmdlCd) || ffnlgCarmdlCd.equals("31"))
			return "판단불가";

		return vhrno.contains("바") || vhrno.contains("사") || vhrno.contains("아") || vhrno.contains("자") ? "영업용" : "비영업용";
	}

	/** 차량번호로 차량구분을 판단한다.
	 * @param vhrno 차량번호
	 * @return 영업용 차량 여부 판단 결과
	 */
	public String getCarGb(String vhrno) {
		if (isEmpty(vhrno))
			return "차량번호 없음";

		boolean first3isNumber = CmmnUtil.isNumeric(vhrno.substring(0, 3));
		if (first3isNumber) {
			int first3 = Integer.parseInt(vhrno.substring(0, 3));
			if (first3 >= 0 && first3 <= 99) {
				return "중기";
			} else if (first3 >= 100 && first3 <= 997) {
				return "일반";
			} else if (first3 >= 998 && first3 <= 999) {
				return "기타";
			}
		}

		if (!isEmpty(getHeavyEquipmentCarkind(vhrno)))
			return "중기";
		for (String str: new String[] {"외교", "준외", "영사", "준영"}) {
			if (vhrno.contains(str))
				return str;
		}
		for (String str: new String[] {"국기", "협정", "대표", "외빈"}) {
			if (vhrno.contains(str))
				return "국제";
		}

		if (vhrno.substring(0,1).equals("임"))
			return "임시";

		if (vhrno.length() == 7
				&& vhrno.substring(0, 3).equals("16다")
				&& CmmnUtil.isNumeric(vhrno.substring(3, 7)))
			return "미군";

		if (vhrno.length() == 10
				&& this.isBiefSidoName(vhrno.substring(0, 2))
				&& CmmnUtil.isNumeric(vhrno.substring(2, 5))
				&& vhrno.substring(5, 6).equals("-")
				&& CmmnUtil.isNumeric(vhrno.substring(6, 10)))
			return "미군";

		int vhrnoLength = vhrno.length();
		if (this.isBiefSidoName(vhrno.substring(0, 2))) {

			//서울 0    가 0000
			//서울 00   가 0000
			//서울 중    가 0000
			//서울 마포   가 0000
			//서울 영등포  가 0000

			if (vhrnoLength >= 8 && vhrnoLength <= 10) {

				String suffix1 = vhrno.substring(vhrnoLength-5, vhrnoLength-4);
				String suffix2 = vhrno.substring(vhrnoLength-4);

				String middle = vhrno.substring(2, vhrnoLength-5);

				if (CmmnUtil.isKorean(suffix1) && CmmnUtil.isNumeric(suffix2)) {

					if (CmmnUtil.isNumeric(middle) && (middle.length() == 1 || middle.length() == 2)) {
						return "일반";
					}
					if (CmmnUtil.isKorean(middle) && (middle.length() >= 1 && middle.length() <= 3)) {
						return "일반";
					}
				}
			}

		} else {

			//00가0000
			if (vhrnoLength == 7
			&& CmmnUtil.isNumeric(vhrno.substring(0, 2))
			&& CmmnUtil.isKorean(vhrno.substring(2, 3))
			&& CmmnUtil.isNumeric(vhrno.substring(3, 7))) {
				return "일반";
			}
		}

		return "판단불가";
	}



	public String getHeavyEquipmentCarkind(String vhrno) {
		if (this.isBiefSidoName(vhrno.substring(0, 2))
				&& CmmnUtil.isKorean(vhrno.substring(4, 5))
				&& CmmnUtil.isNumeric(vhrno.substring(5, 9))
		) {
			switch(vhrno.substring(2, 4)) {
				case "01" : return "불도저";
				case "02" : return "굴삭기";
				case "03" : return "로더";
				case "04" : return "지게차";
				case "05" : return "스크레이퍼";
				case "06" : return "덤프트럭";
				case "07" : return "기중기";
				case "08" : return "콘크리트믹서트럭";
				case "14" :
					if (!vhrno.substring(4,5).equals("허")) {
						return "콘크리트믹서트럭";
					}
			}

			switch(vhrno.substring(2, 5)) {
				case "26거" : return "도로보수트럭";
				case "26너" : return "노면파쇄기";
				case "26버" : return "터널고소용자동차";
				case "26어" : return "수목이식기";
			}
		}

		return "";
	}

	public boolean isBiefSidoName(String str) {
		String[] sidoNames = {
			"서울","대전","대구","부산","광주","인천","울산","세종",
			"경기","강원","충북","충남","전북","전남","경북","경남","제주"
		};

		return Arrays.asList(sidoNames).contains(str);
	}

	/**단속팀 목록을 조회한다.
	 * @param query 단속팀 목록 조회조건
	 * @return 단속팀 목록
	 */
	public List<DataObject> selectTeamList(CrdnQuery query){
		return crdnTeamMapper.selectTeamList(query);
	}

	/**비사용 단속팀 목록을 조회한다.
	 * @param query 비사용 단속팀 목록 조회조건
	 * @return 비사용 단속팀 목록
	 */
	public List<DataObject> selectRemovedTeamList(CrdnQuery query) {
		return crdnTeamMapper.selectRemovedTeamList(query);
	}

	/**단속팀 정보를 삭제한다.
	 * @param teamId 단속팀 ID
	 * @return 저장 여부
	 * <ul><li>저장됐으면 true</li>
	 *     <li>그렇지 않으면 false</li>
	 * </ul>
	 */
	public boolean removeTeamInfo(String teamId) {
		Team team = new Team();
		team.setTeamId(teamId);
		team.setRemovedBy(currentUser().getId());
		return crdnTeamMapper.deleteTeamInfo(team) == 1;
	}

	/**단속팀 정보를 저장한다.
	 * @param fromInsertCrdn 단속정보 입력 프로세스에서 호출하였는지 여부, teamId 단속팀 ID
	 * @return 저장 여부
	 * <ul><li>저장됐으면 true</li>
	 *     <li>그렇지 않으면 false</li>
	 * </ul>
	 */
	public boolean saveTeamInfo(boolean fromInsertCrdn, Team team) {
		boolean result = false;
		DataObject teamInfo = crdnTeamMapper.selectTeamInfoByName(team);

		if (teamInfo != null) {
			boolean differ =
					!equals(team.getCrdnSeCd(), teamInfo.string("CRDN_SE_CD"))
				 || !equals(team.getTeamer1(), teamInfo.string("TEAMER_1"))
				 || !equals(team.getTeamer2(), teamInfo.string("TEAMER_2"))
				 || !equals(team.getTeamer3(), teamInfo.string("TEAMER_3"))
				 || !equals(team.getTeamer4(), teamInfo.string("TEAMER_4"));

			if (differ) {
				Team del = new Team();
				del.setTeamId(teamInfo.string("TEAM_ID"));
				del.setRemovedBy(currentUser().getId());
				crdnTeamMapper.deleteTeamInfo(del);

				result = crdnTeamMapper.insertTeamInfo(team) == 1;
			} else {
				if (!fromInsertCrdn) {
					team.setTeamId(teamInfo.string("TEAM_ID"));
					result = crdnTeamMapper.updateTeamInfo(team) == 1;
				}
			}
		} else {
			result = crdnTeamMapper.insertTeamInfo(team) == 1;
		}

		return result;
	}

	/**단속팀 정보를 조회한다.
	 * @param teamId 단속팀 ID
	 * @return 단속팀 정보
	 */
	public DataObject selectTeamInfo(String teamId) {
		return crdnTeamMapper.selectTeamInfo(teamId);
	}

	/**면제차량 목록을 조회한다.
	 * @param query 면제차량 목록 조회조건
	 * @return 면제차량 목록
	 */
	public List<DataObject> selectExemptionVehicleList(CrdnQuery query) {
		return exmptnVhclMapper.selectExemptionVehicleList(query);
	}

	/**면제차량 정보를 조회한다.
	 * @param exemptionVehicleId 면제차량 ID
	 * @return 면제차량 정보
	 */
	public DataObject getExemptionVehicleInfo(String exemptionVehicleId) {
		return exmptnVhclMapper.selectExemptionVehicleInfo(exemptionVehicleId);
	}

	/**면제차량 정보를 등록한다.
	 * @param exmptnVhcl 면제차량 정보
	 * @return 저장 여부
	 * <ul><li>저장됐으면 true</li>
	 *     <li>그렇지 않으면 false</li>
	 * </ul>
	 */
	public boolean createExemptionVehicleInfo(ExmptnVhcl exmptnVhcl) {
		return exmptnVhclMapper.insert(exmptnVhcl);
	}

	/**면제차량 정보를 수정한다.
	 * @param exmptnVhcl 면제차량 정보
	 * @return 저장 여부
	 * <ul><li>저장됐으면 true</li>
	 *     <li>그렇지 않으면 false</li>
	 * </ul>
	 */
	public boolean updateExemptionVehicleInfo(ExmptnVhcl exmptnVhcl) {
		return exmptnVhclMapper.update(exmptnVhcl);
	}

	/**면제차량 정보를 삭제한다.
	 * @param exmptnVhcl 면제차량 정보
	 * @return 저장 여부
	 * <ul><li>저장됐으면 true</li>
	 *     <li>그렇지 않으면 false</li>
	 * </ul>
	 */
	public boolean removeExemptionVehicleInfo(ExmptnVhcl exmptnVhcl) {
		return exmptnVhclMapper.delete(exmptnVhcl);
	}

	public List<DataObject> getExemptionVehicleHistoryList(String exmptnVhclId) {
		return exmptnVhclMapper.selectExemptionVehicleHistoryList(exmptnVhclId);
	}
}