package abacus.springboot.example.controller;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.abacus.pms.dao.Account;
import com.abacus.pms.wsi.AccountServiceIF;
import com.abacus.pms.wsi.ProductServiceIF;
import com.abacus.xpos.foundation.pubs.DaoIdGenerator;
import com.abacus.xpos.foundation.wsi.EmployeeServiceIF;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import abacus.commons.exception.BusinessException;
import abacus.springboot.example.config.JcConfigKey;
import abacus.springboot.example.dao.JcBill;
import abacus.springboot.example.dao.JcBillHg;
import abacus.springboot.example.dao.JcBillInItem;
import abacus.springboot.example.dao.JcBillPhoto;
import abacus.springboot.example.dao.JcBillSourceItem;
import abacus.springboot.example.util.DateToUpperChinese;
import abacus.springboot.example.util.DateUtil;
import abacus.springboot.example.vo.SiDepositlocation;
import abacus.springboot.example.wsi.JcBillServiceIF;

/**
 * <p>Title:JcBillHgController</p>
   <p>Description: 前端相关-api</p>
   @author chuanZeng 
   @date 2026年8月18日
 */
@RestController
@RequestMapping(value = "/jc/billHg")
public class JcBillHgController extends BaseServlet{

	private static final Logger LOG = LoggerFactory.getLogger(JcBillHgController.class);
	
	@Autowired
	private JcBillServiceIF jcBillService;
	
	@Autowired
	private AccountServiceIF accountService;
	
	@Autowired
	private ProductServiceIF productService;
	
	@Autowired
	private DaoIdGenerator jcBillHgIdGenerator;
	
	@Autowired
	private EmployeeServiceIF employeeService;
	
	/**
	 * 	TODO 稽查入库(回购通知)明细
	 * @param billId
	 * @return
	 * @throws Throwable
	 */
	@RequestMapping(value = "queryJcBillInItems", method = RequestMethod.POST)
	public JSONObject queryJcBillInItems(
			@RequestParam(required = true) String billId
		)
	throws Throwable {
		try {
			
			List<JcBillInItem> items = jcBillService.queryJcBillInItemByBillId(billId);
			
			if(items == null) throw new BusinessException("回购明细不存在！");
			
			List<JcBillInItem> oneList = new ArrayList<JcBillInItem>();
			List<JcBillInItem> twoList = new ArrayList<JcBillInItem>();
			
			
			for(JcBillInItem item : items) {
				if(JcBillInItem.STATUS_TWO != item.getStatus()) {
					Account account = accountService.getAccount(item.getAccount());
					if(account != null) {
						item.setOperator(account.getOperator().getId());
						item.setOperatorname(account.getOperator().getName());
						item.setSalearea(account.getSalearea());
					} else {
						item.setSalearea("");
						item.setSaleareaname("");
						item.setGroupid("");
						item.setGroupname("");
					}
				}
			}
			
			jcBillService.saveJcBillInItem(items);
			
			// 分出，已通知或未通知
			for(JcBillInItem item : items) {
				if(JcBillInItem.STATUS_MINUS_ONE == item.getStatus() || JcBillInItem.STATUS_ONE == item.getStatus()) {
//					item.setPrice(new BigDecimal(String.valueOf(item.getPrice())).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
					oneList.add(item);
				} else {
//					item.setPrice(new BigDecimal(String.valueOf(item.getPrice())).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
					twoList.add(item);
				}
			}
			
			
			
			JSONObject obj = new JSONObject();
			
			obj.put("oneList", oneList);
			obj.put("twoList", twoList);
			obj.put("threeList", items);
			
			return obj;
		} catch(Throwable e){
			LOG.error(e.getMessage(), e);
			e.printStackTrace();
			throw e;
		}
	}

