package abacus.springboot.example.esb;

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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.abacus.xpos.foundation.dao.Employee;
import com.abacus.xpos.foundation.pubs.DaoIdGenerator;
import com.abacus.xpos.foundation.wsi.EmployeeServiceIF;
import com.alibaba.fastjson.JSON;

import abacus.commons.exception.BusinessException;
import abacus.springboot.example.api.view.ApiReqJcBill;
import abacus.springboot.example.api.view.ApiReqJcBillGoodsPhoto;
import abacus.springboot.example.api.view.ApiReqJcBillItem;
import abacus.springboot.example.api.view.ApiRespJcPorduct;
import abacus.springboot.example.api.view.ApiRespJcPorductAcount;
import abacus.springboot.example.api.view.ApiRespJcPorductItem;
import abacus.springboot.example.api.view.ApiRespJcPorductProduct;
import abacus.springboot.example.api.view.JcProduct;
import abacus.springboot.example.api.view.JcProductBillSouce;
import abacus.springboot.example.dao.JcBill;
import abacus.springboot.example.dao.JcBillPhoto;
import abacus.springboot.example.dao.JcBillSourceItem;
import abacus.springboot.example.wsi.ApiJcBillServiceIF;

/**
 * <p>Title:JcBillBizService</p>
   <p>Description: 稽查单业务编排（原内聚于 Controller 的私有方法，按 5 层 DAG 下沉到 esb）</p>
   @author chuanZeng 
   @date 2026年8月18日
 */
@Service
public class JcBillBizService {

	private static final Logger LOG = LoggerFactory.getLogger(JcBillBizService.class);
	
	@Autowired
	private ApiJcBillServiceIF apiJcBillService;
	
	@Autowired
	private DaoIdGenerator jcBillIdGenerator;
	
	@Autowired
	private EmployeeServiceIF employeeService;

	/**
	 * 稽查收货主单保存逻辑
	 * @param reqJcBill
	 * @throws Exception
	 */
	public void saveJcBill(ApiReqJcBill reqJcBill) throws Exception{
		try {
			
			// 稽查单号
			String billId = jcBillIdGenerator.takeDaoId(null);
			
			reqJcBill.setId(billId);
			
			// 明细
			List<ApiReqJcBillItem> items = reqJcBill.getItems();
			
			// 解析明细
			// 新增明细
			List<JcBillSourceItem> createItems = new ArrayList<JcBillSourceItem>();
			
			// 汇总数量
			BigDecimal quantityBig = new BigDecimal("0");
			// 汇总金额
			BigDecimal subtotalBig = new BigDecimal("0");
			
			if(items != null && items.size() >= 1) {
				int indexno = 0;
				for(ApiReqJcBillItem item : items) {
					
					Double quantity = item.getQuantity();
					if(quantity == null) throw new BusinessException("收货数量为空！");
					if(quantity <= 0) throw new BusinessException("收货数量不能小于等于0！");
					
					Double numbers = item.getNumbers();
					if(numbers == null) throw new BusinessException("收货件数为空！");
					if(numbers <= 0) throw new BusinessException("收货件数不能小于等于0！");
					
					Double price = item.getPrice();
					if(price == null) throw new BusinessException("价格为空！");
					if(price <= 0) throw new BusinessException("价格不能小于等于0！");
					
					Double subtotal = item.getSubtotal();
					if(subtotal == null) throw new BusinessException("金额为空！");
					if(subtotal <= 0) throw new BusinessException("金额不能小于等于0！");
						
					item.setIndexno(++indexno);
					createItems.addAll(saveJcBillItem(billId, item));
					
					if(item.getQuantity() != null ) quantityBig = quantityBig.add(new BigDecimal(String.valueOf(item.getQuantity())));
					
					if(item.getSubtotal() != null ) subtotalBig = subtotalBig.add(new BigDecimal(String.valueOf(item.getSubtotal())));
				}
			}
			
			
			Employee emp = employeeService.getEmployee(reqJcBill.getApplicant());
			if(emp == null) throw new BusinessException("申请人不存在！");
			
			// 主单对象
			JcBill jcBill = new JcBill();
			jcBill.setId(billId);
			jcBill.setStatus(JcBill.STATUS_ZERO);
			jcBill.setGoods(reqJcBill.getGoods());
			jcBill.setWarehouse(reqJcBill.getWarehouse());
			jcBill.setWarehousename(reqJcBill.getWarehousename());
			jcBill.setReceivedt(reqJcBill.getReceivedt());
			jcBill.setQuantity(quantityBig.doubleValue());
			jcBill.setSubtotal(subtotalBig.doubleValue());
			jcBill.setApplicant(reqJcBill.getApplicant());
			jcBill.setApplicantname(reqJcBill.getApplicantname());
			jcBill.setDept(emp.getDept().getId());
			jcBill.setApplicantdt(new Date());
			
			apiJcBillService.saveApiReqJcBill(reqJcBill, jcBill, createItems);
		} catch(Throwable e){
			LOG.error(e.getMessage(), e);
			e.printStackTrace();
			throw e;
		}
	}

