/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JCKGetOpenZengoCtrlCC
*   ソースファイル名：JCKGetOpenZengoCtrlCC.java
*   作成者          ：富士通
*   日付            ：2023年01月06日
*＜機能概要＞
*  指定された条件から開通前後判定を取得します。
*  （JCKSV901601CCよりスーパークラスの抽出）
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v64.00.00   2023/01/06   FJ)張本     【ANK-4316-00-00】ｅｏアプリ対応
**********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import static com.fujitsu.futurity.bp.custom.common.JCKPmpCommonUtil.callEKU0011B010;
import static com.fujitsu.futurity.bp.custom.common.JCKPmpCommonUtil.printDebugLog;
import static com.fujitsu.futurity.bp.custom.common.JCKPmpCommonUtil.scCallRun;
import static com.fujitsu.futurity.bp.custom.common.JCKPmpScParamHenshu.getResultMsgList;
import static com.fujitsu.futurity.bp.custom.common.JCKPmpScParamHenshu.isSuccess;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.fujitsu.futurity.bp.custom.constant.JKKSvcConst;
import com.fujitsu.futurity.bp.x21.bpm.db.SessionHandle;
import com.fujitsu.futurity.bp.x21.bpm.exception.RequestParameterException;
import com.fujitsu.futurity.bp.x21.bpm.parameter.IRequestParameterReadWrite;
import com.fujitsu.futurity.bp.x21.cc.AbstractCommonComponent;
import com.fujitsu.futurity.bp.x21.sc.exception.SCException;
import com.fujitsu.futurity.model.base.CAANMsg;

import eo.common.constant.JKKStrConst;
import eo.common.constant.JPCModelConstant;
import eo.ejb.cbs.cbsmsg.EKK0081B557CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0081B557CBSMsg1List;
import eo.ejb.cbs.cbsmsg.EKU0011B010CBSMsg;
import eo.ejb.cbs.cbsmsg.EKU0011B010CBSMsg1List;

/**
 * 指定された条件から開通前後判定を取得します。
 * <BR>
 * @ author 富士通
 */
public class JCKGetOpenZengoFlgCC extends AbstractCommonComponent
{

	/**
	 * 開通済フラグ 初期値（空文字列）
	 */
	private static final String OPEN_ZENGO_FLG_EMPTY = "";
	/**
	 * 開通済フラグが0
	 */
	private static final String OPEN_ZENGO_FLG_0 = "0";
	/**
	 * 開通済フラグが1
	 */
	private static final String OPEN_ZENGO_FLG_1 = "1";

	/** 作業用マップのキー：サービス契約一覧照会(SYSID) */
	public static final String WORK_KEY_EKK0081B557CBSMSGLIST = "EKK0081B557CBSMsg1List";

	public JCKGetOpenZengoFlgCC()
	{
		super();
	}

	/**
	 * 開通前後判定フラグ取得 <br>
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param sysid SYSID
	 * @return open_zengo_flg
	 * @throws Throwable
	 */
	public String getOpenZengoFlg(SessionHandle handle, IRequestParameterReadWrite param, String sysid) throws Throwable
	{
		// 初期値（空文字列）
		String openZengoFlg = OPEN_ZENGO_FLG_EMPTY;

		// サービスIF結果取得(EKK0081B557)
		CAANMsg[] workEKK0081B557 = null;

		workEKK0081B557 = getEKK0081B557CAANMsg(handle, param, sysid);

		if (workEKK0081B557 == null || workEKK0081B557.length == 0)
		{
			// 該当サービス契約が存在しない場合は「判定対象外」とし、空文字列を返却
			return openZengoFlg;
		}

		boolean status = false;

		for (CAANMsg caanMsg : workEKK0081B557)
		{
			// ステータスチェック
			List<String> svcKeiStatList = Arrays.asList("010", "020", "030", "100", "210");
			String svcKeiStat = caanMsg.getString(EKK0081B557CBSMsg1List.SVC_KEI_STAT);

			if (svcKeiStatList.contains(svcKeiStat))
			{
				// 照査NGチェック
				String shozaDslfinCd = caanMsg.getString(EKK0081B557CBSMsg1List.SHOSA_DSL_FIN_CD);
				if (!"2".equals(shozaDslfinCd))
				{

					String svcCd = caanMsg.getString(EKK0081B557CBSMsg1List.SVC_CD);
					String prcGrpCd = caanMsg.getString(EKK0081B557CBSMsg1List.PRC_GRP_CD);
					String pcrsCd = caanMsg.getString(EKK0081B557CBSMsg1List.PCRS_CD);
					// 対象サービス判定
					if (judgeTgSvc(svcCd, prcGrpCd, pcrsCd))
					{
						// 対象サービスが１件以上存在する場合、「0」:開通前を一旦設定する
						openZengoFlg = OPEN_ZENGO_FLG_0;


						// 開通後判定
						status = judgeOpenZengo(handle, param, caanMsg);
					}
				}
			}

			if (status)
			{
				// １つでも開通後が存在する場合は開通後を返却
				openZengoFlg = OPEN_ZENGO_FLG_1;
				break;
			}
		}


		return openZengoFlg;
	}

