
package jp.co.sint.mdk;

import java.text.ParseException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import jp.co.sint.config.SIConfig;
import jp.co.sint.tools.SIDateTime;
import jp.co.sint.tools.SIStringUtil;
import jp.co.sint.tools.SIUtil;

import org.apache.log4j.Category;

import jp.veritrans.tercerog.mdk.ITransaction;
import jp.veritrans.tercerog.mdk.TransactionFactory;
import jp.veritrans.tercerog.mdk.dto.CardAuthorizeRequestDto;
import jp.veritrans.tercerog.mdk.dto.CardAuthorizeResponseDto;
import jp.veritrans.tercerog.mdk.dto.CardCancelRequestDto;
import jp.veritrans.tercerog.mdk.dto.CardCancelResponseDto;
import jp.veritrans.tercerog.mdk.dto.CardReAuthorizeRequestDto;
import jp.veritrans.tercerog.mdk.dto.CardReAuthorizeResponseDto;


public class SIMDKAction3G {
  //ログ用のインスタンスの生成
  private static Category log=Category.getInstance(SIConfig.SILOG4J_WEBSHOP_CATEGORY_NAME);
  
  //注文番号
  private String orderCode="";
  
  //再取引用注文番号
  private String reOrderCode="";
  
  //決済金額
  private String price="0";
  
  //カード番号
  private String cardNo="";
  
  //カード有効期限の年
  private String cardExpiredYear="";
  
  //カード有効期限の月
  private String cardExpiredMonth="";
  
  //サービスタイプ
  private String serviceType="";
  
  //取引タイプ
  private String txnType="";
  
  //カード名義人
  private String custNameOfCard="";
  
  //支払方法
  private String paymentMethod=SIMDKConfig.MDK_PAYMENT_METHOD_ONE;
  
  //支払開始月
  private String paymentStartMonth="";
  
  //分割回数
  private String paymentTimes="";
  
  //与信開始時刻
  private String startDateTime="";
  
  //与信終了時刻
  private String endDateTime="";
  
  
  public SIMDKAction3G(){
  }
  
  /**
   * <b>authAction</b>
   * カード情報の与信処理
   * @param  なし
   * @return 与信処理の結果
   * @throws なし
   */
  public boolean authAction(){
    if (Integer.parseInt(getPrice())<=0) return true;
    else return execAction(SIMDKConfig.MDK_AUTH_TYPE);
  }
  
  /**
   * <b>authAction</b>
   * カード情報の与信売上処理
   * @param  なし
   * @return 与信処理の結果
   * @throws なし
   */
  public boolean authCaptureAction(){
    if (Integer.parseInt(getPrice())<=0) return true;
    else return execAction(SIMDKConfig.MDK_AUTH_CAPTURE_TYPE);
  }
  
  public boolean reAuthAction(){
    if (Integer.parseInt(getPrice())<=0) return true;
    else return execAction(SIMDKConfig.MDK_REAUTH_CAPTURE_TYPE);
  }
  
  public boolean cancelAction(){
    return execAction(SIMDKConfig.MDK_CANCEL_TYPE);
  }
  
  /**
   * <b>execAction</b>
   * 決済処理の共通メソッド
   * @param  lActionType 決済タイプ
   * @return 処理の結果
   * @throws なし
   */
  public boolean execAction(String lActionType){
    if (SIMDKConfig.MDK_AUTH_TYPE.equals(lActionType)){
      return execAuth(false);
    } else if (SIMDKConfig.MDK_AUTH_CAPTURE_TYPE.equals(lActionType)){
      return execAuth(true);
    } else if (SIMDKConfig.MDK_REAUTH_CAPTURE_TYPE.equals(lActionType)){
      return execReAuth();
    } else if (SIMDKConfig.MDK_CANCEL_TYPE.equals(lActionType)){
      return execCancel();
    }
    return false;
  }
  