	/**
	 * 稽查收货明细保存逻辑
	 * @param item
	 * @return
	 * @throws Exception
	 */
	public List<JcBillSourceItem> saveJcBillItem(String billId, ApiReqJcBillItem item) throws Exception{
		try {
			BigDecimal numbersBig = new BigDecimal(String.valueOf(item.getNumbers()));
			BigDecimal qunantiyBig = new BigDecimal(String.valueOf(item.getQuantity()));
			BigDecimal bigprice = new BigDecimal(String.valueOf(item.getPrice()));
			
			// 余数
			double yus = item.getQuantity() % item.getNumbers();
			
			// 瓶数
			BigDecimal qunantiyInt = qunantiyBig.divide(numbersBig, BigDecimal.ROUND_DOWN).setScale(0, BigDecimal.ROUND_DOWN);
			
			// 金额
			BigDecimal bigAmount = bigprice.multiply(new BigDecimal(String.valueOf(item.getQuantity())));
			double subtotal = bigAmount.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
			
			List<JcBillSourceItem> sourceItems = new ArrayList<JcBillSourceItem>();
			JcBillSourceItem sourceItem = null;
			for(int i = 0; i < item.getGoodsPhotos().size(); i++) {
				
				ApiReqJcBillGoodsPhoto photo = item.getGoodsPhotos().get(i);
				
				sourceItem = new JcBillSourceItem();
				sourceItem.setBillid(billId);
				sourceItem.setIndexno(item.getIndexno());
				sourceItem.setStatus(0);
				sourceItem.setRecsource(item.getRecsource());
				sourceItem.setRecplatform(item.getRecplatform());
				sourceItem.setChannel(item.getChannel());
				sourceItem.setPrice(item.getPrice());
				
				if(i == (item.getGoodsPhotos().size() - 1)) {
					sourceItem.setQuantity(qunantiyInt.doubleValue() + yus);
				} else {
					sourceItem.setQuantity(qunantiyInt.doubleValue());
				}
				
				sourceItem.setNumbers(1);
				sourceItem.setSubtotal(subtotal);
				
				sourceItem.setGoodsid(photo.getGoodsid());
				sourceItem.setLogisticsid(photo.getLogisticsid());
				sourceItems.add(sourceItem);
			}
			return sourceItems;
		} catch(Throwable e){
			LOG.error(e.getMessage(), e);
			e.printStackTrace();
			throw e;
		}
	}