	/**
	 * 対象サービス判定 <br>
	 * @param svcCd サービスコード
	 * @param prcGrpCd 料金グループコード
	 * @param pcrsCd 料金コースコード
	 * @return
	 */
	private boolean judgeTgSvc(String svcCd, String prcGrpCd, String pcrsCd)
	{
		return // eo光ネット/eoメールアドレス サービスコードと料金グループコードで判定
		(JKKStrConst.CD00130_01.equals(svcCd) && Arrays.asList(JKKStrConst.CD00133_02, JKKStrConst.CD00133_03, JKKStrConst.CD00133_04,
				JKKStrConst.CD00133_16).contains(prcGrpCd))
				||
				//  eo光TV（再送信除く/再送信多ch含む/KCN除く） 
				//   サービスコード＝テレビサービス(03) かつ 料金コースコード≠再送信(A23)かつ 料金グループコード≠KCN(12)
				(JKKStrConst.CD00130_03.equals(svcCd) && !JKKStrConst.CD00134_A23.equals(pcrsCd) && !JKKStrConst.CD00133_12.equals(prcGrpCd)) ||
				// eo光電話/eo電気/mineo
				Arrays.asList(JKKStrConst.CD00130_02, JKKStrConst.CD00130_05, JKKStrConst.CD00130_51).contains(svcCd);
	}