	/**
	 * 	TODO 查询回购明细对应的溯源信息
	 * @param id
	 * @return
	 * @throws Throwable
	 */
	@RequestMapping(value = "queryHgSourceItems", method = RequestMethod.POST)
	public List<JcBillSourceItem> queryHgSourceItems(
			@RequestParam(required = true) String id
		)
	throws Throwable {
		try {
			JcBillInItem inItem = jcBillService.queryJcBillInItemById(Long.parseLong(id));
			
			if(inItem == null) throw new BusinessException("回购明细不存在！");
			
			List<JcBillSourceItem> billItems = jcBillService.queryJcBillSourceItemByBillId(inItem.getBillid());
			
			if(billItems == null) throw new BusinessException("溯源信息不存在！");
			
			// 按客户编码+商品编码+收货单价分组
			Map<String, List<JcBillSourceItem>> mapItems = billItems.stream()
					.collect(Collectors.groupingBy(e -> {
						return e.getAccount() + "#" + e.getProduct() + "#" + String.valueOf(e.getPrice());
					}, 
					Collectors.collectingAndThen(Collectors.toList(), value -> value)
				));
			
			Map<String, List<JcBillPhoto>> mapPhoto = jcBillService.queryJcBillPhoto(inItem.getBillid());
			
			// 找出对应的来源明细
			List<JcBillSourceItem> tempItems = mapItems.get(inItem.getAccount() + "#" + inItem.getProduct() + "#" + String.valueOf(inItem.getPrice()));
			
			for(JcBillSourceItem item : tempItems) {
				
				// 稽查付款截图
				List<JcBillPhoto> fkts = mapPhoto.get(JcBillPhoto.JC_FK + "#" + String.valueOf(item.getIndexno()));
				if(fkts != null && fkts.size() >= 1) {
					List<String> fkList = new ArrayList<String>();
					
					for(JcBillPhoto fkt : fkts) {
						fkList.add(fkt.getUrlphoto());
					}
					
					item.setPaymentPhoto(fkList);
				}
				
				// 货品图
				List<JcBillPhoto> hpts = mapPhoto.get(JcBillPhoto.JC_HP + "#" + String.valueOf(item.getIndexno()) + "#" + item.getGoodsid());
				if(hpts != null && hpts.size() >= 1) {
					List<String> hpList = new ArrayList<String>();
					
					for(JcBillPhoto hpt : hpts) {
						hpList.add(hpt.getUrlphoto());
					}
					
					item.setGoodsPhotos(hpList);
					item.setHpts(hpts);
				}
			}
			
			
			return tempItems;
		} catch(Throwable e){
			LOG.error(e.getMessage(), e);
			e.printStackTrace();
			throw e;
		}
	}
	
	
	/**
	 * 	TODO 终止回购
	 * @param id
	 * @return
	 * @throws Throwable
	 */
	@RequestMapping(value = "terminateHgInItem", method = RequestMethod.POST)
	public void terminateHgInItem(
			@RequestParam(required = true) String id
		)
	throws Throwable {
		try {
			
			JcBillInItem inItem = jcBillService.queryJcBillInItemById(Long.parseLong(id));
			
			if(inItem == null) throw new BusinessException("回购明细不存在！");
			
			inItem.setStatus(JcBillInItem.STATUS_MINUS_ONE);
			
			jcBillService.saveTerminateHgInItem(inItem);
			
		} catch(Throwable e){
			LOG.error(e.getMessage(), e);
			e.printStackTrace();
			throw e;
		}
	}
	