	/**
	 * 稽查收货主单修改逻辑
	 * @param reqJcBill
	 * @throws Exception
	 */
	public void updateJcbill(ApiReqJcBill reqJcBill) throws Exception{
		try {
			
			// 稽查单号
			String billId = reqJcBill.getId();
			
			// 明细
			List<ApiReqJcBillItem> items = reqJcBill.getItems();
			
			// 解析明细
			// 新增明细
			List<JcBillSourceItem> createItems = new ArrayList<JcBillSourceItem>();
			// 修改明细
			List<JcBillSourceItem> updateItems = new ArrayList<JcBillSourceItem>();
			
			// 汇总数量
			BigDecimal quantityBig = new BigDecimal("0");
			// 汇总金额
			BigDecimal subtotalBig = new BigDecimal("0");
			
			/*if(items != null && items.size() >= 1) {
				int indexno = apiJcBillService.countJcBillItemIndexno(billId);
				for(ApiReqJcBillItem item : items) {
					if(item.getId() == null) {
						
						item.setIndexno(++indexno);
						createItems.addAll(saveJcBillItem(billId, item));
					} else {
						
						updateItems.addAll(updateJcbillItem(billId, item));
					}
					
					if(item.getQuantity() != null ) quantityBig = quantityBig.add(new BigDecimal(String.valueOf(item.getQuantity())));
					
					if(item.getSubtotal() != null ) subtotalBig = subtotalBig.add(new BigDecimal(String.valueOf(item.getSubtotal())));
				}
			}*/
			if(items != null && items.size() >= 1) {
				int indexno = 0;
				for(ApiReqJcBillItem item : items) {
					
					Double quantity = item.getQuantity();
					if(quantity == null) throw new BusinessException("收货数量为空！");
					if(quantity <= 0) throw new BusinessException("收货数量不能小于等于0！");
					
					Double numbers = item.getNumbers();
					if(numbers == null) throw new BusinessException("收货件数为空！");
					if(numbers <= 0) throw new BusinessException("收货件数不能小于等于0！");
					
					Double price = item.getPrice();
					if(price == null) throw new BusinessException("价格为空！");
					if(price <= 0) throw new BusinessException("价格不能小于等于0！");
					
					Double subtotal = item.getSubtotal();
					if(subtotal == null) throw new BusinessException("金额为空！");
					if(subtotal <= 0) throw new BusinessException("金额不能小于等于0！");
						
					item.setIndexno(++indexno);
					createItems.addAll(saveJcBillItem(billId, item));
					
					if(item.getQuantity() != null ) quantityBig = quantityBig.add(new BigDecimal(String.valueOf(item.getQuantity())));
					
					if(item.getSubtotal() != null ) subtotalBig = subtotalBig.add(new BigDecimal(String.valueOf(item.getSubtotal())));
				}
			}
			
			
			Employee emp = employeeService.getEmployee(reqJcBill.getApplicant());
			if(emp == null) throw new BusinessException("申请人不存在！");
			
			// 主单对象
			JcBill jcBill = new JcBill();
			jcBill.setId(reqJcBill.getId());
			jcBill.setStatus(JcBill.STATUS_ZERO);
			jcBill.setGoods(reqJcBill.getGoods());
			jcBill.setWarehouse(reqJcBill.getWarehouse());
			jcBill.setWarehousename(reqJcBill.getWarehousename());
			jcBill.setReceivedt(reqJcBill.getReceivedt());
			jcBill.setQuantity(quantityBig.doubleValue());
			jcBill.setSubtotal(subtotalBig.doubleValue());
			jcBill.setApplicant(reqJcBill.getApplicant());
			jcBill.setApplicantname(reqJcBill.getApplicantname());
			jcBill.setDept(emp.getDept().getId());
			jcBill.setApplicantdt(new Date());
			
			apiJcBillService.updateApiReqJcBill(reqJcBill, jcBill, createItems, updateItems);
			
		} catch(Throwable e){
			LOG.error(e.getMessage(), e);
			e.printStackTrace();
			throw e;
		}
	}