  public boolean execAuth(boolean withCapture){
    boolean lRes=false;
    SIDateTime lDateTime=new SIDateTime();
    setStartDateTime(lDateTime.getFullDateTime());
    
    CardAuthorizeRequestDto reqDto = new CardAuthorizeRequestDto();
    reqDto.setOrderId(getOrderCode());
    reqDto.setWithCapture(String.valueOf(withCapture));
    reqDto.setAmount(getPrice());
    reqDto.setCardNumber(getCardNo());
    reqDto.setCardExpire(getCardExpired());
    reqDto.setJpo("10");
    
    ITransaction tran = null;
    CardAuthorizeResponseDto resDto = null;
    
    try {
        tran = TransactionFactory.getInstance(reqDto);
        resDto = (CardAuthorizeResponseDto) tran.execute();
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }
    
    // リクエストとレスポンスを実行コンソール上で表示する
    log.debug("与信開始..."+getStartDateTime());
    if (withCapture) log.debug("lActionType = AuthCapture");
    else  log.debug("lActionType = Auth");
    log.debug("OrderCode = "+getOrderCode());
    if (getCardNo().length()>6)log.debug("CardNo ="+getCardNo().substring(0,5));
    else log.debug("CardNo = "+getCardNo());
    log.debug("CustNameOfCard = "+getCustNameOfCard());
    log.debug("CardExpired = "+getCardExpired());
    
    if (SIUtil.isNotNull(resDto.getMstatus())&&resDto.getMstatus().equalsIgnoreCase(SIMDKConfig.MDK_STATUS_SUCCESS)){//成功
      lRes=true;
    }else{
      log.error("MStatus="+resDto.getMstatus()+",MErrMsg="+resDto.getMerrMsg());
      log.error("VResultCode="+resDto.getVResultCode()+",OrderID="+resDto.getOrderId());
      lRes=false;
    }
    lDateTime=new SIDateTime();
    setEndDateTime(lDateTime.getFullDateTime());
    log.debug("与信終了..."+getEndDateTime());
    return lRes;
  }
  
  public boolean execReAuth(){
    boolean lRes=false;
    SIDateTime lDateTime=new SIDateTime();
    setStartDateTime(lDateTime.getFullDateTime());
    
    CardReAuthorizeRequestDto reqDto = new CardReAuthorizeRequestDto();
    reqDto.setOrderId(getOrderCode());
    reqDto.setOriginalOrderId(getReOrderCode());
    reqDto.setAmount(getPrice());
    
    ITransaction tran = null;
    CardReAuthorizeResponseDto resDto = null;
    
    try {
        tran = TransactionFactory.getInstance(reqDto);
        resDto = (CardReAuthorizeResponseDto) tran.execute();
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }
    
    // リクエストとレスポンスを実行コンソール上で表示する
    log.debug("与信開始..."+getStartDateTime());
    log.debug("lActionType = ReAuthCapture");
    log.debug("OrderCode = "+getOrderCode());
    if (getCardNo().length()>6)log.debug("CardNo ="+getCardNo().substring(0,5));
    else log.debug("CardNo = "+getCardNo());
    log.debug("CustNameOfCard = "+getCustNameOfCard());
    log.debug("CardExpired = "+getCardExpired());
    
    
    if (SIUtil.isNotNull(resDto.getMstatus())&&resDto.getMstatus().equalsIgnoreCase(SIMDKConfig.MDK_STATUS_SUCCESS)){//成功
      lRes=true;
    }else{
      log.error("MStatus="+resDto.getMstatus()+",MErrMsg="+resDto.getMerrMsg());
      log.error("VResultCode="+resDto.getVResultCode()+",OrderID="+resDto.getOrderId());
      lRes=false;
    }
    lDateTime=new SIDateTime();
    setEndDateTime(lDateTime.getFullDateTime());
    log.debug("与信終了..."+getEndDateTime());
    return lRes;
  }
  
