package nccloud.api.so.so.UpCloses;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.HashSet;
import java.util.Set;
import java.util.TimeZone;
import java.util.Arrays;


import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import nc.bs.framework.common.NCLocator;
import nc.impl.pubapp.pattern.data.bill.BillQuery;
import nc.itf.uap.IUAPQueryBS;
import nc.jdbc.framework.processor.ArrayListProcessor;


import nc.jdbc.framework.processor.MapProcessor;
import nc.vo.mmpac.pickm.entity.AggPickmVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFDateTime;
import nc.vo.so.m30.entity.SaleOrderViewVO;
import nccloud.api.rest.utils.ResultMessageUtil;
import nccloud.dto.mmpac.pickm.pub.entity.PickmDeleteInfo;
import nccloud.pubitf.so.saleorderclose.utils.SaleOrderCloseUtils;
import nccloud.util.so.TransBillUtil;


import nccloud.ws.rest.resource.AbstractNCCRestResource;
import org.json.JSONString;
import nc.bs.dao.BaseDAO;

import nccloud.pubitf.so.saleorderclose.service.IQuerySaleOrderCloseService;

import nc.itf.mmpac.pickm.IPickmMaintainService;


@Path("so/so/UpCloses")
public class ClosesoUpdateBL extends AbstractNCCRestResource {

    @Override
    public String getModule() {
        return "so";
    }

    // 用于存储手工维护的必填字段和字段说明
    private Map<String, String> requiredFields;

    // 构造方法，初始化必填字段及其说明
    public ClosesoUpdateBL() {
        // 初始化必填字段列表及字段说明
        requiredFields = new HashMap<>();
        requiredFields.put("pk_org", "业务单元");
        requiredFields.put("array.vbillcode", "单据编号");
        requiredFields.put("array.crowno", "行号");
        requiredFields.put("array.sendQty", "发货数量");
    }