	/**
	 * 稽查收货明细修改逻辑
	 * @param item
	 * @return
	 * @throws Exception
	 */
	public List<JcBillSourceItem> updateJcbillItem(String billId, ApiReqJcBillItem item) throws Exception{
		try {
			BigDecimal numbersBig = new BigDecimal(String.valueOf(item.getNumbers()));
			BigDecimal qunantiyBig = new BigDecimal(String.valueOf(item.getQuantity()));
			BigDecimal bigprice = new BigDecimal(String.valueOf(item.getPrice()));
			
			// 余数
			double yus = item.getQuantity() % item.getNumbers();
			
			// 瓶数
			BigDecimal qunantiyInt = qunantiyBig.divide(numbersBig, BigDecimal.ROUND_DOWN).setScale(0, BigDecimal.ROUND_DOWN);
			
			// 金额
			BigDecimal bigAmount = bigprice.multiply(new BigDecimal(String.valueOf(item.getQuantity())));
			double subtotal = bigAmount.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
			
			List<JcBillSourceItem> sourceItems = new ArrayList<JcBillSourceItem>();
			JcBillSourceItem sourceItem = null;
			for(int i = 0; i < item.getGoodsPhotos().size(); i++) {
				
				ApiReqJcBillGoodsPhoto photo = item.getGoodsPhotos().get(i);
				
				sourceItem = new JcBillSourceItem();
				sourceItem.setId(item.getId());
				sourceItem.setBillid(billId);
				sourceItem.setIndexno(item.getIndexno());
				sourceItem.setStatus(0);
				sourceItem.setRecsource(item.getRecsource());
				sourceItem.setRecplatform(item.getRecplatform());
				sourceItem.setChannel(item.getChannel());
				sourceItem.setPrice(item.getPrice());
				
				if(i == (item.getGoodsPhotos().size() - 1)) {
					sourceItem.setQuantity(qunantiyInt.doubleValue() + yus);
				} else {
					sourceItem.setQuantity(qunantiyInt.doubleValue());
				}
				
				sourceItem.setNumbers(1);
				sourceItem.setSubtotal(subtotal);
				
				sourceItem.setGoodsid(photo.getGoodsid());
				sourceItem.setLogisticsid(photo.getLogisticsid());
				sourceItems.add(sourceItem);
			}
			return sourceItems;
			
//			JcBillSourceItem sourceItem = new JcBillSourceItem();
//			sourceItem.setId(item.getId());
//			sourceItem.setBillid(billId);
//			sourceItem.setIndexno(item.getIndexno());
//			sourceItem.setStatus(1);
//			sourceItem.setRecsource(sourceItem.getRecsource());
//			sourceItem.setRecplatform(sourceItem.getRecplatform());
//			sourceItem.setChannel(sourceItem.getChannel());
//			sourceItem.setPrice(sourceItem.getPrice());
//			sourceItem.setQuantity(sourceItem.getQuantity());
//			sourceItem.setNumbers(sourceItem.getNumbers());
//			sourceItem.setSubtotal(sourceItem.getSubtotal());
//			sourceItem.setGoodsid(sourceItem.getGoodsid());
//			sourceItem.setLogisticsid(sourceItem.getLogisticsid());
//			
//			return sourceItem;
		} catch(Throwable e){
			LOG.error(e.getMessage(), e);
			e.printStackTrace();
			throw e;
		}
	}

