package vip.xiaonuo.purchase.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import vip.xiaonuo.purchase.entity.PurchaseOrder;
import vip.xiaonuo.purchase.entity.vo.*;
import vip.xiaonuo.purchase.mapper.PurchaseOrderMapper;
import vip.xiaonuo.purchase.param.PurchaseOrderParam;
import vip.xiaonuo.purchase.param.PurchaseParam;
import vip.xiaonuo.purchase.service.IPurchaseOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.temporal.ChronoUnit;
import java.util.*;

/**
 * <p>
 * 采购订单表 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-11-25
 */
@Service
public class PurchaseOrderServiceImpl extends ServiceImpl<PurchaseOrderMapper, PurchaseOrder> implements IPurchaseOrderService {

    @Autowired
    private PurchaseOrderMapper purchaseOrderMapper;

    @Override
    public PurchaseOrderVo getOrder(PurchaseParam purchaseParam) {
        String orgId = purchaseParam.getOrgId();
        PurchaseOrderVo vo = new PurchaseOrderVo();
        QueryWrapper<PurchaseOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(orgId), "org_id", orgId).orderByAsc("create_time");
        String time = purchaseParam.getTime();
        DateTime dateTime = DateUtil.beginOfYear(new Date());
        if ("".equals(time) || null == time) {
            queryWrapper.ge("create_time", dateTime);
            DateTime time1 = DateUtil.beginOfMonth(new Date());
            DateTime last = DateUtil.lastMonth();
            DateTime beginOfMonth = DateUtil.beginOfMonth(last);
            DateTime endOfMonth = DateUtil.endOfMonth(last);
            QueryWrapper<PurchaseOrder> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq(StringUtils.isNotBlank(orgId), "org_id", orgId);
            queryWrapper1.ge("create_time", time1);
            queryWrapper1.select(" IFNULL(sum(invoice_price),'0') invoicePrice");
            PurchaseOrder order = purchaseOrderMapper.selectOne(queryWrapper1);//本月发票金额
            queryWrapper1.clear();
            queryWrapper1.eq(StringUtils.isNotBlank(orgId), "org_id", orgId);
            queryWrapper1.select(" IFNULL(sum(invoice_price),'0') invoicePrice");
            queryWrapper1.between("create_time", beginOfMonth, endOfMonth);
            PurchaseOrder order1 = purchaseOrderMapper.selectOne(queryWrapper1);//上月发票金额
            if (Double.valueOf(order.getInvoicePrice()).equals(0)) {
                vo.setMonthRank("0");
            } else if (Double.valueOf(order1.getInvoicePrice()).equals(0)||order1.getInvoicePrice()==null) {
                vo.setMonthRank("100");
            } else {
                DecimalFormat def = new DecimalFormat("0.00");
                vo.setMonthRank(def.format((Double.valueOf(order.getInvoicePrice()) / Double.valueOf(order1.getInvoicePrice()))));
            }
        } else {
            queryWrapper.between("create_time", time + "-01 00:00:00", time + "-31 23:59:59");
            String year = time.substring(0, 4);
            String month = time.substring(5, 7);
            YearMonth yearMonth = YearMonth.of(Integer.parseInt(year), Integer.parseInt(month));
            YearMonth previousMonth = yearMonth.minusMonths(1);
            QueryWrapper<PurchaseOrder> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq(StringUtils.isNotBlank(orgId), "org_id", orgId);
            queryWrapper1.between("create_time", time + "-01 00:00:00", time + "-31 23:59:59");
            queryWrapper1.select(" sum(invoice_price) invoicePrice");
            PurchaseOrder order = purchaseOrderMapper.selectOne(queryWrapper1);//本月发票金额
            queryWrapper1.clear();
            queryWrapper1.eq(StringUtils.isNotBlank(orgId), "org_id", orgId);
            queryWrapper1.select(" sum(invoice_price) invoicePrice");
            queryWrapper1.between("create_time", previousMonth + "-01 00:00:00", previousMonth + "-31 23:59:59");
            PurchaseOrder order1 = purchaseOrderMapper.selectOne(queryWrapper1);//上月发票金额
            if (ObjectUtil.isEmpty(order)) {
                vo.setMonthRank("0");
            } else if (ObjectUtil.isEmpty(order1)||order1.getInvoicePrice().equals("0")) {
                vo.setMonthRank("100");
            } else {
                DecimalFormat def = new DecimalFormat("0.00");
                vo.setMonthRank(def.format((Double.valueOf(order.getInvoicePrice()) - Double.valueOf(order1.getInvoicePrice()))/Double.valueOf(order1.getInvoicePrice())*100));
            }
        }
        List<PurchaseOrder> purchaseOrders = purchaseOrderMapper.selectList(queryWrapper);