    @POST
    @Path("/ClosesoUpdateBL")
    @Consumes({"application/json"})
    @Produces({"application/json"})
/**
 * 关闭销售订单
 * 该方法接收一个JSON字符串作为输入，解析并验证其中的数据，然后根据操作类型关闭相应的销售订单
 *
 * @param json 包含销售订单信息和操作类型的JSON字符串
 * @return 返回一个JSON字符串，表示操作结果
 */
public JSONString ClosesoUpdateBL(JSONString json) {
        JSONObject errojson = new JSONObject();
        Set<String> vbillcodes = new HashSet<>();
        Set<String> billcodes = new HashSet<>();
        // 创建map 9-冻结； 10-办结； 11-终止； 8：生效(取消冻结)
        Map<String, String> operationMap = new HashMap<>();

        try {
            ArrayList<String> bidsList = new ArrayList<>();
            operationMap.put("9", "冻结");
            operationMap.put("10", "办结");
            operationMap.put("11", "终止");
            operationMap.put("8", "生效");
            // 将输入的JSON字符串解析为JSONObject
            JSONObject jObject = JSON.parseObject(json.toJSONString());
            if (jObject == null) {
                return ResultMessageUtil.exceptionToJSON(new NullPointerException("JSONString:null"));
            }
            String operation = (String) jObject.getOrDefault("operation", "");
            String pk_org = null;
//            operation="9";
            // 从解析的JSON对象中获取必要的字段
            JSONArray array = jObject.getJSONArray("array");

            // 循环 array 取值
            String updateSql = null;
            String def1=operationMap.get(operation.toString());
            if (def1 == null){
                return ResultMessageUtil.exceptionToJSON(new NullPointerException("操作类型不存在"));
            }
            String operationSql = " SELECT bd.pk_defdoc ID from bd_defdoc bd " +
                    "LEFT join bd_defdoclist bdl ON bd.pk_defdoclist=bdl.pk_defdoclist WHERE bdl.code ='HTZT' AND bd.code = '" + operation.toString()  + "' ";
//            List<Map<String,Object>> operationresult = (List<Map<String,Object>>) getQueryService().executeQuery(operationSql, new ArrayListProcessor());
            Map<String, Object> valList = (Map<String, Object>) getQueryService().executeQuery(operationSql, new MapProcessor());
//            if (operationresult == null || operationresult.size() == 0) {
//                errojson.put("status", "0");
//                errojson.put("message", "操作类型不存在");
//                errojson.put("codeList", null);
//                // 返回表示操作成功的JSON字符串
//                return ResultMessageUtil.toJSON(errojson);
//            }
            String operationId = null;
//            // 循环result取csaleorderbid与ts生成"1001A11000000B0OJ2HI,2024-12-02 10:16:10"这种样式插入bidsList
//            for (Map<String,Object> row : operationresult) {
//                operationId = (String) row.get("bd.pk_defdoc");
//            }
            operationId = (String) valList.get("id");
            if (operationId == null) {
                errojson.put("status", "0");
                errojson.put("message", "操作类型不存在");
                errojson.put("codeList", null);
                // 返回表示操作成功的JSON字符串
                return ResultMessageUtil.toJSON(errojson);
            }
            for (int i = 0; i < array.size(); i++) {
                Map item = (Map) array.get(i);
                String vctcode = (String) item.getOrDefault("vctcode", "");
                updateSql = "   UPDATE so_saleorder h" +
                        "   SET h.vdef1 = '" + operationId + "' "+
                        "   WHERE EXISTS (" +
                        "       SELECT 1" +
                        "       FROM  bd_defdoc hbd  "+
                        "       WHERE hbd.pk_defdoc=h.VDEF6" +
                        "       AND hbd.code = '" + vctcode + "' " +
                        "   );";

//                updateSql = "   UPDATE so_saleorder h" +
//                        "   SET h.vdef19 = '" + json.toJSONString()  + "' " +
//                        "   WHERE h.vdef6 = '" + "ZKWEQ0400425" + "' " + "   ;";
//                updateSql = "   UPDATE so_saleorder h" +
//                        "   SET h.vdef1 = '" + operationId + "' , h.vdef19 =  '"+json.toJSONString()  +"'  '"+
//                        "   WHERE h.vdef6 =  '" + result.get(0)[0]+ "' " + "   ;";
                // 验证operation字段是否存在
                if (vctcode == null) {
                    return ResultMessageUtil.exceptionToJSON(new NullPointerException("vctcode:null"));
                }
                // 根据组织ID和销售订单代码获取销售订单的唯一标识
                String sql = " select  h.csaleorderid,b.csaleorderbid,h.ts,hbd.code as vbillcode,o.code as pk_org,h.vbillcode as billcode from so_saleorder h  "
                        + "left join so_saleorder_b b on h.csaleorderid=b.csaleorderid "
                        + "left join org_salesorg o on h.pk_org=o.pk_salesorg "
                +" left join bd_defdoc hbd on hbd.pk_defdoc=h.VDEF6 "+

                         "where hbd.code='" + vctcode + "' ";
                List<Object[]> result = (List<Object[]>) getQueryService().executeQuery(sql, new ArrayListProcessor());
                if (result == null || result.size() == 0) {
                    errojson.put("status", "0");
                    errojson.put("message", "查询无此合同号");
                    errojson.put("codeList", null);

                    // 返回表示操作成功的JSON字符串
                    return ResultMessageUtil.toJSON(errojson);
                 }

                // 循环result取csaleorderbid与ts生成"1001A11000000B0OJ2HI,2024-12-02 10:16:10"这种样式插入bidsList
                for (Object[] row : result) {
                    String csaleorderbid = (String) row[1];
                    String ts = (String) row[2];
                    bidsList.add(csaleorderbid + "," + ts);
                    String vbillcode = (String) row[3];
                    String billcode = (String) row[5];
                    if (vbillcode != null) {
                        pk_org=(String)row[4];
                        vbillcodes.add(vbillcode);
                        billcodes.add(billcode);
                    }
                }
            }
            // 使用 ArrayList 存储 PickmDeleteInfo 对象
            ArrayList<PickmDeleteInfo> pickmDeleteInfoList = new ArrayList<>();
            for (String vbillcode : vbillcodes) {
//                String vsql = "select cpickmid,ts from mm_pickm where vbillcode='" + vbillcode + "'";
                String vsql = "select mm.cpickmid,mm.ts,hbd.code as vbillcode,mm.pk_org,hbd.code as vctcode from mm_pickm mm " +
                        " left join org_salesorg o on mm.pk_org=o.pk_salesorg " +
                        " left join bd_defdoc hbd on hbd.pk_defdoc=mm.vdef6" +
                        " where hbd.code='"+vbillcode+"'";

                List<Object[]> vresult = (List<Object[]>) getQueryService().executeQuery(vsql, new ArrayListProcessor());
                for (Object[] row : vresult) {
                    String csaleorderbid = (String) row[0];
                    String ts = (String) row[1];
                    // 创建 PickmDeleteInfo 对象并设置其属性
                    PickmDeleteInfo info = new PickmDeleteInfo();
                    info.setPks(csaleorderbid);
                    info.setTs(new UFDateTime(ts, TimeZone.getTimeZone("Asia/Shanghai")));
                    // 将 PickmDeleteInfo 对象添加到列表中
                    pickmDeleteInfoList.add(info);
                }
            }

// 将 ArrayList 转换为数组
            PickmDeleteInfo[] pickmDeleteInfos = pickmDeleteInfoList.toArray(new PickmDeleteInfo[0]);



            IPickmMaintainService context = (IPickmMaintainService) NCLocator.getInstance().lookup(IPickmMaintainService.class.getName());
            AggPickmVO[] aggVOs = getAggPickmVOs(pickmDeleteInfos);
            String ret2 = "";

//            9-冻结； 10-办结； 11-终止； 8：生效(取消冻结)

            String ret;
            // 根据操作类型执行相应的服务方法
            if (operation.equals("9")) {
                // 执行关闭操作
                // 如果pickmDeleteInfoList不为空执行执行ret2 = Arrays.toString(context.finishPickm(aggVOs));
                 if (aggVOs.length>0){
                     ret2 = Arrays.toString(context.finishPickm(aggVOs));

                 }
            } else if (operation.equals("8")) {
                // 执行开启操作
                if (aggVOs.length>0){
                    ret2 = Arrays.toString(context.unfinishPickm(aggVOs));

                }
            } else if (operation.equals("11")) {
                // 执行开启操作
                if (aggVOs.length>0) {
                    ret2 = Arrays.toString(context.unfinishPickm(aggVOs));
                }
            }


            int succState = updateSaleBSQty(updateSql.toString());

            for (String vbillcode : billcodes){
                // 更新流程生产订单
                String updateSql1 = "   UPDATE mm_mo h" +
                        "   SET h.vdef5 = '" + operationId + "' "+
                        "   WHERE  h.vsrccode = '" + vbillcode + "' " +
                        "   ;";
                updateSaleBSQty(updateSql1.toString());
            }
            // 如果操作成功，设置错误JSON对象的code为0，表示成功
            errojson.put("status", "1");
            errojson.put("message", "销售订单状态修改了"+succState+"条，"+ret2);
            errojson.put("codeList", vbillcodes);

            // 返回表示操作成功的JSON字符串
            return ResultMessageUtil.toJSON(errojson);

        } catch (Exception e) {
            errojson.put("status", "0");
            errojson.put("message", e.getMessage());
            errojson.put("codeList", vbillcodes);
            // 返回表示操作失败的JSON字符串
            return ResultMessageUtil.toJSON(errojson);
     }
}
    /**
     * 根据删除信息获取对应的AggPickmVO对象数组
     * 此方法用于根据PickmDeleteInfo数组中的信息，查询并构建AggPickmVO对象数组
     * 它首先提取删除信息中的主键和时间戳，然后根据主键查询对应的AggPickmVO对象，
     * 并将时间戳信息添加到查询到的对象中
     *
     * @param deleteinfo 包含删除信息的数组，用于获取被删除记录的主键和时间戳
     * @return 返回查询到的AggPickmVO对象数组，如果未找到则可能返回null或空数组
     */
    private AggPickmVO[] getAggPickmVOs(PickmDeleteInfo[] deleteinfo) {
        // 初始化一个字符串数组，用于存储删除信息的主键
        String[] pks = new String[deleteinfo.length];
        // 初始化一个HashMap，用于存储主键和对应的时间戳
        Map<String, UFDateTime> map = new HashMap();

        // 遍历删除信息数组，提取主键和时间戳，并存储到相应的数据结构中
        for(int i = 0; i < deleteinfo.length; ++i) {
            String pk = deleteinfo[i].getPks();
            pks[i] = pk;
            map.put(pk, deleteinfo[i].getTs());
        }

        // 创建一个BillQuery对象，用于查询AggPickmVO类的对象
        BillQuery<AggPickmVO> query = new BillQuery(AggPickmVO.class);
        // 使用提取的主键数组查询对应的AggPickmVO对象数组
        AggPickmVO[] aggVOs = (AggPickmVO[])query.query(pks);

        // 如果查询到的AggPickmVO对象数组不为空，则遍历数组，将时间戳信息添加到每个对象中
        if (aggVOs != null && aggVOs.length > 0) {
            for(int j = 0; j < aggVOs.length; ++j) {
                String key = aggVOs[j].getParentVO().getCpickmid();
                aggVOs[j].getParentVO().setAttributeValue("ts", map.get(key));
            }
        }

        // 返回查询到的AggPickmVO对象数组
        return aggVOs;
    }
    /**
     * 根据给定的业务ID数组和关闭原因查询销售订单视图信息
     *
     * @param bidts 包含业务ID和时间戳的字符串数组，用于查询特定的销售订单
     * @param vclosereason 销售订单的关闭原因，用于过滤查询结果或设置关闭状态
     * @return SaleOrderViewVO[] 返回一个销售订单视图对象数组，包含查询到的销售订单信息
     * @throws BusinessException 当查询过程中发生错误时抛出此异常
     */
    public static SaleOrderViewVO[] queryViewByBIDs(String[] bidts, String vclosereason) throws BusinessException {
        // 创建一个映射，用于存储从业务ID时间戳字符串中提取的时间戳信息
        Map<String, UFDateTime> bid_ts = new HashMap();
        // 使用工具类方法解析业务ID时间戳字符串，获取仅包含业务ID的数组和对应的时间戳信息
        String[] bids = TransBillUtil.splitBidts(bidts, bid_ts);

        // 通过服务定位器获取查询销售订单关闭状态的服务实例
        IQuerySaleOrderCloseService service = (IQuerySaleOrderCloseService)NCLocator.getInstance().lookup(IQuerySaleOrderCloseService.class);
        // 调用服务方法，根据业务ID数组查询销售订单视图信息
        SaleOrderViewVO[] vos = service.queryByIds(bids);

        // 使用工具类方法，根据之前提取的时间戳信息更新销售订单视图对象数组中的时间戳字段
        TransBillUtil.fillBodyTs(vos, "csaleorderbid", bid_ts);
        // 设置销售订单视图对象数组中的关闭原因信息
        SaleOrderCloseUtils.setCloseOpenReason(vos, vclosereason);
        // 返回填充了查询结果的销售订单视图对象数组
        return vos;
    }
    /*
     *创建时间：2024-11-28
     *作用：查询
     *传值：无
     *返回值：必填项map对象
     */
    private int updateSaleBSQty(String sql) throws BusinessException {
        BaseDAO baseDAO = new BaseDAO();
        int succInt = baseDAO.executeUpdate(sql);
        return succInt;
    }

    public IUAPQueryBS getQueryService() {
        return NCLocator.getInstance().lookup(IUAPQueryBS.class);
    }

}