	/**
	 * 回购单号是按回购单显示明细，以回购单号为主，解析
	 * @param product
	 * @param stockInId
	 * @param hgId
	 * @return
	 * @throws Exception
	 */
	public List<ApiRespJcPorduct> hgAnalyze(String product, String stockInId, String hgId) throws Exception {
		try {
			
			long time1 = System.currentTimeMillis();
			List<JcProduct> jcProducts = apiJcBillService.queryJcProduct(product, stockInId, hgId);
			LOG.info("稽查货品查询>>>回购单逻辑>>>queryJcProduct耗时>>>{}", (System.currentTimeMillis() - time1));
			
			// 获取稽查单号集合
	        List<String> billIds = jcProducts.stream()
                    .map(JcProduct::getBillid) 
                    .collect(Collectors.toList());
			
        long time2 = System.currentTimeMillis();
        Map<String, List<JcProductBillSouce>> mapGoods = apiJcBillService.queryJcProductBillSouce(billIds);
        LOG.info("稽查货品查询>>>回购单逻辑>>>queryJcProductBillSouce耗时>>>{}", (System.currentTimeMillis() - time2));
        
			LOG.info("稽查货品查询>>>回购单逻辑>>>按稽查单号+客户编码+商品编码，分组数据>>>{}", JSON.toJSONString(mapGoods));

        
        long time3 = System.currentTimeMillis();
        Map<String, List<JcBillPhoto>> mapPhoto = apiJcBillService.queryJcBillPhotoIn(billIds);
			LOG.info("稽查货品查询>>>回购单逻辑>>>queryJcBillPhotoIn查询耗时>>>{}", (System.currentTimeMillis() - time3));
        
			// 按稽查单号+入库单号+回购单号+出库单号,分组
			Map<String, List<JcProduct>> mapProducts = jcProducts.stream()
					.collect(Collectors.groupingBy(e -> {
						return e.getBillid() + e.getBillin() + e.getBillhg() + e.getWdtbillout();
					}, 
					Collectors.collectingAndThen(Collectors.toList(), value -> value)
				));
			LOG.info("稽查货品查询>>>回购单逻辑>>>按稽查单号+入库单号+回购单号+出库单号,分组数据>>>{}", JSON.toJSONString(mapProducts));
			
    		// 客户编码汇总，同一个客户下的商品
			Map<String, List<JcProduct>> mapAccProducts = jcProducts.stream()
					.collect(Collectors.groupingBy(e -> {
						return e.getBillid() + e.getBillin() + e.getBillhg()+ e.getAccount();
					}, 
					Collectors.collectingAndThen(Collectors.toList(), value -> value)
				));
			LOG.info("稽查货品查询>>>回购单逻辑>>>按稽查单号+入库单号+回购单号+客户编码，分组数据>>>{}", JSON.toJSONString(mapAccProducts));

			
			long time4 = System.currentTimeMillis();
			List<ApiRespJcPorduct> respJcProducts = new ArrayList<ApiRespJcPorduct>();
			ApiRespJcPorduct respJcProduct = null;
	        for(String key : mapProducts.keySet()) {
	        	
	        	List<JcProduct> tempJcProducts = mapProducts.get(key);
	        	
	        	JcProduct jcProduct = tempJcProducts.get(0);
	        	
	        	respJcProduct = new ApiRespJcPorduct();
	        	if(jcProduct.getBillid() != null) respJcProduct.setBillId(jcProduct.getBillid());
	        	if(jcProduct.getBillin() != null) respJcProduct.setStockInId(jcProduct.getBillin());
	        	if(jcProduct.getBillhg() != null) respJcProduct.setHgId(jcProduct.getBillhg());
	        	if(jcProduct.getWdtbillout() != null) respJcProduct.setStockOutId(jcProduct.getWdtbillout());
	        	
	        	List<ApiRespJcPorductAcount> accounts = new ArrayList<ApiRespJcPorductAcount>();
				ApiRespJcPorductAcount account = null;
	        	for(JcProduct tempJcProduct : tempJcProducts) {
	        		
	        		account = new ApiRespJcPorductAcount();
		        	account.setAccount(tempJcProduct.getAccount());
	        		account.setAccountName(tempJcProduct.getAccountname());
	        		
					String keyAccount = tempJcProduct.getBillid() + tempJcProduct.getBillin() + tempJcProduct.getBillhg() +tempJcProduct.getAccount();
					
					List<JcProduct> accTempJcProducts = mapAccProducts.get(keyAccount);
					
					LOG.info("稽查货品查询>>>回购单逻辑>>>按稽查单号+入库单号+回购单号+客户编码({})，汇总同一客户数据>>>{}", keyAccount, JSON.toJSONString(accTempJcProducts));
					
					List<ApiRespJcPorductProduct> products = new ArrayList<ApiRespJcPorductProduct>(); 
	        		ApiRespJcPorductProduct ajproduct = null;
					for(JcProduct accJcProduct : accTempJcProducts) {
						
						ajproduct = new ApiRespJcPorductProduct();
	        			ajproduct.setProduct(tempJcProduct.getProduct());
	        			ajproduct.setProductName(tempJcProduct.getProductname());
	        			ajproduct.setQuantity(tempJcProduct.getQuantity() + "瓶/" + tempJcProduct.getNumbers() + "件");
						
						
						
	        			String keyGoods = accJcProduct.getBillid() + accJcProduct.getAccount() + accJcProduct.getProduct();
	        			
	        			List<JcProductBillSouce> tempGoods = mapGoods.get(keyGoods);
	        			
	        			LOG.info("稽查货品查询>>>回购单逻辑>>>按稽查单号+客户编码+商品编码({})，分组数据>>>{}", keyGoods, JSON.toJSONString(tempGoods));
	        			
						List<ApiRespJcPorductItem> items = new ArrayList<ApiRespJcPorductItem>(); 
						ApiRespJcPorductItem item = null;
						for(JcProductBillSouce tempGood : tempGoods) {
							item = new ApiRespJcPorductItem();
							item.setGoodsId(tempGood.getGoodsid());
							
							List<JcBillPhoto> hpts = mapPhoto.get(JcBillPhoto.JC_HP + "#" + String.valueOf(tempGood.getIndexno()) + "#" + String.valueOf(tempGood.getGoodsid()));
							List<String> hptList = new ArrayList<String>();
							if(hpts != null && hpts.size() >= 1) {
								for(JcBillPhoto hpt : hpts) {
									if(tempGood.getBillid().equals(hpt.getSrcid())) {
										hptList.add(hpt.getUrlphoto());
									}
								}
							}
							item.setPhotos(hptList);
							
							items.add(item);
							/*if(StringUtils.isBlank(product)) {
								item = new ApiRespJcPorductItem();
								item.setGoodsId(tempGood.getGoodsid());
								
								List<JcBillPhoto> hpts = mapPhoto.get(JcBillPhoto.JC_HP + "#" + String.valueOf(tempGood.getIndexno()) + "#" + String.valueOf(tempGood.getGoodsid()));
								List<String> hptList = new ArrayList<String>();
								if(hpts != null && hpts.size() >= 1) {
									for(JcBillPhoto hpt : hpts) {
										hptList.add(hpt.getUrlphoto());
									}
								}
								item.setPhotos(hptList);
								
								items.add(item);
							} else {
								if(product.equals(tempGood.getGoodsid())) {
									item = new ApiRespJcPorductItem();
									item.setGoodsId(tempGood.getGoodsid());
									
									List<JcBillPhoto> hpts = mapPhoto.get(JcBillPhoto.JC_HP + "#" + String.valueOf(tempGood.getIndexno()) + "#" + String.valueOf(tempGood.getGoodsid()));
									List<String> hptList = new ArrayList<String>();
									if(hpts != null && hpts.size() >= 1) {
										for(JcBillPhoto hpt : hpts) {
											hptList.add(hpt.getUrlphoto());
										}
									}
									item.setPhotos(hptList);
									
									items.add(item);
								}
							}*/
							
						}
							
						if(items.size() >= 1) {
							ajproduct.setItems(items);
							
							products.add(ajproduct);
						}
					}
					
					if(products.size() >= 1) {
	        			account.setProducts(products);
		        	
		        		accounts.add(account);
	        		}
	        	}
	        	
				if(accounts.size() >= 1) {
					respJcProduct.setAccounts(accounts);
		        	
		        	respJcProducts.add(respJcProduct);
				}
	        }
	        LOG.info("稽查货品查询>>>回购单逻辑>>>数据封装耗时>>>{}", (System.currentTimeMillis() - time4));
			
	        return respJcProducts;
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			e.printStackTrace();
			throw e;
		}
	}

}