        double money = 0.00;
        double acceptNumber = 0.00;
        double acceptMoney = 0.00;
        double enterNumber = 0.00;
        double enterMoney = 0.00;
        double invoiceMoney = 0.00;
        int invoiceNumber = 0;
        DecimalFormat def = new DecimalFormat("0.00");
        if (purchaseOrders.size() != 0) {
            for (PurchaseOrder purchaseOrder : purchaseOrders) {
                if (purchaseOrder.getPurchaseMoney() != null) {
                    money = money + Double.valueOf(purchaseOrder.getPurchaseMoney());
                }
                if (purchaseOrder.getMaterialAcceptPrice() != null) {
                    acceptMoney = acceptMoney + Double.valueOf(purchaseOrder.getMaterialAcceptPrice());
                }
                if (purchaseOrder.getMaterialAcceptNumber() != null) {
                    acceptNumber = acceptNumber + Double.valueOf(purchaseOrder.getMaterialAcceptNumber());
                }
                if (purchaseOrder.getEnterNumber() != null) {
                    enterNumber = enterNumber + Double.valueOf(purchaseOrder.getEnterNumber());
                }
                if (purchaseOrder.getEnterPrice() != null) {
                    enterMoney = enterMoney + Double.valueOf(purchaseOrder.getEnterPrice());
                }
                if (purchaseOrder.getInvoicePrice() != null) {
                    invoiceMoney = invoiceMoney + Double.valueOf(purchaseOrder.getInvoicePrice());
                }
                if (purchaseOrder.getInvoiceNumber() != null) {
                    invoiceNumber = invoiceNumber + purchaseOrder.getInvoiceNumber();
                }

            }

        } else {
            vo.setRank("0");
            vo.setOrderNumber("0");
        }
        QueryWrapper<PurchaseOrder> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq(StringUtils.isNotBlank(orgId), "org_id", orgId).orderByAsc("create_time");
        if ("".equals(time) || null == time) {
            queryWrapper2.ge("create_time", dateTime);
        } else {
            queryWrapper2.between("create_time", time + "-01 00:00:00", time + "-31 23:59:59");
        }
        queryWrapper2.select(" CONVERT(IFNULL(avg(rank),'0'),decimal(10,2)) 'rank',CONVERT(IFNULL(avg(month_rank),'0'),decimal(10,2)) 'monthRank'");
        PurchaseOrder order = purchaseOrderMapper.selectOne(queryWrapper2);

        vo.setRank(order.getRank());
        vo.setOrderNumber(String.valueOf(purchaseOrders.size()));

        vo.setPurchaseMoney(def.format(money / 10000));
        vo.setMaterialAcceptPrice(def.format(acceptMoney / 10000));
        vo.setMaterialAcceptNumber(def.format(acceptNumber));
        vo.setEnterNumber(def.format(enterNumber));
        vo.setEnterPrice(def.format(enterMoney / 10000));
        vo.setInvoiceNumber(purchaseOrders.size());
        vo.setInvoicePrice(def.format(invoiceMoney / 10000));