	/**
	 * 	TODO 修改回购价格
	 * @param id
	 * @return
	 * @throws Throwable
	 */
	@RequestMapping(value = "updateHgprice", method = RequestMethod.POST)
	public JcBillInItem updateHgprice(
			@RequestParam(required = true) String id,
			@RequestParam(required = true) String hgprice
		)
	throws Throwable {
		try {
			
			JcBillInItem inItem = jcBillService.queryJcBillInItemById(Long.parseLong(id));
			if(inItem == null) throw new BusinessException("回购明细不存在！");
			
			inItem.setOldhgprice(inItem.getHgprice());
			
			BigDecimal bigHgprice = new BigDecimal(hgprice);
			
			BigDecimal bigAmount = bigHgprice.multiply(new BigDecimal(String.valueOf(inItem.getQuantity())));
			
			inItem.setHgprice(bigHgprice.doubleValue());
			inItem.setHgamount(bigAmount.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
			
			jcBillService.updateHgprice(inItem);
			
			return inItem;
		} catch(Throwable e){
			LOG.error(e.getMessage(), e);
			e.printStackTrace();
			throw e;
		}
	}
	
	
	/**
	 * 	TODO 回购查询
	 * @param id
	 * @return
	 * @throws Throwable
	 */
	@RequestMapping(value = "queryHg", method = RequestMethod.POST)
	public JSONObject queryHg(
			@RequestParam(required = false) String from,
			@RequestParam(required = false) String thru,
			
			@RequestParam(required = false) String account,
			@RequestParam(required = false) String salearea,
			@RequestParam(required = false) String id,
			@RequestParam(required = false) String billId,
			@RequestParam(required = false) String status,
			@RequestParam(required = false) String product,
			@RequestParam(required = false) String manager,
			@RequestParam(required = true) int typ,
			
			@RequestParam(required = true) int page,
			@RequestParam(required = true) int size
		)
	throws Throwable {
		try {
			
			// 创建起始时间
			String fromDate = null;
			if (StringUtils.isNotBlank(from)) {
				fromDate = DateUtil.formatDateTime(DateUtil.getFromDate(DateUtil.toDate(from)));
			}
			// 创建截止时间
			String thruDate = null;
			if (StringUtils.isNotBlank(thru)) {
				thruDate = DateUtil.formatDateTime(DateUtil.getThruDate(DateUtil.toDate(thru)));
			}
			
			// 当前页
//			int pageNumber = page/size + 1;
			Pageable pageable = PageRequest.of(page - 1, size);
			
			Page<JcBillHg> pages = jcBillService.queryJcBillHg(fromDate, thruDate, account, salearea, id, billId,
					status, product, manager, typ, pageable);
			
			for(JcBillHg hg : pages.getContent()) {
				hg.setAmount(hg.getSubtotal() + hg.getFreight());
			}
			
			JSONObject obj = new JSONObject();
			
			obj.put("list", pages.getContent());
			obj.put("total", pages.getTotalElements());
			
			return obj;
		} catch(Throwable e){
			LOG.error(e.getMessage(), e);
			e.printStackTrace();
			throw e;
		}
	}
	
	
	/**
	 * 	TODO 回购-驳回
	 * 	待提交-->回购通知节点
	 * 	待付款-->待提交，
	 *	已付款-->待付款
	 *	待分仓-->已付款    
	 * @param billId
	 * @param typ 1-回购认款，2-回购分仓
	 * @return
	 */
	@RequestMapping(value = "rejectBillHg", method = RequestMethod.POST)
	public JcBillHg rejectBillHg(
			@RequestParam(required = false) String billHgId,
			@RequestParam(required = false) int status,
			@RequestParam(required = true) int typ
		)
	throws Throwable {
		try {
			
			JcBillHg billHg = jcBillService.queryJcBillHg(billHgId);
			
			if(billHg == null) throw new BusinessException("回购订单不存在！");
			
			List<JcBillInItem> inItems = null;
			JcBill jcBill = null;
			if(JcBillHg.STATUS_ONE == status) {
				
				inItems = jcBillService.queryJcBillInItemByBillId(billHg.getBillid());
				
				if(inItems == null) throw new BusinessException("回购明细不存在！");
				
				// 设置明细状态和回购单号为空
				
				// 是否部分回购
				boolean informFlag = false;
				for(JcBillInItem item : inItems) {
					if(billHgId.equals(item.getBillhg())) {
						item.setStatus(JcBillInItem.STATUS_ONE);
						item.setBillhg(null);
					}
					if(item.getStatus() == JcBillInItem.STATUS_TWO) {
						informFlag = true;
					}
				}
				
				jcBill = jcBillService.queryJcBillById(billHg.getBillid());
				
				if(jcBill == null) throw new BusinessException("收货记录不存在！");
				
				// 稽查收货记录修改状态
//				if(informFlag) jcBill.setStatus(JcBill.STATUS_SIX);
//				else jcBill.setStatus(JcBill.STATUS_FIVE);
				if(informFlag) jcBill.setHgstatus(JcBill.HGSTATUS_ONE);
				else jcBill.setStatus(JcBill.STATUS_FIVE);
				
				billHg.setStatus(JcBillHg.STATUS_MINUS_ONE);
				
			} else if(JcBillHg.STATUS_TWO == status) {
				
				billHg.setStatus(JcBillHg.STATUS_ONE);
				
			} else if(JcBillHg.STATUS_THREE == status || JcBillHg.STATUS_FOUR == status) {
				
				billHg.setStatus(JcBillHg.STATUS_TWO);
				
			} else if(JcBillHg.STATUS_FIVE == status) {
				
				SiDepositlocation sd = jcBillService.querySiDepositlocationHGfc(billHg.getId());
				
				if(sd == null) {// WDT
					throw new BusinessException("该单据需要通知仓库在旺店通删除入库单，并联系信息部撤回。");
				} else {
					if(sd.getPush() == 1) {// WMS
						
						JSONObject obj = jcBillService.gwisSubCancelOrder(billHg.getId(), "B2BCK");
						
						if(obj.getBooleanValue("success")) {
							
							billHg.setStatus(JcBillHg.STATUS_FOUR);
						} else {
							throw new BusinessException(obj.getString("body"));
						}
					} else {
						throw new BusinessException("该单据需要通知仓库在旺店通删除入库单，并联系信息部撤回。");
					}
				}
				
			} else {
				throw new BusinessException("未知状态不能驳回！");
			}
			
			jcBillService.saveRejectBillHg(status, typ, jcBill, billHg, inItems);
			
			billHg.setAmount(billHg.getSubtotal() + billHg.getFreight());
			
			return billHg;
		} catch(Throwable e){
			LOG.error(e.getMessage(), e);
			e.printStackTrace();
			throw e;
		}
	}
	
	/**
	 * 	TODO 确认收款
	 * @param billId
	 * @return
	 */
	@RequestMapping(value = "querenSk", method = RequestMethod.POST)
	public JcBillHg querenSk(
			@RequestParam(required = false) String billHgId
		)
	throws Throwable {
		try {
			
			JcBillHg billHg = jcBillService.queryJcBillHg(billHgId);
			
			if(billHg == null) throw new BusinessException("回购订单不存在！");
			
			String key_jc_wdt_fcflage = getConfigValue(JcConfigKey.KEY_JC_WDT_FCFLAGE);
			boolean fcFlag = Boolean.parseBoolean(key_jc_wdt_fcflage);
			
			if(fcFlag) billHg.setStatus(JcBillHg.STATUS_FIVE);
			else billHg.setStatus(JcBillHg.STATUS_FOUR);
			
			
			jcBillService.saveQuerenSk(billHg, fcFlag);
			
			
			billHg.setAmount(billHg.getSubtotal() + billHg.getFreight());
			
			return billHg;
		} catch(Throwable e){
			LOG.error(e.getMessage(), e);
			e.printStackTrace();
			throw e;
		}
	}
	
	/**
	 * 	TODO 分仓
	 * @param billId
	 * @return
	 */
	@RequestMapping(value = "createFc", method = RequestMethod.POST)
	public JcBillHg createFc(
			@RequestParam(required = false) String billHgId
		)
	throws Throwable {
		try {
			
			JcBillHg billHg = jcBillService.queryJcBillHg(billHgId);
			
			if(billHg == null) throw new BusinessException("回购订单不存在！");
			
			billHg.setStatus(JcBillHg.STATUS_FIVE);
			
			jcBillService.savecreateFc(billHg);
			
			billHg.setAmount(billHg.getSubtotal() + billHg.getFreight());
			
			return billHg;
		} catch(Throwable e){
			LOG.error(e.getMessage(), e);
			e.printStackTrace();
			throw e;
		}
	}
	
	
	/**
	 * 	TODO 修改分仓仓库
	 * @param billId
	 * @return
	 */
	@RequestMapping(value = "updateFcWarehouse", method = RequestMethod.POST)
	public JcBillHg updateFcWarehouse(
			@RequestParam(required = true) String billHgId,
			@RequestParam(required = true) String warehouse,
			@RequestParam(required = true) String warehouseName
		)
	throws Throwable {
		try {
			JcBillHg billHg = jcBillService.queryJcBillHg(billHgId);
			
			if(billHg == null) throw new BusinessException("回购订单不存在！");
			
			// 老对象保存为JSONString
			String oldJsonStr = JSON.toJSONString(billHg);
			
			billHg.setFhwarehouse(warehouse);
			billHg.setFhwarehousename(warehouseName);
			
			jcBillService.updateFcWarehouse(oldJsonStr, billHg);
			
			billHg.setAmount(billHg.getSubtotal() + billHg.getFreight());
			
			return billHg;
		} catch(Throwable e){
			LOG.error(e.getMessage(), e);
			e.printStackTrace();
			throw e;
		}
	}
	
	/**
	 * 	TODO 修改运营备注
	 * @param billId
	 * @return
	 */
	@RequestMapping(value = "updateRemark1", method = RequestMethod.POST)
	public JcBillHg updateRemark1(
			@RequestParam(required = true) String billHgId,
			@RequestParam(required = true) String remark
		)
	throws Throwable {
		try {
			JcBillHg billHg = jcBillService.queryJcBillHg(billHgId);
			
			if(billHg == null) throw new BusinessException("回购订单不存在！");
			
			// 老对象保存为JSONString
			String oldJsonStr = JSON.toJSONString(billHg);
			
			billHg.setRemark1(remark);
			
			jcBillService.updateFcWarehouse(oldJsonStr, billHg);
			
			billHg.setAmount(billHg.getSubtotal() + billHg.getFreight());
			
			return billHg;
		} catch(Throwable e){
			LOG.error(e.getMessage(), e);
			e.printStackTrace();
			throw e;
		}
	}
	
	/**
	 * 	TODO 修改收货地址
	 * @param billId
	 * @return
	 */
	@RequestMapping(value = "updatePac", method = RequestMethod.POST)
	public JcBillHg updatePac(
			@RequestParam(required = true) String billHgId,
			@RequestParam(required = true) String provincename,
			@RequestParam(required = true) String cityname,
			@RequestParam(required = true) String areaname,
			@RequestParam(required = true) String address,
			@RequestParam(required = true) String consignee,
			@RequestParam(required = true) String consigneephone
		)
	throws Throwable {
		try {
			JcBillHg billHg = jcBillService.queryJcBillHg(billHgId);
			
			if(billHg == null) throw new BusinessException("回购订单不存在！");
			
			// 老对象保存为JSONString
			String oldJsonStr = JSON.toJSONString(billHg);
			
			billHg.setProvincename(provincename);
			billHg.setCityname(cityname);
			billHg.setAreaname(areaname);
			billHg.setAddress(address);
			billHg.setConsignee(consignee);
			billHg.setConsigneephone(consigneephone);
			
			jcBillService.updatePac(oldJsonStr, billHg);
			
			billHg.setAmount(billHg.getSubtotal() + billHg.getFreight());
			
			return billHg;
		} catch(Throwable e){
			LOG.error(e.getMessage(), e);
			e.printStackTrace();
			throw e;
		}
	}

	
	// TODO 创建通知函文章
	@RequestMapping(value="createTzh", method = RequestMethod.POST)
	public JSONObject createTzh(
			@RequestParam(required = true) String inItems,
			@RequestParam(required = false) String bzj
	) throws Exception {
		try {
			
			if(StringUtils.isBlank(inItems)) throw new BusinessException("未勾选！");
			
			List<JcBillInItem> items = JSON.parseArray(inItems, JcBillInItem.class);
			
			List<JcBillSourceItem> billItems = jcBillService.queryJcBillSourceItemByBillId(items.get(0).getBillid());
			if(billItems == null) throw new BusinessException("稽查明细不存在！");
			
			if(StringUtils.isBlank(bzj)) bzj = "2、在接到本通知函后一周内，缴纳1万元市场管理保证金，汇入我司对公账户。";
			
			
			return creatTzhObj(items, billItems.get(0), bzj);
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			e.printStackTrace();
			throw e;
		}
	}
	
	/**
	 * 	生成通知函个节点
	 * @param item
	 * @return
	 * @throws Exception
	 */
	private JSONObject creatTzhObj(List<JcBillInItem> items, JcBillSourceItem billItem, String bzj)  throws Exception{
		try {
			JcBillInItem inItem = items.get(0);
			
			JSONObject obj = new JSONObject();
			
			// 客户
			obj.put("account", inItem.getAccount() + inItem.getAccountname());
			
			// 回购单价
			obj.put("hgprice", String.valueOf(inItem.getHgprice()).replace("\\.0*$", ""));
			
			// 年月日
			obj.put("dataz", DateToUpperChinese.getUpperDate(new Date()));
			
			// 收货门店
			Map<String, String> mapChannel = items.stream()
					.collect(Collectors.groupingBy(e -> {
						return e.getChannel();
					}, 
					Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0).getChannel())
				));
			String channelStr = "";
			for(String key : mapChannel.keySet()) {
				if("线上".equals(billItem.getRecsource())) {
					channelStr += billItem.getRecplatform() + key + "、";
				} else {
					channelStr += key + "、";
				}
			}
			obj.put("channel", channelStr.toString().substring(0, channelStr.length() - 1));
			
			// 商品
			Map<String, JcBillInItem> mapPorduct = items.stream()
					.collect(Collectors.groupingBy(e -> {
						return e.getProduct() + String.valueOf(e.getPrice());
					}, 
					Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0))
				));
			
			double numbers = 0;
			StringBuffer productStr = new StringBuffer();
			for(String key : mapPorduct.keySet()) {
				JcBillInItem productItem = mapPorduct.get(key);
				BigDecimal price = new BigDecimal(String.valueOf(productItem.getPrice()));
//				BigDecimal amount = price.multiply(new BigDecimal(String.valueOf(productItem.getQuantity()))).setScale(2, BigDecimal.ROUND_HALF_UP);
//				
//				BigDecimal numPrice = amount.divide(new BigDecimal(String.valueOf(productItem.getNumbers())), 4, BigDecimal.ROUND_HALF_UP).setScale(4, BigDecimal.ROUND_HALF_UP);
//			
//				LOG.info(removeZeros(String.valueOf(numPrice.doubleValue())));
				
//				productStr.append("收货价格" + removeZeros(String.valueOf(price.doubleValue())) + "元/瓶、");
				
//				numbers += productItem.getNumbers();
				
				numbers += productItem.getQuantity();
			}
			obj.put("product", inItem.getProductname());
//			obj.put("product", inItem.getProductname() + "，" + productStr.toString().substring(0, productStr.length() - 1));
			
			// 件数
			obj.put("numbers", numbers);
			
			// 支付方式-打款信息
			Map<String, String> offlineMaps = getConfigSet(JcConfigKey.KEY_GROUP, JcConfigKey.KEY_JC_PAYMENT_OFFLINE);
			
			obj.put("dkxx", offlineMaps.get("zhmc") + "、" + offlineMaps.get("khyh") + "、" + offlineMaps.get("yhzh"));
			
			// 保证金
			obj.put("bzj", bzj);
			
			return obj;
		} catch(Throwable e){
			LOG.error(e.getMessage(), e);
			e.printStackTrace();
			throw e;
		}
	}
	
	/**
	 * 	去掉小数位0的数字
	 * @param str
	 * @return
	 */
	private String removeZeros(String str) {
		if(str.indexOf(".") > 0) {
        	str = str.replace("0+?$", "");// 删除掉尾数为0的字符
        	str = str.replace("[.]$", "");// 结尾如果是小数点，则去掉
        }
		return str;
	}
	
}












