package com.bcxin.ins.coninsweb.order.stragegy.order.impl;

import com.bcxin.ins.service.order.PolicyService;
import com.bcxin.ins.coninsweb.order.stragegy.order.OrderSupplyStrategy;
import com.bcxin.ins.coninsweb.order.stragegy.order.OrderSupplyType;
import com.bcxin.ins.service.product.ProductService;
import com.bcxin.ins.vo.*;
import com.bcxin.mybatisplus.toolkit.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;

/**
 * 保费计算策略
 * @author zxf
 * @date 2018/08/30
 * @说明 策略方案提议及案例提供人：hzp 2018/06/12
 */
@Component
@OrderSupplyType(type = OrderSupplyType.OrderSupplyTypeEnum.INSURANCE_CALCULATION)
public class StragegyInsuranceCalculation implements OrderSupplyStrategy {

    @Autowired
    private PolicyService policyService;

    @Autowired
    private ProductService productService;

    @Override
    public ModelAndView policyInitService(HttpServletRequest request, Long product_id) {
        return null;
    }

    @Override
    public ModelAndView getPolicyService(Long order_id, int page) {
        return null;
    }

    @Override
    public ResultDto pendingPolicyService(Object object, HttpServletRequest request) {
        return null;
    }

    @Override
    public ModelAndView confirmPolicyService(Long order_id) {
        return null;
    }

    @Override
    public ModelAndView paymentRequestService(Long order_id) {
        return null;
    }

    @Override
    public ResultDto underwritingRequestService(HttpServletRequest request) {
        return null;
    }

