package com.bcxin.ins.service.order.impl;

import com.bcxin.ins.dao.order.InsTransactionAPIDao;
import com.bcxin.ins.entity.policy_core.InsAgreement;
import com.bcxin.ins.entity.policy_core.InsInsuranceSlip;
import com.bcxin.ins.entity.policy_core.InsTransaction;
import com.bcxin.ins.entity.product_core.ProPrimary;
import com.bcxin.ins.service.order.*;
import com.bcxin.ins.service.preservation.InsPreservationResultSetAPIService;
import com.bcxin.ins.service.product.InsProductAPIService;
import com.bcxin.ins.util.DateUtil;
import com.bcxin.ins.util.IdWorker;
import com.bcxin.ins.util.MyConverUtil;
import com.bcxin.ins.util.toolbox.StrUtil;
import com.bcxin.ins.vo.*;
import com.bcxin.mybatisplus.service.impl.ServiceImpl;
import com.xiaoleilu.hutool.thread.ThreadUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * <b>交易业务处理 </b>
 * 
 * @author zxf
 * @date 2017年1月5日 上午10:28:33
 * @注意事项 </b>
 * <b>
 */
@Service
@Transactional
public class InsTransactionAPIServiceImpl extends ServiceImpl<InsTransactionAPIDao, InsTransaction> implements InsTransactionAPIService {

	@Autowired
	private InsTransactionAPIDao dao;
	@Autowired
	private InsInsuranceSlipAPIService insInsuranceSlipAPIService;

	@Autowired
	private InsAgreementAPIService insAgreementService;
	@Autowired
	private InsRoleInpolicyAPIService insRolieInpolicyAPIService;
	@Autowired
	private InsProductAPIService insProductAPIService;

	@Autowired
	private PolicyService policyService;
	@Autowired
	private InsPreservationResultSetAPIService insPreservationResultSetAPIService;


	/**
	 * <b>订单id查询所有交易详细信息 </b> 
	 * 
	 * @param oid
	 * @return
	 * @author ZXF 
	 * @date 2017年1月6日 上午10:07:40
	 * @注意事项 </b>
	 * <b>
	 */
	@Override
	public List<InsTransaction> selectInsTransactionByInsOrderForm(Long oid){
		return dao.selectInsTransactionByInsOrderForm(oid);
	}

	@Override
	public InsTransaction initInsTransaction(){
		InsTransaction insTransaction = new InsTransaction();
		insTransaction.setStart_time(new Date());
		dao.insert(insTransaction);
		return insTransaction;
	}
	
	/**
	 * <b>根据List<InsTransaction>封装到 List<TransactionVo>中</b> 
	 * 
	 * @param itList
	 * @return
	 * @author ZXF 
	 * @date 2017年1月8日 下午3:18:47
	 * @注意事项 </b>
	 * <b>
	 */
	@Override
	public List<TransactionVo> packagingTransactionVoListByInsTransactionList(List<InsTransaction> itList){
		List<TransactionVo> voList = new ArrayList<TransactionVo>();
		for(InsTransaction it : itList){
			voList.add(accordingToInsTransactionIntoTransactionVo(it));
		}
		return voList;
	}
	
	/**
	 * <b>根据Vo及订单交易记录表ID更新InsTransaction数据 </b> 
	 * 
	 * @param vo
	 * @param insTransaction_id 承保信息表id
	 * @author ZXF 
	 * @date 2017年1月7日 下午4:26:25
	 * @注意事项 </b>
	 * <b>
	 */
	@Override
	public void accordingToTheTransactionVoSetUpInsTransaction(TransactionVo vo,Long insTransaction_id){
		InsTransaction insTransaction = null;
		if(StrUtil.isNotBlank(vo.getOid())){
			insTransaction = dao.selectById(Long.parseLong(vo.getOid()));
		}else{
			insTransaction = initInsTransaction();
		}
		try {
			MyConverUtil.map2PO(MyConverUtil.PO2Map(vo), insTransaction);
		} catch (Exception e) {
			e.printStackTrace();
		}
		dao.updateById(insTransaction);
	}
	