	/**
	 * 開通後判定 <br>
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param caanMsg サービス契約一覧照会（SYSID）2明細の該当レコード
	 * @return boolean 運用日付よりも小さい
	 * @throws Throwable
	 */
	private boolean judgeOpenZengo(SessionHandle handle, IRequestParameterReadWrite param, CAANMsg caanMsg) throws Throwable
	{
		String opeDate = JCCBPCommon.getOpeDate(null);
		String svcCd = caanMsg.getString(EKK0081B557CBSMsg1List.SVC_CD);
		String svcStaYmd = caanMsg.getString(EKK0081B557CBSMsg1List.SVC_STA_YMD);

		// サービスコード判定
		List<String> svcCdList_05_51 = Arrays.asList(JKKStrConst.CD00130_05, JKKStrConst.CD00130_51);
		List<String> svcCdList_02_03 = Arrays.asList(JKKSvcConst.SVC_CD_TEL, JKKSvcConst.SVC_CD_TV);
		List<String> prcGrpCdList_02_03_04 = Arrays.asList(JKKStrConst.CD00133_02, JKKStrConst.CD00133_03, JKKStrConst.CD00133_04);
		List<String> tkHoshikiCdList_003_004_005_006_007 =
				Arrays.asList(JKKStrConst.CD00590_VDSL1, JKKStrConst.CD00590_VDSL2, JKKStrConst.CD00590_VDSL3, JKKStrConst.CD00590_VDSL4,
						JKKStrConst.CD00590_VDSL5);

		if (svcCdList_05_51.contains(svcCd))
		{
			// 開通後判定（サービス開始日）
			if (svcStaYmd != null && !svcStaYmd.isEmpty() && svcStaYmd.compareTo(opeDate) < 0)
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		else if (svcCdList_02_03.contains(svcCd))
		{
			// 工事案件情報取得処理
			CAANMsg workEKU0011B010 = getKojiakInfo(handle, param, caanMsg.getString(EKK0081B557CBSMsg1List.SVC_KEI_NO));

			// 開通後判定（サービス開始日/工事予定日）
			String takniKojiFinRsvYmd = null;
			if (workEKU0011B010 != null)
			{
				takniKojiFinRsvYmd = workEKU0011B010.getString(EKU0011B010CBSMsg1List.TAKNI_KOJI_FIN_RSV_YMD);
			}

			return judgeOpenZengoDate(svcStaYmd, takniKojiFinRsvYmd);
		}
		else if (JKKSvcConst.SVC_CD_NET.equals(svcCd))
		{
			// 料金グループコード判定
			String prcGrpCd = caanMsg.getString(EKK0081B557CBSMsg1List.PRC_GRP_CD);
			String tkHoshikiCd = caanMsg.getString(EKK0081B557CBSMsg1List.TK_HOSHIKI_CD);
			String tkHoshikiPatternCd = caanMsg.getString(EKK0081B557CBSMsg1List.TK_HOSHIKI_PATTERN_CD);
			if (JKKStrConst.CD00133_16.equals(prcGrpCd))
			{
				// 開通後判定（サービス開始日）
				if (svcStaYmd != null && !svcStaYmd.isEmpty() && svcStaYmd.compareTo(opeDate) < 0)
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			else if (prcGrpCdList_02_03_04.contains(prcGrpCd))
			{
				// マンションタイプ判定 - FALSEの場合
				if (JKKStrConst.CD00133_02.equals(prcGrpCd) || JKKStrConst.CD00133_03.equals(prcGrpCd) || tkHoshikiCd == null
						|| tkHoshikiCd.isEmpty() || tkHoshikiCdList_003_004_005_006_007.contains(tkHoshikiCd)
						|| (JKKStrConst.CD00590_OPTICAL.equals(tkHoshikiCd) && !JKKStrConst.TK_HOSHIKI_PATTERN_CD_51.equals(tkHoshikiPatternCd)))
				{
					// 工事案件情報取得処理
					CAANMsg workEKU0011B010 = getKojiakInfo(handle, param, caanMsg.getString(EKK0081B557CBSMsg1List.SVC_KEI_NO));

					// 開通後判定（サービス開始日/工事予定日）
					String takniKojiFinRsvYmd = null;
					if (workEKU0011B010 != null)
					{
						takniKojiFinRsvYmd = workEKU0011B010.getString(EKU0011B010CBSMsg1List.TAKNI_KOJI_FIN_RSV_YMD);
					}

					return judgeOpenZengoDate(svcStaYmd, takniKojiFinRsvYmd);
				}
				// マンションタイプ判定 - TRUEの場合
				else
				{
					// 開通後判定（サービス開始日/サービス開始希望日）
					String svcUseStaKiboYmd = caanMsg.getString(EKK0081B557CBSMsg1List.SVC_USE_STA_KIBO_YMD);
					return judgeOpenZengoDate(svcStaYmd, svcUseStaKiboYmd);
				}
			}
			else
			{
				return false; // FALSE返却
			}
		}
		else
		{
			return false; // FALSE返却
		}
	}

	/**
	 * 工事案件情報 <br>
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param svcKeiNo サービス契約番号
	 * @return CAANMsg 工事案件一覧照会明細
	 * @throws Throwable
	 */
	private CAANMsg getKojiakInfo(SessionHandle handle, IRequestParameterReadWrite param, String svcKeiNo) throws Throwable
	{
		// 工事案件一覧照会サービスIF実行
		CAANMsg[] workEKU0011B010 = getEKU0011B010CAANMsg(handle, param, svcKeiNo);

		if (workEKU0011B010 == null || workEKU0011B010.length == 0)
		{
			return null;
		}

		List<String> kojiakSbtCd_01_003 = Arrays.asList("001", "003");

		for (CAANMsg caanMsg : workEKU0011B010)
		{
			String kojiakSbtCd = caanMsg.getString(EKU0011B010CBSMsg1List.KOJIAK_SBT_CD);
			String kojiakStat = caanMsg.getString(EKU0011B010CBSMsg1List.KOJIAK_STAT);
			String mansKojiakStatCd = caanMsg.getString(EKU0011B010CBSMsg1List.MANS_KOJIAK_STAT_CD);

			if (kojiakSbtCd_01_003.contains(kojiakSbtCd))
			{
				// ステータスチェック
				if ("900".equals(kojiakStat))
				{
					continue;
				}

				if ("900".equals(mansKojiakStatCd))
				{
					continue;
				}

				return caanMsg;
			}
		}

		return null;
	}

	/**
	 * <br>
	 * @param handle セッションハンドル
	 * @param scCall サービスコンポーネントリクエスト
	 * @param param リクエストパラメータ
	 * @param sysid SYSID
	 * @return CAANMsg[]
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	private CAANMsg[] getEKK0081B557CAANMsg(SessionHandle handle, IRequestParameterReadWrite param, String sysid) throws Exception
	{
		// 機能コード：１
		Map result = callEKK0081B557(handle, param, JPCModelConstant.FUNC_CD_1, sysid);
		CAANMsg[] workEKK0081B557 = null;
		if (isSuccess(result))
		{
			workEKK0081B557 = getResultMsgList(result, EKK0081B557CBSMsg.EKK0081B557CBSMSG1LIST);
		}

		setMappingWorkAreaEKK0081B557(param, workEKK0081B557);

		return workEKK0081B557;
	}

	/**
	 * <br>
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param svcKeiNo サービス契約番号
	 * @return CAANMsg[]
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	private CAANMsg[] getEKU0011B010CAANMsg(SessionHandle handle, IRequestParameterReadWrite param, String svcKeiNo) throws Exception
	{
		Map result = callEKU0011B010(handle, param, JPCModelConstant.FUNC_CD_1, svcKeiNo);
		CAANMsg[] workEKU0011B010Msg = null;
		if (isSuccess(result))
		{
			workEKU0011B010Msg = getResultMsgList(result, EKU0011B010CBSMsg.EKU0011B010CBSMSG1LIST);
		}

		return workEKU0011B010Msg;
	}

	/**
	 * 開通後判定
	 * @param dateYmd1 日付1
	 * @param dateYmd2 日付2
	 * @return boolean 運用日付よりも小さい
	 */
	private boolean judgeOpenZengoDate(String dateYmd1, String dateYmd2)
	{
		String opeDate = JCCBPCommon.getOpeDate(null);

		// 上記2つの項目が両方とも未設定の場合、FALSEを返却する。
		if ((dateYmd1 == null || dateYmd1.isEmpty()) && (dateYmd2 == null || dateYmd2.isEmpty()))
		{
			return false;
		}
		// 片方が設定あり、片方が設定なしの場合
		else if ((dateYmd1 != null && !dateYmd1.isEmpty()) && (dateYmd2 == null || dateYmd2.isEmpty()))
		{
			if (dateYmd1.compareTo(opeDate) < 0)
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		else if ((dateYmd1 == null || dateYmd1.isEmpty()) && (dateYmd2 != null && !dateYmd2.isEmpty()))
		{
			if (dateYmd2.compareTo(opeDate) < 0)
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		// 両方とも設定ありの場合
		else if ((dateYmd1 != null && !dateYmd1.isEmpty()) && (dateYmd2 != null && !dateYmd2.isEmpty()))
		{
			if (dateYmd1.compareTo(dateYmd2) < 0)
			{
				if (dateYmd1.compareTo(opeDate) < 0)
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			else
			{
				if (dateYmd2.compareTo(opeDate) < 0)
				{
					return true;
				}
				else
				{
					return false;
				}
			}
		}
		else
		{
			return false;
		}
	}

	/**
	 * @param param
	 * @param workEKK0081B557
	 * @throws RequestParameterException
	 */
	@SuppressWarnings("unchecked")
	private void setMappingWorkAreaEKK0081B557(IRequestParameterReadWrite param, CAANMsg[] workEKK0081B557) throws RequestParameterException
	{
		// 作業領域のマップを取得
		Map workMap = param.getMappingWorkArea();
		if (workMap == null)
		{
			workMap = new HashMap();
			param.setMappingWorkArea(workMap);
		}

		// 作業用マップに設定
		workMap.put(WORK_KEY_EKK0081B557CBSMSGLIST, workEKK0081B557);
	}

	/**
	 * サービス契約一覧照会(SYSID)5呼出。<br />
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param funcCd 機能コード
	 * @param sysid SYSID
	 * @return ＳＣ実行結果
	 * @throws RequestParameterException 
	 * @throws SCException 
	 */
	private static Map<?, ?> callEKK0081B557(SessionHandle handle, IRequestParameterReadWrite param, String funcCd, String sysid)
			throws RequestParameterException, SCException
	{
		//*****************************************************************
		// サービス契約一覧照会(SYSID)5への上りマッピング
		//*****************************************************************
		Map<Object, Object> inMap = new HashMap<Object, Object>();
		inMap.put(EKK0081B557CBSMsg.FUNC_CODE, funcCd);
		inMap.put(EKK0081B557CBSMsg.KEY_SYSID, sysid);
		HashMap<String, Object> paramMap = JCKBPCommon.createScParamForSearch(param, EKK0081B557CBSMsg.class , inMap, funcCd);

		//***************************************************
		// ＳＣ呼出実行
		//***************************************************
		printDebugLog("サービス契約一覧照会(SYSID)5呼び出し開始");
		Map<?, ?> result = scCallRun(param, handle, paramMap);
		printDebugLog("サービス契約一覧照会(SYSID)5呼び出し完了" + result);

		return result;
	}
}