    @Override
    public ResultDto insuranceCalculationService(HttpServletRequest request) {
        //产品编码 TODO 如果引用该方案，需注意页面传的产品编码名称（可能是productCode，也可能是product_code）
        String productCode = request.getParameter("productCode");
        if(StringUtils.isEmpty(productCode) ? false : productCode.contains(ConstProp.XYX_DQCK)){

        }else if(StringUtils.isEmpty(productCode) ? false : productCode.contains(ConstProp.XYX_XWCK)){

        }else if(StringUtils.isEmpty(productCode) ? false : productCode.contains(ConstProp.BZX_SSBQ)){

        }else if(StringUtils.isEmpty(productCode) ? false : productCode.contains(ConstProp.GZX)){
//            if(productCode.contains(ConstProp.GZX_HT)){//华泰公责险
//
//            }else{//其它保险公司公责险
//
//            }
        }else if(StringUtils.isEmpty(productCode) ? false : productCode.contains(ConstProp.TYX)){

        }else if(StringUtils.isEmpty(productCode) ? false : productCode.contains(ConstProp.GZZRX)){
            String is_contain_repo = request.getParameter("is_contain_repo");
            String person_num = request.getParameter("person_num");
            String premium = request.getParameter("premium");
            return insuranceCalculationGZZRX(productCode, is_contain_repo, person_num, premium);
        }else if(StringUtils.isEmpty(productCode) ? false : productCode.contains(ConstProp.ZZX)){
            String exAcreage = request.getParameter("exAcreage");//展位面积
            String result = policyService.zzx_amount_count(productCode,exAcreage);
            if(ConstProp.CODE_SUCCESS.equals(result.split(ConstProp.POUND_SIGN)[0])){
                return new ResultDto(result.split(ConstProp.POUND_SIGN)[1], ConstProp.CODE_SUCCESS, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
            }
            return new ResultDto(result.split(ConstProp.POUND_SIGN)[1], ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
        }else if(StringUtils.isEmpty(productCode) ? false : productCode.contains(ConstProp.GCTB)){
            String insuredAmount = request.getParameter("insuredAmount");//保险金额
            String provinceCode = request.getParameter("provinceCode");//省编码
            String cityCode = request.getParameter("cityCode");//市编码
            String aptitudeLevel = request.getParameter("aptitudeLevel");//资质等级
            String officeType = request.getParameter("officeType");//工程类型
            return insuranceCalculationGCTB(productCode, insuredAmount, provinceCode, cityCode, aptitudeLevel, officeType);
        }else if(StringUtils.isEmpty(productCode) ? false : productCode.contains(ConstProp.GCLY)){

        }
        return null;
    }

    @Override
    public ResultDto getElectronicInsuranceService(Long order_id) {
        return null;
    }

    private ResultDto insuranceCalculationGZZRX(String product_code, String is_contain_repo, String person_num, String premium){
        if(StringUtils.isNotEmpty(product_code)&&StringUtils.isNotEmpty(is_contain_repo)&&StringUtils.isNotEmpty(person_num)&&StringUtils.isNotEmpty(premium)){
            BigDecimal prm = BigDecimal.ZERO;//总保费
            BigDecimal aom = BigDecimal.ZERO;//总保额
            BigDecimal pm = BigDecimal.valueOf(Double.parseDouble(premium));//单个初始保费
            //可选增加保费
            String epm = "GZZRX-RB-1".equals(product_code) ? "25"
                    : "GZZRX-RB-2".equals(product_code) ? "35"
                    : "GZZRX-RB-3".equals(product_code) ? "45"
                    : "GZZRX-RB-4".equals(product_code) ? "55"
                    :"0";
            //单个保额
            String eam = "GZZRX-RB-1".equals(product_code) ? "3000000"
                    : "GZZRX-RB-2".equals(product_code) ? "4000000"
                    : "GZZRX-RB-3".equals(product_code) ? "5000000"
                    : "GZZRX-RB-4".equals(product_code) ? "6000000"
                    :"0";
            if(!ConstProp.DIGIT_ZERO.equals(eam)){
                //统计保额
                aom = (BigDecimal.valueOf(Double.parseDouble(eam))).multiply(BigDecimal.valueOf(Double.parseDouble(person_num))).setScale(2,BigDecimal.ROUND_HALF_UP);
            }
            if(ConstProp.DIGIT_ONE.equals(is_contain_repo)){
                //初始保费加可选保费，当is_contain_repo=1时
                pm = pm.add(BigDecimal.valueOf(Double.parseDouble(epm)));
            }
            //统计保费
            prm = pm.multiply(BigDecimal.valueOf(Double.parseDouble(person_num))).setScale(2,BigDecimal.ROUND_HALF_UP);
            System.out.println(prm+ConstProp.POUND_SIGN+aom);
            return new ResultDto(prm+ConstProp.POUND_SIGN+aom, ConstProp.CODE_SUCCESS, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
        }
        return new ResultDto(ConstProp.BLANK_CHAR, ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
    }

    private ResultDto insuranceCalculationGCTB(String productCode, String insuredAmount, String provinceCode, String cityCode, String aptitudeLevel, String officeType){
        if(StringUtils.isNotEmpty(insuredAmount)
                &&StringUtils.isNotEmpty(productCode)
                &&StringUtils.isNotEmpty(provinceCode)
                &&StringUtils.isNotEmpty(cityCode)){
            BigDecimal premium = BigDecimal.ZERO;
            if("350200".equals(cityCode)){//如果是厦门市直接用方案二计算保费
                premium = numPremium(insuredAmount, aptitudeLevel, officeType);
            }else {
                if(productCode.contains("BZX-DB")){
                    premium = numPremium(insuredAmount, aptitudeLevel, officeType);
                }else if(productCode.contains("BZX-TB")){
                    if("350000".equals(provinceCode)) {//如果是福建省除厦门市外用方案一计算保费
                        premium = numPremiumOt(insuredAmount);
                    }else{
                        return new ResultDto(ConstProp.BLANK_CHAR, ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
                    }
                }else{
                    return new ResultDto(ConstProp.BLANK_CHAR, ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
                }
            }
            if(!(premium.compareTo(BigDecimal.ZERO)<0)){
                return new ResultDto(String.valueOf(premium.setScale(2,BigDecimal.ROUND_HALF_UP)), ConstProp.CODE_SUCCESS, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
            }else{
                return new ResultDto(ConstProp.BLANK_CHAR, ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
            }
        }
        return new ResultDto(ConstProp.BLANK_CHAR, ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
    }

    //保费计算方案一（太保福建地区除厦门市外）
    private BigDecimal numPremiumOt(String insuredAmount){
        BigDecimal ia = BigDecimal.valueOf(Double.parseDouble(insuredAmount));
        BigDecimal premium = BigDecimal.ZERO;
        if(!(ia.compareTo(BigDecimal.ZERO)<0)&&!((BigDecimal.valueOf(Double.parseDouble("100000"))).compareTo(ia)<0)){//0-100000
            premium = BigDecimal.valueOf(Double.parseDouble("150"));
        }else if(ia.compareTo(BigDecimal.valueOf(Double.parseDouble("100000")))>0&&(BigDecimal.valueOf(Double.parseDouble("800000"))).compareTo(ia)>=0){//100000-800000
            premium = ia.multiply(BigDecimal.valueOf(Double.parseDouble("0.0015")));
        }
        return premium;
    }

    //保费计算方案二（阳光，太保厦门地区用，都邦全国用）
    private BigDecimal numPremium(String insuredAmount, String aptitudeLevel, String officeType){
        BigDecimal ia = BigDecimal.valueOf(Double.parseDouble(insuredAmount));
        BigDecimal premium = BigDecimal.ZERO;
        if(!(ia.compareTo(BigDecimal.ZERO)<0)&&!((BigDecimal.valueOf(Double.parseDouble("100000"))).compareTo(ia)<0)){//0-100000
            premium = BigDecimal.valueOf(Double.parseDouble("300"));
        }else if(!(ia.compareTo(BigDecimal.valueOf(Double.parseDouble("100000")))<0)&&!((BigDecimal.valueOf(Double.parseDouble("200000"))).compareTo(ia)<0)){//100000-200000
            premium = BigDecimal.valueOf(Double.parseDouble("350"));
        }else if(!(ia.compareTo(BigDecimal.valueOf(Double.parseDouble("200000")))<0)&&!((BigDecimal.valueOf(Double.parseDouble("300000"))).compareTo(ia)<0)){//200000-300000
            premium = BigDecimal.valueOf(Double.parseDouble("400"));
        }else if(!(ia.compareTo(BigDecimal.valueOf(Double.parseDouble("300000")))<0)&&!((BigDecimal.valueOf(Double.parseDouble("400000"))).compareTo(ia)<0)){//300000-400000
            premium = BigDecimal.valueOf(Double.parseDouble("450"));
        }else if(!(ia.compareTo(BigDecimal.valueOf(Double.parseDouble("400000")))<0)&&!((BigDecimal.valueOf(Double.parseDouble("500000"))).compareTo(ia)<0)){//400000-500000
            premium = BigDecimal.valueOf(Double.parseDouble("500"));
        }else if(!(ia.compareTo(BigDecimal.valueOf(Double.parseDouble("500000")))<0)&&!((BigDecimal.valueOf(Double.parseDouble("600000"))).compareTo(ia)<0)){//500000-600000
            premium = BigDecimal.valueOf(Double.parseDouble("550"));
        }else if(!(ia.compareTo(BigDecimal.valueOf(Double.parseDouble("600000")))<0)&&!((BigDecimal.valueOf(Double.parseDouble("700000"))).compareTo(ia)<0)){//600000-700000
            premium = BigDecimal.valueOf(Double.parseDouble("600"));
        }else if(!(ia.compareTo(BigDecimal.valueOf(Double.parseDouble("700000")))<0)&&!((BigDecimal.valueOf(Double.parseDouble("800000"))).compareTo(ia)<0)){//700000-800000
            premium = BigDecimal.valueOf(Double.parseDouble("650"));
        }
        return premium.multiply(alNum(aptitudeLevel)).multiply(otNum(officeType));
    }

    //企业资质系数
    private BigDecimal alNum(String aptitudeLevel){
        if(ConstProp.DIGIT_ONE.equals(aptitudeLevel)) {
            return BigDecimal.valueOf(Double.parseDouble("0.7"));
        }
        if(ConstProp.DIGIT_TWO.equals(aptitudeLevel)) {
            return BigDecimal.valueOf(Double.parseDouble("0.95"));
        }
        if(ConstProp.DIGIT_THREE.equals(aptitudeLevel)) {
            return BigDecimal.ONE;
        }
        if(ConstProp.DIGIT_FOUR.equals(aptitudeLevel)) {
            return BigDecimal.valueOf(Double.parseDouble("1.3"));
        }
        if(ConstProp.DIGIT_FIVE.equals(aptitudeLevel)) {
            return BigDecimal.valueOf(Double.parseDouble("1.5"));
        }
        return BigDecimal.ONE;
    }

    //工程类型系数
    private BigDecimal otNum(String officeType){
        if("7".equals(officeType)||"0001".equals(officeType)){
            return BigDecimal.valueOf(Double.parseDouble("0.7"));
        }
        return BigDecimal.ONE;
    }
}