	/**
	 * <b>根据承保信息表 封装到TransactionVo </b> 
	 * @param insTransaction 承保信息表 
	 * @return
	 * @author ZXF 
	 * @date 2017年1月9日 下午9:59:47
	 * @注意事项 </b>
	 * <b>
	 */
	@Override
	public TransactionVo accordingToInsTransactionIntoTransactionVo(InsTransaction insTransaction) {
		TransactionVo vo = new TransactionVo();
		if(insTransaction == null){
			return vo;
		}
		vo.setOid(String.valueOf(insTransaction.getIns_transaction_id()));
		try {
			MyConverUtil.map2PO(MyConverUtil.PO2Map(insTransaction), vo);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return vo;
	}
	
	/**
	 * <b>通过订单id获取已创建的交易信息集取第一条数据的支付地址设置到 OrderFormVo 中</b> 
	 * 
	 * @param vo
	 * @param order_id
	 * @author ZXF 
	 * @date 2017年1月14日 上午10:29:24
	 * @注意事项 </b>
	 * <b>
	 */
	@Override
	public void setOrderFormVoOfShowUrlByOrderID(OrderFormVo vo, Long order_id){
		List<InsTransaction> insTransactionList = selectInsTransactionByInsOrderForm(order_id);
		if(insTransactionList.size()>ConstProp.INT_NUMBER_ZERO){
			InsTransaction insTransaction = insTransactionList.get(ConstProp.INT_NUMBER_ZERO);
			vo.setPay_methods(insTransaction.getPay_type());
			vo.setPay_order_number(insTransaction.getPay_order_number());
			if(StrUtil.isNotBlank(insTransaction.getDeal_url())){
				vo.setShow_url(insTransaction.getDeal_url());
			}
		}
		String p_p = "";
		for(InsTransaction it : insTransactionList){
			if(StringUtils.isNotEmpty(it.getPay_order_url())){
				p_p = p_p + ","+it.getPay_order_url();
			}
		}
		vo.setPay_order_url(p_p);
	}
	
	/**
	 * <b>页面获取上传支付信息等插入到分销,每次上传都创建一条新的记录</b> 
	 * 
	 * @param path_url 支付凭证上传路径
	 * @param order 订单
	 * @param path_sign 支付阶段标识
	 * @author ZXF 
	 * @date 2016年12月28日 上午11:03:32
	 * @注意事项 </b>
	 * <b>
	 */
	@Override
	public void uploadPayMentFileToTranction(String path_url, InsInsuranceSlip order, String path_sign, String payAmount, String paymentMethod){
		InsTransaction it = getTranctionByorderIDAndStatus(order.getIns_insurance_slip_id());
		if(it == null){
			it = new InsTransaction();
			it.setStart_time(DateUtil.getTimestamp());
			IdWorker idWorker = new IdWorker(ConstProp.INT_NUMBER_WORKERID, ConstProp.INT_NUMBER_ZERO);
			it.setTrade_serial_number(String.valueOf(idWorker.nextId()));
			it.setPay_type(paymentMethod);//ConstProp.DIGIT_SIX
			String payment_way = "1";
			if(order.getUnderwrite() != null){
				payment_way = order.getUnderwrite().getPayment_way();
			}
			it.setPayment_method(payment_way);
			it.setUser_id(order.getRegister_user_id());
			it.setInsurance_slip(order);
			it.setTransaction_status(DictConst.PAY_STATUS_WZF);
			dao.insert(it);
		}else{
			it.setUpdate_time(DateUtil.getTimestamp());
			it.setEnd_time(DateUtil.getTimestamp());
		}
		it.setPay_amount(new BigDecimal(payAmount));
		it.setPath_sign(path_sign);
		it.setPay_order_url(path_url);
		dao.updateById(it);
	}

	/**
	 * <b>根据订单ID及支付状态获取支付信息</b>
	 * @param order_id
	 * @author ZXF
	 * @date 2016年12月28日 上午11:03:32
	 * @注意事项 </b>
	 * <b>
	 */
	@Override
	public InsTransaction getTranctionByorderIDAndStatus(Long order_id) {
		List<InsTransaction> insTransactionList = selectInsTransactionByInsOrderForm(order_id);
		if(insTransactionList == null){
			return null;
		}
		for(InsTransaction it : insTransactionList){
			if(DictConst.PAY_STATUS_WZF.equals(it.getTransaction_status())){
				return it;
			}
		}
		return null;
	}

	/**
	 * 保存,更新 交易表
	 * @param vo
	 */
	@Override
	public void saveTransaction(PolicyTransactionVo vo) {

		if(vo.getOid()!=null){
			return;
		}
		//根据订单 id  查询 出  投保单id    和 子投保单ID
		InsInsuranceSlip insInsuranceSlip = insInsuranceSlipAPIService.selectById(Long.parseLong(vo.getPolicy_id()));
		if(StrUtil.isNotBlank(vo.getPayment_method())){
			InsTransaction  insTransaction = null;
			List<InsTransaction> insTransactionList = selectInsTransactionByInsOrderForm(Long.parseLong(vo.getPolicy_id()));
			if(insTransactionList.size()>0){
				insTransaction = insTransactionList.get(0);
			}else{
				insTransaction = initInsTransaction();
				insTransaction.setInsurance_slip(insInsuranceSlip);//订单id
			}
			if(StringUtils.isNotEmpty(vo.getTrade_serial_number())){
				insTransaction.setTrade_serial_number(vo.getTrade_serial_number());//交易流水号
			}
			insTransaction.setPayment_method(vo.getPayment_method());//payment_method 1.一次性支付
			if(StringUtils.isEmpty(insTransaction.getPay_type())){
				insTransaction.setPay_type(vo.getPay_type());//pay_type 6.转账 支付方式 *
			}
			if(vo.getOut_of_pocket() != null){
				insTransaction.setOut_of_pocket(vo.getOut_of_pocket());
			}
			if(insTransaction.getPay_amount()==null||BigDecimal.ZERO.equals(insTransaction.getPay_amount())){
				insTransaction.setPay_amount(vo.getPay_amount());//交易金额 *
			}
			if(StringUtils.isEmpty(insTransaction.getPay_order_url())){
				insTransaction.setPay_order_url(vo.getPay_order_url());//支付凭证地址 *
			}
			insTransaction.setPay_order_number(vo.getPay_order_number());//支付凭证号
			if(StringUtils.isNotEmpty(vo.getPath_sign())){
				insTransaction.setPath_sign(vo.getPath_sign());
			}else{
				OrderFormVo orderVo = policyService.accordingToOrderIDToGetPolicyDto(insInsuranceSlip.getIns_insurance_slip_id());
				insTransaction.setPath_sign("1".equals(orderVo.getPay_methods())? "1" : "");
			}
			insTransaction.setDeal_url(vo.getDeal_url());//支付地址
			insTransaction.setEnd_time(vo.getEnd_time());//交易结束时间
			insTransaction.setTransaction_status(vo.getTransaction_status());//交易状态
			insTransaction.setUser_id(vo.getUser_id());//创建用户
			dao.updateById(insTransaction);
		}
		if(StrUtil.isBlank(vo.getPolicy_serial_number())){
			return;
		}
		//同时需要把投保单号进行修改
		//查出投保单号ins_insurance_slip
		insInsuranceSlip.setPolicy_serial_number(vo.getPolicy_serial_number());//投保单号
		if(!DictConst.PAY_TYPE_XX.equals(vo.getPay_type())){
			if(vo.getOut_of_pocket() != null){
				insInsuranceSlip.setPremium(vo.getOut_of_pocket());
			}
			if(vo.getPay_amount() != null){//TODO 雪峰确认逻辑
				insInsuranceSlip.setPremium(vo.getPay_amount());
			}
		}
		if(StrUtil.isNotBlank(vo.getNotice_no())){
			insInsuranceSlip.setNotice_no(vo.getNotice_no());
		}
		insInsuranceSlipAPIService.updateById(insInsuranceSlip);
	}

	/**
	 * 更新交易表
	 * @param vo
	 */
	@Override
	public void updateTransaction(PolicyTransactionVo vo) {
		if(StrUtil.isNotBlank(vo.getPolicy_id())){
			InsTransaction  insTransaction = null;
			List<InsTransaction> insTransactionList = selectInsTransactionByInsOrderForm(Long.parseLong(vo.getPolicy_id()));
			if(insTransactionList.size()>0){
				insTransaction = insTransactionList.get(0);
			}else{
				return;
			}
			if(StringUtils.isNotEmpty(vo.getTrade_serial_number())){
				insTransaction.setTrade_serial_number(vo.getTrade_serial_number());//交易流水号
			}
			if(StringUtils.isEmpty(insTransaction.getPay_type())){
				insTransaction.setPay_type(vo.getPay_type());//pay_type 6.转账 支付方式 *
			}
			insTransaction.setPay_order_number(vo.getPay_order_number());//支付凭证号
			insTransaction.setEnd_time(vo.getEnd_time());//交易结束时间
			dao.updateById(insTransaction);
		}
	}

	/**
	 * 保存,其他
	 * 设置电子保函 ，电子保单
	 * @param vo
	 */
	@Override
	public void savePolicyOther(PolicyTransactionVo vo) {
		InsInsuranceSlip insInsuranceSlip = insInsuranceSlipAPIService.selectById(vo.getPolicy_id());
		if(insInsuranceSlip ==null){
			return;
		}
		InsAgreement insAgreement = insAgreementService.selectInsAgreementByInsInsuranceSlip(insInsuranceSlip.getIns_insurance_slip_id());
		if(insAgreement == null){
			return;
		}
		if(StringUtils.isNotEmpty(vo.getLg_path())){
			insInsuranceSlip.setLg_path(vo.getLg_path());//保函地址
			insAgreement.setLg_path(vo.getLg_path());//保函地址
		}
		if(StringUtils.isNotEmpty(vo.getInsure_path())){
			insInsuranceSlip.setInsure_path(vo.getInsure_path());//保单地址
			insAgreement.setInsure_path(vo.getInsure_path());//保单地址
		}
		insInsuranceSlipAPIService.updateById(insInsuranceSlip);
		insAgreementService.updateById(insAgreement);
	}

	/**
	 * 保存保单
	 * 修改订单状态为已经承包  orderstatus 6
	 * 交易记录改为已经支付
	 * @param vo
	 */
	@Override
	public void savePolicyExternalReference(PolicyTransactionVo vo) {
		InsInsuranceSlip insInsuranceSlip = insInsuranceSlipAPIService.selectById(vo.getPolicy_id());

		Long orderId=Long.parseLong(vo.getPolicy_id());

		List<InsTransaction> list=	dao.selectInsTransactionByInsOrderForm(orderId); //交易 表
		if(list!=null&&list.size()>0){
			// 交易记录改为已经支付
			InsTransaction  insTransaction =list.get(0);
			insTransaction.setTransaction_status(DictConst.PAY_STATUS_YZF);//设置已经支付
			insTransaction.setEnd_time(DateUtil.getTimestamp());
			insTransaction.setOut_of_pocket(insInsuranceSlip.getPremium());
			insTransaction.setPath_sign("1");
			dao.updateById(insTransaction);
		}
		if(StrUtil.isNotBlank(vo.getPolicy_number())){//修改订单状态为已承保
			/*insInsuranceSlip.setOrder_status("6");
			insInsuranceSlip.setEnd_time(new Date());
			insInsuranceSlipAPIService.updateById(insInsuranceSlip);*/
			//生成保单insAgreementService.willInsurePolicyVoChangeIntoInsAgreementg(order.getInsuranceSlipg().getId(), vo.getExternalReference());
			insAgreementService.willInsurePolicyVoChangeIntoInsAgreement(insInsuranceSlip.getIns_insurance_slip_id(), vo.getPolicy_number());
			OrderFormVo orderVo = new OrderFormVo();
			orderVo.setOid(vo.getPolicy_id());
			orderVo.setPolicy_status(DictConst.ORDER_STATUS_YCB);
			policyService.updateOrderFormStatus(orderVo);
			ThreadUtil.excAsync(()->{
				otherCZ(insInsuranceSlip.getIns_insurance_slip_id(),insInsuranceSlip.getPro_primary().getPro_primary_id());
			},false);
		}
	}

	/**
	 * 保存保单(用于承保后支付状态的订单业务)
	 * 修改订单状态为承保后支付  orderstatus 16
	 * @param vo
	 */
	@Override
	public void savePolicyExternalReference_16(PolicyTransactionVo vo) {
		InsInsuranceSlip insInsuranceSlip = insInsuranceSlipAPIService.selectById(vo.getPolicy_id());
		Long orderId=Long.parseLong(vo.getPolicy_id());
		if(StrUtil.isNotBlank(vo.getPolicy_number())){//修改订单状态为已承保
			OrderFormVo orderVo = new OrderFormVo();
			orderVo.setOid(vo.getPolicy_id());
			orderVo.setPolicy_status(DictConst.ORDER_STATUS_HZF);
			policyService.updateOrderFormStatus(orderVo);
			/*insInsuranceSlip.setOrder_status("6");
			insInsuranceSlip.setEnd_time(new Date());
			insInsuranceSlipAPIService.updateById(insInsuranceSlip);*/
			//生成保单insAgreementService.willInsurePolicyVoChangeIntoInsAgreementg(order.getInsuranceSlipg().getId(), vo.getExternalReference());
			insAgreementService.willInsurePolicyVoChangeIntoInsAgreement(insInsuranceSlip.getIns_insurance_slip_id(), vo.getPolicy_number());
			ThreadUtil.excAsync(()->{
				otherCZ(insInsuranceSlip.getIns_insurance_slip_id(),insInsuranceSlip.getPro_primary().getPro_primary_id());
			},false);
		}
	}

	/**
	 * <b> 用来处理一些承保后跟订单有关的业务操作 </b>
	 * @author ZXF
	 * @create 2018/06/05 0005 17:02
	 * @version
	 * @注意事项 </b>
	 */
	@Override
	public void otherCZ(Long order_id, Long pro_id){
		ProPrimary product = insProductAPIService.getProduct(pro_id);
		if(StringUtils.isEmpty(product.getProduct_code())){
			return;
		}
		if(product.getProduct_code().contains(ConstProp.TYX)||product.getProduct_code().contains(ConstProp.GZZRX)){
			insPreservationResultSetAPIService.initResultSetByOrderId(order_id);
		}
		/*if(ConstProp.DIGIT_TWO.equals(product.getInsured_person_property())){
			//被保险人批量创建账号
			insRolieInpolicyAPIService.createUserByRole(order_id);
		}*/
	}

	@Override
	public void updateTransationMsg(PolicyTransactionVo vo){

		List<InsTransaction> list=	dao.selectInsTransactionByInsOrderForm(Long.parseLong(vo.getPolicy_id())); //交易 表
		if(list!=null&&list.size()>0){
			// 交易记录改为已经支付
			InsTransaction  insTransaction =list.get(0);
			insTransaction.setTransaction_status(DictConst.PAY_STATUS_YZF);//设置已经支付
			insTransaction.setEnd_time(vo.getEnd_time());
			insTransaction.setOut_of_pocket(vo.getOut_of_pocket());
			insTransaction.setPath_sign("1");
			dao.updateById(insTransaction);
		}
	}

	@Override
	public void savePolicyExternalReferenceToDB(PolicyTransactionVo vo) {
		InsInsuranceSlip insInsuranceSlip = insInsuranceSlipAPIService.selectById(vo.getPolicy_id());
		if(StrUtil.isNotBlank(vo.getPolicy_number())){//修改订单状态为已承保
			insAgreementService.willInsurePolicyVoChangeIntoInsAgreement(insInsuranceSlip.getIns_insurance_slip_id(), vo.getPolicy_number());
			ProPrimary product = insProductAPIService.getProduct(insInsuranceSlip.getPro_primary().getPro_primary_id());
		}
	}

	/**
	 * <b>根据订单ID获取支付期标识</b> 
	 * 注：1-0指1为支付期标识号（当前需要上传凭证的位数），0指新的标识如果-1则表示可做修改
	 * @param order_id 
	 * @author ZXF 
	 * @date 2016年12月28日 上午11:03:32
	 * @注意事项 </b>
	 * <b>
	 */
	@Override
	public String accordingToOrderIDGainPathSign(String order_id) {
		List<InsTransaction> insTransactionList = selectInsTransactionByInsOrderForm(Long.parseLong(order_id));
		String pathSign = "1-0";
		if(insTransactionList == null){
			return pathSign;
		}
		for(InsTransaction it : insTransactionList){
			if(DictConst.PAY_STATUS_WZF.equals(it.getTransaction_status())){
				pathSign = it.getPath_sign()+"-1";
			}
		}
		if("1-0".equals(pathSign)){
			pathSign = String.valueOf(insTransactionList.size()+1)+"-0";
		}
		return pathSign;
	}
}