  public boolean execCancel(){
    boolean lRes=false;
    SIDateTime lDateTime=new SIDateTime();
    setStartDateTime(lDateTime.getFullDateTime());
    
    CardCancelRequestDto reqDto = new CardCancelRequestDto();
    reqDto.setOrderId(getOrderCode());
    
    ITransaction tran = null;
    CardCancelResponseDto resDto = null;
    
    try {
        tran = TransactionFactory.getInstance(reqDto);
        resDto = (CardCancelResponseDto) tran.execute();
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }
    
    // リクエストとレスポンスを実行コンソール上で表示する
    log.debug("与信開始..."+getStartDateTime());
    log.debug("lActionType = Cancel");
    log.debug("OrderCode = "+getOrderCode());
    if (getCardNo().length()>6)log.debug("CardNo ="+getCardNo().substring(0,5));
    else log.debug("CardNo = "+getCardNo());
    log.debug("CustNameOfCard = "+getCustNameOfCard());
    log.debug("CardExpired = "+getCardExpired());
    
    
    if (SIUtil.isNotNull(resDto.getMstatus())&&resDto.getMstatus().equalsIgnoreCase(SIMDKConfig.MDK_STATUS_SUCCESS)){//成功
      lRes=true;
    }else{
      log.error("MStatus="+resDto.getMstatus()+",MErrMsg="+resDto.getMerrMsg());
      log.error("VResultCode="+resDto.getVResultCode()+",OrderID="+resDto.getOrderId());
      lRes=false;
    }
    lDateTime=new SIDateTime();
    setEndDateTime(lDateTime.getFullDateTime());
    log.debug("与信終了..."+getEndDateTime());
    return lRes;
  }
  
  public String getCardExpired() {
    if (SIUtil.isNull(getCardExpiredMonth())&&SIUtil.isNull(getCardExpiredYear()))return "";
    else return getCardExpiredMonth()+"/"+getCardExpiredYear();
  }
  
  public String getCardExpiredMonth() {
    return cardExpiredMonth;
  }
  
  public String getCardExpiredYear() {
    return cardExpiredYear;
  }
  
  public String getCardNo() {
    return this.cardNo;
  }
  
  public String getCustNameOfCard() {
    return custNameOfCard;
  }
  
  public String getOrderCode() {
    return this.orderCode;
  }
  
  public String getReOrderCode() {
    return this.reOrderCode;
  }
  
  public String getPrice() {
    return price;
  }
  
  public String getServiceType() {
    return serviceType;
  }
  
  public String getTxnType() {
    return txnType;
  }
  
  public String getPaymentMethod(){
    return this.paymentMethod;
  }
  
  public String getPaymentStartMonth(){
    return this.paymentStartMonth;
  }
  
  public String getPaymentTimes(){
    return this.paymentTimes;
  }
  
  public String getPaymentType(){
    if (getPaymentMethod().equals(SIMDKConfig.MDK_PAYMENT_METHOD_ONE)) {
      return "";
    }else if (getPaymentMethod().equals(SIMDKConfig.MDK_PAYMENT_METHOD_MULIT)){
      if (SIUtil.isNull(getPaymentStartMonth())) return "61C"+getPaymentTimes();
      else return "61A"+getPaymentStartMonth()+"C"+getPaymentTimes();
    }else if (getPaymentMethod().equals(SIMDKConfig.MDK_PAYMENT_METHOD_BONUS)){
      return "21";
    }else if (getPaymentMethod().equals(SIMDKConfig.MDK_PAYMENT_METHOD_MULIT_BONUS)){
      if (SIUtil.isNull(getPaymentStartMonth())) return "31C"+getPaymentTimes();
      else return "31A"+getPaymentStartMonth()+"C"+getPaymentTimes();
    }else return "";
  }
  
  public void setStartDateTime(String lStartDateTime){
    if (SIUtil.isNull(lStartDateTime)) lStartDateTime="";
    this.startDateTime=lStartDateTime;
  }
  
  public void setEndDateTime(String lEndDateTime){
    if (SIUtil.isNull(lEndDateTime)) lEndDateTime="";
    this.endDateTime=lEndDateTime;
  }
  
  public void setCardExpired(String lCardExpired) {
    if (SIUtil.isNull(lCardExpired)) lCardExpired="";
    String[] lExp=SIStringUtil.split(lCardExpired,"/");
    if (lExp.length==1){
      setCardExpiredMonth(lExp[0]);
    }else if (lExp.length==2){
      setCardExpiredMonth(lExp[0]);
      setCardExpiredYear(lExp[1]);
    }
  }
  
  public void setCardExpiredMonth(String lCardExpiredMonth) {
    if (SIUtil.isNull(lCardExpiredMonth)) lCardExpiredMonth="";
    else lCardExpiredMonth=SIUtil.lFillIn(lCardExpiredMonth,2);
    cardExpiredMonth = lCardExpiredMonth;
  }
  
