package com.bcxin.ins.coninsweb.order.controller.api.gyx;

import com.bcxin.ins.service.order.PolicyService;
import com.bcxin.ins.service.product.ProductService;
import com.bcxin.ins.rest.UserSupportUtil;
import com.bcxin.ins.core.base.web.BaseController;
import com.bcxin.ins.spring.annotation.LoginRequired;
import com.bcxin.ins.spring.annotation.OperationLog;
import com.bcxin.ins.util.IdWorker;
import com.bcxin.ins.util.RegionUtils;
import com.bcxin.ins.util.enums.IdType;
import com.bcxin.ins.util.enums.NatureLinkage;
import com.bcxin.ins.vo.*;
import com.bcxin.mybatisplus.toolkit.StringUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 负责前台个意险投保流程的业务逻辑处理
 * @author zxf
 *
 */
@Controller
@RequestMapping("/api/gyx")
public class GYX_Policy_API_Controller extends BaseController {


	@Autowired
	private PolicyService policyService;

	@Autowired
	private ProductService productService;

	@OperationLog(source = OperationLog.SOURCETYPE.FRONT,title ="【视图】产品-访问投保页")
	@LoginRequired(methodParamKey={"1#product_id"}, redirectUrl = "insurance/policy_init_iframe/{product_id}")
	@RequestMapping("/policyInit/{product_id}")
	public ModelAndView policyInit(HttpServletRequest request, @PathVariable Long product_id, ModelMap model) {
		ClientUserVo userdetail = UserSupportUtil.getSessionUser();
		String personNum = request.getParameter("personNum");
		int num = 0;
		if(StringUtils.isNotEmpty(personNum)){
			num = Integer.parseInt(personNum);
		}
		//请求百保盾返回企业信息及员工信息
		GYXPolicyVo vo = new GYXPolicyVo();
		if(StringUtils.isNotEmpty(userdetail.getWeb_type())) {
			List<RoleSubjectVo> doList = null;
			if (userdetail.getWeb_type().indexOf(ConstProp.ARS) != -1) {
				doList = policyService.getComAndEmpByUserID_BBDAPI(userdetail.getWeb_id(),userdetail.getWeb_type());
			}
			if (userdetail.getWeb_type().contains(ConstProp.SAAS)||userdetail.getWeb_type().contains(ConstProp.PASP)) {
				doList = policyService.getComAndEmpByUserID_API(userdetail.getWeb_id(),userdetail.getWeb_type());
			}
			if(doList != null){
				List<RoleSubjectVo> voList = sortRoleList(doList,num,0);
				vo.setRoleSubjectList(voList);
			}
		}
		ModelAndView view = new ModelAndView();
		view.addObject(ConstProp.VO, vo);
		view.addObject(ConstProp.RECOMMEND_CODE,UserSupportUtil.getRecommendCode());
		orderAllotInit(product_id, view);
		setTokenByApi(view);
		return view;
	}

	/**
	 * 根据获取到的投保人被保人列表筛选排序
	 * @param doList
	 * @param num 被保人人数限制
	 * @param type 0为初始1为已存在被保险人
	 * @return
	 */
	private List<RoleSubjectVo> sortRoleList(List<RoleSubjectVo> doList,int num,int type){
		List<RoleSubjectVo> results = new ArrayList<RoleSubjectVo>();
		if(doList == null){
			if(num>0){
				RoleSubjectVo appRole = new RoleSubjectVo();
				appRole.setKind(ConstProp.DIGIT_ONE);
				results.add(appRole);
				RoleSubjectVo insRole = null;
				for(int i=0;i<num;i++){
					insRole = new RoleSubjectVo();
					insRole.setKind(ConstProp.DIGIT_TWO);
					results.add(insRole);
					insRole = null;
				}
				return results;
			}else{
				return null;
			}
		}
		List<RoleSubjectVo> insurceRoleList = new ArrayList<RoleSubjectVo>();
		for(RoleSubjectVo vo : doList){
			if(ConstProp.DIGIT_ONE.equals(vo.getKind())){
				results.add(vo);
			}else{
				insurceRoleList.add(vo);
			}
		}
		if(results.size() == 0){
			RoleSubjectVo vo = new RoleSubjectVo();
			vo.setKind(ConstProp.DIGIT_ONE);
			results.add(vo);
		}
		if(type != 0){
			results.addAll(insurceRoleList);
			return results;
		}
		//以上筛选投保人，筛选被保险人
		if(insurceRoleList.size()<=0){
			return results;
		}
		int insRoleNum = insurceRoleList.size();
		if(insRoleNum<num){//加载被保险人，被保险人小于限制人数
			results.addAll(insurceRoleList);
			int lastNum = num-insRoleNum;
			for(int i=0;i<lastNum;i++){
				RoleSubjectVo rvo = new RoleSubjectVo();
				rvo.setKind(ConstProp.DIGIT_TWO);
				results.add(rvo);
			}
		}else if(insRoleNum==num){
			results.addAll(insurceRoleList);
		}else if(num == 0){
			results.addAll(insurceRoleList);
		}else{
			for(int i=0;i<num;i++){
				results.add(insurceRoleList.get(i));
			}
		}

		return results;
	}