        String year = time.substring(0, 4);
        int i = Integer.parseInt(year);
        LocalDate currentDate = LocalDate.now();
        int lastYear = currentDate.getYear() - 1;
        QueryWrapper<PurchaseOrder> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq(StringUtils.isNotBlank(orgId), "org_id", orgId);
        queryWrapper1.between("create_time", i-1 + "-01-01 00:00:00", i-1 + "-12-31 23:59:59");
        queryWrapper1.select(" CONVERT(IFNULL(avg(purchase_money),'0'),decimal(10,2)) 'purchaseMoney'");
        PurchaseOrder purchaseOrder = purchaseOrderMapper.selectOne(queryWrapper1);
        if (ObjectUtil.isNotEmpty(purchaseOrder)) {
            vo.setLastAvgPrice(def.format(Double.valueOf(purchaseOrder.getPurchaseMoney()) / 10000));
        } else {
            vo.setLastAvgPrice("0.00");
        }
        return vo;
    }

    @Override
    public List<PurchaseOrderMoneyVo> listOrderMoney(PurchaseOrderParam orderParam) {
        String orgId = orderParam.getOrgId();
        String time = orderParam.getTime();
        QueryWrapper<PurchaseOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(orgId), "org_id", orgId).orderByAsc("create_time");
        queryWrapper.select(" IFNULL(sum(purchase_money),'0') purchaseMoney,create_time createTime,IFNULL(count(*),'0') invoiceNumber");
        BigDecimal math = new BigDecimal("10000");
        List<PurchaseOrderMoneyVo> list = new ArrayList<>();

        if ( null == orderParam.getTimeType() || 0==(orderParam.getTimeType())) {
//            if (StringUtils.isNotBlank(time)) {
//                String year = time.substring(0, 4);
//                queryWrapper.between("create_time", year + "-01-01 00:00:00", year + "-12-31 23:59:59");
//            }
            if ("".equals(orderParam.getOrderType()) || null == orderParam.getOrderType()) {
                queryWrapper.groupBy("DATE_FORMAT(create_time,'%Y')");
            } else {
                queryWrapper.groupBy("DATE_FORMAT(create_time,'%Y')");
            }

            List<PurchaseOrder> orders = purchaseOrderMapper.selectList(queryWrapper);
            if (orders.size() != 0) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
                for (PurchaseOrder order : orders) {
                    PurchaseOrderMoneyVo vo = new PurchaseOrderMoneyVo();
                    vo.setTime(sdf.format(order.getCreateTime()));
                    BigDecimal bd = new BigDecimal(order.getPurchaseMoney());
                    bd = bd.divide(math, 2, RoundingMode.HALF_UP);
                    vo.setOrderMoney(bd.toString());
                    vo.setOrderNumber(order.getInvoiceNumber());
                    list.add(vo);
                }
            }
        } else {
            DateTime dateTime = DateUtil.beginOfYear(new Date());
            queryWrapper.ge("create_time", dateTime);
            if ("".equals(orderParam.getOrderType()) || null == orderParam.getOrderType()) {
                queryWrapper.groupBy("DATE_FORMAT(create_time,'%Y-%m')");
            } else {
                queryWrapper.groupBy("DATE_FORMAT(create_time,'%Y-%m')");
            }
            List<PurchaseOrder> orders = purchaseOrderMapper.selectList(queryWrapper);
            if (orders.size() != 0) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
                for (PurchaseOrder order : orders) {
                    PurchaseOrderMoneyVo vo = new PurchaseOrderMoneyVo();
                    vo.setTime(sdf.format(order.getCreateTime()));
                    BigDecimal bd = new BigDecimal(order.getPurchaseMoney());
                    bd = bd.divide(math, 2, RoundingMode.HALF_UP);
                    vo.setOrderMoney(bd.toString());
                    vo.setOrderNumber(order.getInvoiceNumber());
                    list.add(vo);
                }
            }
        }
        return list;
    }

    @Override
    public List<PurchaseOrderTypeVo> orderType(PurchaseParam param) {
        String orgId = param.getOrgId();
        DateTime month = DateUtil.beginOfMonth(new Date());
        DateTime year = DateUtil.beginOfYear(new Date());
        LocalDate currentDate = LocalDate.now();
        int lastYear = currentDate.getYear() - 1;
        LocalDate lastYearSameDate = currentDate.minus(1, ChronoUnit.YEARS); // 减去一年
        int lastYearSameMonth = lastYearSameDate.getMonthValue(); // 获取去年同月份
        String lastMonth = "";
        if (lastYearSameMonth > 9) {
            lastMonth = String.valueOf(lastYearSameMonth);
        } else {
            lastMonth = "0" + lastYearSameMonth;
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<PurchaseOrderTypeVo> orderTypeVos = purchaseOrderMapper.listType(sdf.format(month), sdf.format(year), lastYear + "-" + lastMonth, lastYear, orgId);
        return orderTypeVos;
    }

    @Override
    public List<PurchaseMoneyVo> listMoney(PurchaseParam param) {
        String time = param.getTime();
        String substring = time.substring(0, 4);
        QueryWrapper<PurchaseOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(param.getOrgId()), "org_id", param.getOrgId());

        queryWrapper.between("create_time", Integer.parseInt(substring)+"-01-01 00:00:00",Integer.parseInt(substring) + "-12-31 23:59:59");
        queryWrapper.select(" IFNULL(sum(purchase_money),'0') purchaseMoney,create_time createTime");
        queryWrapper.groupBy("DATE_FORMAT(create_time,'%Y-%m')");
        List<PurchaseOrder> orders = purchaseOrderMapper.selectList(queryWrapper);
        queryWrapper.clear();
        queryWrapper.eq(StringUtils.isNotBlank(param.getOrgId()), "org_id", param.getOrgId());


        queryWrapper.between("create_time", Integer.parseInt(substring)-1 + "-01-01 00:00:00", Integer.parseInt(substring)-1 + "-12-31 23:59:59");
        queryWrapper.select(" IFNULL(sum(purchase_money),'0') purchaseMoney,create_time createTime");
        queryWrapper.groupBy("DATE_FORMAT(create_time,'%Y-%m')");
        List<PurchaseOrder> orders1 = purchaseOrderMapper.selectList(queryWrapper);
        List<PurchaseMoneyVo> list = new ArrayList<>();

        BigDecimal math = new BigDecimal("10000");
        for (int i = 1; i < 13; i++) {
            PurchaseMoneyVo vo = new PurchaseMoneyVo();
            vo.setTime(i + "月");
            for (PurchaseOrder order : orders) {
                Calendar cal = Calendar.getInstance();
                cal.setTime(order.getCreateTime());
                int month = cal.get(Calendar.MONTH) + 1; // 注意月份是从0开始计数的，所以需要加1
                if (i == month) {
                    BigDecimal bg = new BigDecimal(order.getPurchaseMoney());
                    bg = bg.divide(math, 2, RoundingMode.HALF_UP);
                    vo.setMoney(bg.toString());
                }
            }
            for (PurchaseOrder order : orders1) {
                Calendar cal = Calendar.getInstance();
                cal.setTime(order.getCreateTime());
                int month = cal.get(Calendar.MONTH) + 1; // 注意月份是从0开始计数的，所以需要加1
                if (i == month) {
                    BigDecimal bg = new BigDecimal(order.getPurchaseMoney());
                    bg = bg.divide(math, 2, RoundingMode.HALF_UP);
                    vo.setLastMoney(bg.toString());
                }
            }
            list.add(vo);
        }
        return list;
    }

    @Override
    public JSONArray materialType(PurchaseParam param) {
        QueryWrapper<PurchaseOrder> queryWrapper = new QueryWrapper<>();
        String time = param.getTime();
        DateTime dateTime = DateUtil.beginOfYear(new Date());
        if ("".equals(time) || null == time) {
            queryWrapper.ge("create_time", dateTime);
        } else {
            queryWrapper.between("create_time", time + "-01 00:00:00", time + "-31 23:59:59");
        }
        queryWrapper.eq(StringUtils.isNotBlank(param.getOrgId()), "org_id", param.getOrgId());
        BigDecimal math = new BigDecimal("10000");
        List<PurchaseMaterialVo> list = purchaseOrderMapper.getSupplier(queryWrapper);
        for (int i = 0; i < list.size(); i++) {
            BigDecimal bg = new BigDecimal(list.get(i).getValue());
//            bg = bg.divide(math, 2, RoundingMode.HALF_UP);
//            list.get(i).setValue(bg.toString());
            if (list.get(i).getName() == null) {
                list.remove(i);
            }
        }
        JSONArray jsonArray = new JSONArray(list);
        System.out.println("数组的大小" + jsonArray.size());
        JSONArray array = jsonArraySort(jsonArray, "value", true);
        return array;
    }

    /*数组排序*/
    public static JSONArray jsonArraySort(JSONArray jsonArr, String sortKey, boolean is_desc) {
        //存放排序结果json数组
        JSONArray sortedJsonArray = new JSONArray();
        //用于排序的list
        List<JSONObject> jsonValues = new ArrayList<JSONObject>();
        //将参数json数组每一项取出，放入list
        if (jsonArr.size() < 6) {
            for (int i = 0; i < jsonArr.size(); i++) {
                jsonValues.add(jsonArr.getJSONObject(i));
            }
            //快速排序，重写compare方法，完成按指定字段比较，完成排序
            Collections.sort(jsonValues, new Comparator<JSONObject>() {
                //排序字段
                private final String KEY_NAME = sortKey;

                //重写compare方法
                @Override
                public int compare(JSONObject a, JSONObject b) {
                    //如果用String接会导致一位数和两位数混合比对的时候不能准确比出来，要用int类型接
                    //String valA = new String();
                    //String valB = new String();
                    Float valA = 0.00f;
                    Float valB = 0.00f;
                    try {
                        valA = Float.parseFloat(a.getString(KEY_NAME));
                        valB = Float.parseFloat(b.getString(KEY_NAME));
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    //是升序还是降序
                    if (is_desc) {
                        return -valA.compareTo(valB);
                    } else {
                        return -valB.compareTo(valA);
                    }

                }
            });
            //将排序后结果放入结果jsonArray
            for (int i = 0; i < jsonArr.size(); i++) {
                sortedJsonArray.add(jsonValues.get(i));
            }
        } else {
            for (int i = 0; i < 5; i++) {
                jsonValues.add(jsonArr.getJSONObject(i));
            }
            //快速排序，重写compare方法，完成按指定字段比较，完成排序
            Collections.sort(jsonValues, new Comparator<JSONObject>() {
                //排序字段
                private final String KEY_NAME = sortKey;

                //重写compare方法
                @Override
                public int compare(JSONObject a, JSONObject b) {
                    //如果用String接会导致一位数和两位数混合比对的时候不能准确比出来，要用int类型接
                    //String valA = new String();
                    //String valB = new String();
                    Float valA = 0.00f;
                    Float valB = 0.00f;
                    try {
                        valA = Float.parseFloat(a.getString(KEY_NAME));
                        valB = Float.parseFloat(b.getString(KEY_NAME));
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    //是升序还是降序
                    if (is_desc) {
                        return -valA.compareTo(valB);
                    } else {
                        return -valB.compareTo(valA);
                    }

                }
            });
            //将排序后结果放入结果jsonArray
            for (int i = 0; i < 5; i++) {
                sortedJsonArray.add(jsonValues.get(i));
            }
        }

        return sortedJsonArray;
    }

}