  public void setCardExpiredYear(String lCardExpiredYear) {
    if (SIUtil.isNull(lCardExpiredYear)) {
      lCardExpiredYear="";
    }else if (lCardExpiredYear.length()==4){
      lCardExpiredYear=lCardExpiredYear.substring(2);
    }else {
      lCardExpiredYear=SIUtil.lFillIn(lCardExpiredYear,2);
    }
    cardExpiredYear = lCardExpiredYear;
  }
  
  public void setCardNo(String lCardNo) {
    if (SIUtil.isNull(lCardNo)) lCardNo="";
    if (lCardNo.length()>6)log.debug("card no="+lCardNo.substring(0,5));
    else log.debug("card no="+lCardNo);
    this.cardNo = lCardNo;
  }
  
  public void setCustNameOfCard(String lCustNameOfCard) {
    if (SIUtil.isNull(lCustNameOfCard)) lCustNameOfCard="";
    custNameOfCard = lCustNameOfCard;
  }
  
  public void setOrderCode(String lOrderCode) {
    if (SIUtil.isNull(lOrderCode)) lOrderCode="";
    this.orderCode = lOrderCode;
  }
  
  public void setReOrderCode(String lReOrderCode) {
    if (SIUtil.isNull(lReOrderCode)) lReOrderCode="";
    this.reOrderCode = lReOrderCode;
  }
  
  public void setPrice(String lPrice) {
    if (SIUtil.isNull(lPrice)) lPrice="0";
    price = lPrice;
  }
  
  public void setServiceType(String lServiceType) {
    if (SIUtil.isNull(lServiceType)) lServiceType="";
    serviceType = lServiceType;
  }
  
  public void setTxnType(String lTxnType) {
    if (SIUtil.isNull(lTxnType)) lTxnType="";
    txnType = lTxnType;
  }
  
  public void setPaymentMethod(String lPaymentMethod){
    if (SIUtil.isNull(lPaymentMethod)) lPaymentMethod=SIMDKConfig.MDK_PAYMENT_METHOD_ONE;
    this.paymentMethod = lPaymentMethod;
  }
  
  public void setPaymentStartMonth(String lPaymentStartMonth){
    if (SIUtil.isNull(lPaymentStartMonth)) lPaymentStartMonth="";
    else lPaymentStartMonth=SIUtil.lFillIn(lPaymentStartMonth,2);
    this.paymentStartMonth = lPaymentStartMonth;
  }
  
  public void setPaymentTimes(String lPaymentTimes){
    if (SIUtil.isNull(lPaymentTimes)) lPaymentTimes="";
    else lPaymentTimes=SIUtil.lFillIn(lPaymentTimes,2);
    this.paymentTimes = lPaymentTimes;
  }
  
  public String getStartDateTime(){
    return this.startDateTime;
  }
  
  public String getEndDateTime(){
    return this.endDateTime;
  }
  
  public String getActionTime(){
    if (SIUtil.isNull(getStartDateTime()) || SIUtil.isNull(getEndDateTime())) return "-1";
    SIDateTime lStartDateTime=new SIDateTime();
    SIDateTime lEndDateTime=new SIDateTime();
    try {
      lStartDateTime=new SIDateTime(getStartDateTime(),SIConfig.SIDATE_TIME_FORMAT);
      lEndDateTime=new SIDateTime(getEndDateTime(),SIConfig.SIDATE_TIME_FORMAT);
      long lDiff=lEndDateTime.getDateTime()-lStartDateTime.getDateTime();
      log.debug("getActionTime:lStartDateTime="+getStartDateTime()+",lEndDateTime="+getEndDateTime()+",lDiff="+lDiff);
      return String.valueOf(lDiff);
    } catch (ParseException e) {
      e.printStackTrace();
      return "-1";
    }
  }
  
  public static void cancelByFailuer(HttpServletRequest request){
    HttpSession session=request.getSession(true);//セッションの取得
    SIMDKAction3G lMDKAction=(SIMDKAction3G)session.getAttribute(SIConfig.SISESSION_MDK_AUTH_NAME);
    if (lMDKAction!=null){
      log.debug("受注失敗しました。既に決済情報もキャンセルします。");
      if (!lMDKAction.cancelAction())log.error("エラーによって、決済カードのキャンセル失敗しました。");
      session.removeAttribute(SIConfig.SISESSION_MDK_AUTH_NAME);
    }
  }
}