	private String createOrderAndGetOrderIDByProductID(Long product_id, Long user_id, String recommendCode,String trade_serial_number){
		Map<String, Object> map = policyService.createOrderFormByProductOid(product_id, user_id, recommendCode, trade_serial_number);
		if(map.get(ConstProp.ORDER_ID) != null){
			return (String)map.get(ConstProp.ORDER_ID);
		}
		return "";
	}

	/**
	 * <b>通过订单ID跳转到投保界面 </b>
	 *
	 * @param request
	 * @param order_id
	 * @return
	 * @author ZXF
	 * @date 2016年12月21日 下午1:46:44
	 * @注意事项 </b>
	 * <b>
	 */
	@LoginRequired(methodParamKey={"1#order_id"}, redirectUrl = "insurance/gyx/policy/policy_iframe/{order_id}")
	@RequestMapping("/policy/{order_id}")
	public ModelAndView enterInfo(HttpServletRequest request, @PathVariable Long order_id) {
		ModelAndView view = new ModelAndView();
		orderAllot(order_id, view);
		setTokenByApi(view);
		return view;
	}

	private void orderAllotInit(Long product_id, ModelAndView view) {
		ProductVo pd = productService.getProduct(product_id);
		OrderFormVo dto = new OrderFormVo();
		dto.setProduct_oid(pd.getOid());
		dto.setProduct_code(pd.getProduct_code());
		dto.setGross_premium(pd.getPremium_min());
		dto.setTrade_serial_number(String.valueOf(IdWorker.getId()));
		view.addObject("sigId", String.valueOf(IdWorker.getId()));//普通的页面标识
		view.addObject(ConstProp.PD,pd);
		view.addObject(ConstProp.DTO,dto);
		view.addObject("personTypeList", IdType.personList());
		if(StringUtils.isNotEmpty(pd.getProduct_code())){
			if(ConstProp.GYX.equals(pd.getProduct_code().split(ConstProp.MINUS)[0])){
				try {
					view.addObject(ConstProp.PROVINCELIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_ONE, ConstProp.BLANK_CHAR));
				}catch (Exception e){
					e.printStackTrace();
				}
				view.setViewName("/coninsweb/api/gyx/policy/gyx_enterBasicInfo");
			}
		}
	}

	@RequestMapping(value = "/natureChange")
	@ResponseBody
	public Map<String, String> natureChange(HttpServletRequest request) {
		String nID = request.getParameter("nID");
		if(StringUtils.isNotEmpty(nID)){
			Map<String, String> map = NatureLinkage.getMapByProvince(nID);
			return map;
		}
		return null;
	}

	private void orderAllot(Long order_id, ModelAndView view) {
		try {
			OrderFormVo dto = policyService.accordingToOrderIDToGetPolicyDto(order_id);
			ProductVo pd = productService.getProduct(Long.parseLong(dto.getProduct_oid()));
			view.addObject(ConstProp.PD,pd);
			view.addObject(ConstProp.DTO,dto);
			view.addObject("personTypeList", IdType.personList());
			if(StringUtils.isEmpty(dto.getProduct_code()) || !ConstProp.GYX.equals(dto.getProduct_code().split(ConstProp.MINUS)[0])){
				return;
			}
			GYXPolicyVo vo = policyService.accordingToOrderIDToGetGYXPolicyVo(order_id);
			view.addObject(ConstProp.VO,vo);
			view.setViewName("/coninsweb/api/gyx/policy/gyx_enterBasicInfo");
			view.addObject(ConstProp.PROVINCELIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_ONE, ConstProp.BLANK_CHAR));
			if(vo == null){
				return;
			}
			if(vo.getRoleSubjectList().size()>0){
				//投保人地址
				if (StringUtils.isNotEmpty(vo.getRoleSubjectList().get(0).getReg_province())) {
					view.addObject(ConstProp.REG_CITYLIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_TWO, vo.getRoleSubjectList().get(0).getReg_province()));
				}
				if (StringUtils.isNotEmpty(vo.getRoleSubjectList().get(0).getReg_city())) {
					view.addObject(ConstProp.REG_AREALIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_THREE, vo.getRoleSubjectList().get(0).getReg_city()));
				}
			}
		}catch (Exception e){
			e.printStackTrace();
		}

	}

	/**
	 * <b>团意险投保界面跳转到确认页面中间的业务 </b>
	 *
	 * @param order_id
	 * @param request
	 * @return
	 * @throws Exception
	 * @author ZXF
	 * @date 2016年12月28日 下午4:21:44
	 * @注意事项 </b>
	 * <b>
	 */
	@LoginRequired(methodParamKey={"0#order_id"}, redirectUrl = "insurance/gyx/policy/policy_iframe/{order_id}")
	@RequestMapping("/policy/confirmPage/{order_id}")
	public ModelAndView confirmPage(@PathVariable Long order_id, HttpServletRequest request) throws Exception{
		ModelAndView view = new ModelAndView();
		OrderFormVo dto = policyService.accordingToOrderIDToGetPolicyDto(order_id);
		ProductVo pd = productService.getProduct(Long.parseLong(dto.getProduct_oid()));
		view.addObject(ConstProp.PD,pd);
		view.addObject(ConstProp.DTO,dto);
		if(StringUtils.isEmpty(dto.getProduct_code()) ? false : ConstProp.GYX.equals(dto.getProduct_code().split(ConstProp.MINUS)[0])){
			view.setViewName("/coninsweb/api/gyx/policy/policyConfirm");
			GYXPolicyVo vo = policyService.accordingToOrderIDToGetGYXPolicyVo(order_id);
			List<IdType> typeList = IdType.doList();
			view.addObject(ConstProp.VO,vo);
			view.addObject("typeList",typeList);
			view.addObject(ConstProp.REG_ROLE, RegionUtils.getRegionNameByALLCode(vo.getRoleSubjectList().get(0).getReg_province(), vo.getRoleSubjectList().get(0).getReg_city(), vo.getRoleSubjectList().get(0).getReg_district()));
		}
		setTokenByApi(view);
		return view;
	}

	/**
	 * <b>团意险投保单客户填一半暂存，方法 </b>
	 *
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 * @author ZXF
	 * @date 2016年12月21日 下午1:47:55
	 * @注意事项 </b>
	 * <b>
	 */
	@OperationLog(source = OperationLog.SOURCETYPE.FRONT_ORDER,title ="【请求】产品-订单投保")
	@RequestMapping("/policy/pendingGYXPolicyVoPolicy")
	@ResponseBody
	public ResultDto pendingGYXPolicyVoPolicy(GYXPolicyVo vo, HttpServletRequest request, HttpServletResponse response) throws Exception{
		String recommendCode = request.getParameter(ConstProp.RECOMMENDCODE);
		return policyService.pendingGYXPolicyVoPolicy(vo, recommendCode);
	}

	/**
	 * <b>修改订单状态</b>
	 *
	 * @return
	 * @throws Exception
	 * @author ZXF
	 * @date 2016年12月21日 下午1:47:55
	 * @注意事项 </b>
	 * <b>
	 */
	@LoginRequired
	@RequestMapping("/policy/updateOrderFormStatus")
	@ResponseBody
	public ResultDto updateOrderFormStatus(HttpServletRequest request) throws Exception{
		String order_id = request.getParameter(ConstProp.ORDER_ID);
		String status = request.getParameter("status");
		if(StringUtils.isEmpty(order_id) || StringUtils.isEmpty(status)){
			return new ResultDto("数据丢失，请刷新页面后重试！", ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
		}
		OrderFormVo vo = new OrderFormVo();
		vo.setOid(String.valueOf(order_id));
		vo.setPolicy_status(status);
		String orderID = policyService.updateOrderFormStatus(vo);
		if(StringUtils.isNotEmpty(orderID)){
			return new ResultDto("订单录入成功。", ConstProp.CODE_SUCCESS, orderID, ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR);
		}else{
			return new ResultDto("数据丢失，请刷新页面后重试！", ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
		}
	}

	/**
	 * <b>业务逻辑处理，保存保单信息
	 * 页面流转：点击保单保存，跳转支付页面 </b>
	 *
	 * @param order_id 保单id
	 * @return
	 * @author ZXF
	 * @date 2016年12月21日 下午1:48:20
	 * @注意事项 </b>
	 * <b>
	 */
	@LoginRequired(methodParamKey={"0#order_id"}, redirectUrl = "insurance/gyx/policy/payment_iframe/{order_id}")
	@RequestMapping("/policy/policyPayment/{order_id}")
	public ModelAndView savePolicy(@PathVariable long order_id, HttpServletRequest request) {
		ModelAndView view = new ModelAndView();
		try {
			OrderFormVo vo = policyService.accordingToOrderIDToGetPolicyDto(order_id);
			ProductVo pd = productService.getProduct(Long.parseLong(vo.getProduct_oid()));
			view.addObject(ConstProp.PD,pd);
			view.addObject(ConstProp.DTO,vo);
			if(StringUtils.isNotEmpty(vo.getPay_methods())){
				AdviceNoteVo anVo = policyService.accordingToOrderIDToGetAdviceNoteVo(order_id);
				view.setViewName("/coninsweb/api/gyx/transaction/paymentNotice");
				view.addObject(ConstProp.ANVO, anVo);
				view.addObject(ConstProp.NOWTIME,new Date());
				setTokenByApi(view);
				return view;
			}
			if(vo.getPolicy_status().equals(ConstProp.DIGIT_FOUR)){//待支付
				if(ConstProp.GYX.equals(pd.getProduct_code().split(ConstProp.MINUS)[0])){//跳转太保支付页面
					view.setViewName("/coninsweb/api/gyx/transaction/policyPayment_TB");
				}else{
					//失败界面
				}
			}else if(vo.getPolicy_status().equals(ConstProp.DIGIT_FIVE)){//待承保
				view.setViewName("/coninsweb/api/gyx/transaction/finishPay");
			}
		}catch (Exception e){
			e.printStackTrace();
		}
		view.addObject(ConstProp.NOWTIME,new Date());
		setTokenByApi(view);
		return view;
	}

	@RequestMapping("/sessionInfo")
	@ResponseBody
	public ResultDto sessionInfo(HttpServletRequest reqeust, ModelMap model) {
		String name = reqeust.getParameter("name");
		String base64 = reqeust.getParameter("base64");
		model.addAttribute(name, base64);
		return new ResultDto("", ConstProp.CODE_SUCCESS, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
	}

	@RequestMapping("/policy/deleteRoleInPolicyByOid")
	@ResponseBody
	public ResultDto deleteRoleInPolicyByOid(HttpServletRequest request) {
		String role_id = request.getParameter("role_id");
		if(StringUtils.isEmpty(role_id)){
			return new ResultDto("数据丢失，删除失败！", ConstProp.CODE_FAILURE,ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
		}
		if(policyService.deleteRoleInPolicyByOid(role_id)){
			return new ResultDto("删除成功！", ConstProp.CODE_SUCCESS,ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
		}else{
			return new ResultDto("运行时异常，删除失败！", ConstProp.CODE_FAILURE,ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
		}
	}

	/**
	 * excel文件上传并解析
	 * @param request
	 * @return
	 * @throws IOException
	 */
	@RequestMapping("/policy/uploadRoleFile")
	public ModelAndView uploadRoleFile(MultipartHttpServletRequest request) throws IOException {
		ModelAndView view = new ModelAndView("/coninsweb/api/gmr/policy/b");
		MultipartFile roleFile = request.getFile("role_file");
		List<Map<String,String>> list = null;
		if(roleFile == null){
			view.addObject("list", list);
			setTokenByApi(view);
			return view;
		}
		InputStream is = roleFile.getInputStream();
		XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is);
		list = Lists.newArrayList();
		// Read the Sheet
		for (int numSheet = 0; numSheet < xssfWorkbook.getNumberOfSheets(); numSheet++) {
			XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(numSheet);
			if (xssfSheet == null) {
				continue;
			}
			// Read the Row
			for (int rowNum = 1; rowNum <= xssfSheet.getLastRowNum(); rowNum++) {
				XSSFRow xssfRow = xssfSheet.getRow(rowNum);
				if (xssfRow == null) {
					continue;
				}
				Map<String,String> map = Maps.newHashMap();
				for (int i = 0; i < 6; i++) {
					XSSFCell cell = xssfRow.getCell(i);
					if ( cell == null ) {
						map.put(i+"","");
						continue;
					}
					map.put(i+"",getValue(cell));
				}
				list.add(map);
			}
		}
		view.addObject("list", list);
		setTokenByApi(view);
		return view;
	}

	@SuppressWarnings("static-access")
	private static String getValue(XSSFCell xssfRow) {
		if (xssfRow.getCellType() == xssfRow.CELL_TYPE_BOOLEAN) {
			return String.valueOf(xssfRow.getBooleanCellValue());
		} else if (xssfRow.getCellType() == xssfRow.CELL_TYPE_NUMERIC) {
			return String.valueOf(xssfRow.getNumericCellValue());
		} else {
			return String.valueOf(xssfRow.getStringCellValue());
		}
	}


}
