package vip.xiaonuo.money.service.impl;

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 com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import vip.xiaonuo.money.entity.MoneyOverdue;
import vip.xiaonuo.money.entity.MoneyWriteOverdue;
import vip.xiaonuo.money.entity.vo.MoneyBorrowUserVo;
import vip.xiaonuo.money.mapper.MoneyOverdueMapper;
import vip.xiaonuo.money.mapper.MoneyWriteOverdueMapper;
import vip.xiaonuo.money.param.MoneyOverdueDetailPageParam;
import vip.xiaonuo.money.param.MoneyOverduePageParam;
import vip.xiaonuo.money.param.MoneyOverdueParam;
import vip.xiaonuo.money.service.IMoneyOverdueService;
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.util.*;

/**
 * <p>
 * 财务应收逾期表 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-11-21
 */
@Service
public class MoneyOverdueServiceImpl extends ServiceImpl<MoneyOverdueMapper, MoneyOverdue> implements IMoneyOverdueService {

    @Autowired
    private MoneyOverdueMapper overdueMapper;
    @Autowired
    private MoneyWriteOverdueMapper writeOverdueMapper;

    @Override
    public JSONObject getOverdueCount(MoneyOverdueParam overdueParam) {
        String orgId = overdueParam.getOrgId();
        QueryWrapper<MoneyWriteOverdue> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(orgId), "org_id", orgId);
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -1);
        queryWrapper.ge("end_time", calendar.getTime());
        queryWrapper.select("convert(IFNULL(sum(money),'0'),decimal(10,2)) money");
        MoneyWriteOverdue writeOverdue = writeOverdueMapper.selectOne(queryWrapper);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("money", writeOverdue.getMoney());
        return jsonObject;
    }

    @Override
    public JSONObject overdueRank(MoneyOverdueParam overdueParam) {
        String orgId = overdueParam.getOrgId();
        QueryWrapper<MoneyWriteOverdue> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(orgId), "org_id", orgId);
        queryWrapper.select("sum(money) money,end_time endTime");
        List<MoneyWriteOverdue> writeOverdues = writeOverdueMapper.selectList(queryWrapper);
        double count = 0.00;
        double isOverdue = 0.00;
        double disOverdue = 0.00;
        JSONObject jsonObject = new JSONObject();
        DecimalFormat def = new DecimalFormat("0.00");

        if (ObjectUtil.isNotEmpty(writeOverdues)) {
            for (MoneyWriteOverdue overdue : writeOverdues) {
                if (overdue.getEndTime().before(new Date())) {
                    isOverdue = isOverdue + Double.valueOf(overdue.getMoney());
                }else {
                    disOverdue = disOverdue + Double.valueOf(overdue.getMoney());
                }
                count = isOverdue + disOverdue;
            }
            if (count == 0) {
                jsonObject.put("isOverdue", "0");
                jsonObject.put("disOverdue", "100");
            } else {
                jsonObject.put("isOverdue", def.format(isOverdue / count));
                jsonObject.put("disOverdue", def.format(disOverdue / count));
            }
        } else {
            jsonObject.put("isOverdue", "0");
            jsonObject.put("disOverdue", "100");
        }
        return jsonObject;
    }

    @Override
    public List<MoneyBorrowUserVo> userRank(MoneyOverdueParam overdueParam) {
        String orgId = overdueParam.getOrgId();
        String time = overdueParam.getTime();
        List<MoneyBorrowUserVo> userRank = overdueMapper.getUserRank(time + "-01 00:00:00", time + "-31 23:59:59",orgId);
        BigDecimal math = new BigDecimal("10000");
        List<MoneyBorrowUserVo> list = new ArrayList<>();
        if (userRank.size() != 0) {
            Double collect = 0.00;
            Double overdue = 0.00;
            for (int i = 0; i < userRank.size(); i++) {
                if (i < 15) {
                    BigDecimal bg = new BigDecimal(userRank.get(i).getCollectPrice());
                    bg = bg.divide(math, 2, RoundingMode.HALF_UP);
                    BigDecimal bg1 = new BigDecimal(userRank.get(i).getOverduePrice());
                    bg1 = bg1.divide(math, 2, RoundingMode.HALF_UP);
                    userRank.get(i).setCollectPrice(bg.toString());
                    userRank.get(i).setOverduePrice(bg1.toString());
                    list.add(userRank.get(i));
                } else {
                    collect = collect + Double.valueOf(userRank.get(i).getCollectPrice());
                    overdue = overdue + Double.valueOf(userRank.get(i).getOverduePrice());
                }
            }
            MoneyBorrowUserVo vo = new MoneyBorrowUserVo();
            vo.setUserName("others");
            BigDecimal c1 = new BigDecimal(collect);
            c1 = c1.divide(math, 2, RoundingMode.HALF_UP);
            BigDecimal c2 = new BigDecimal(overdue);
            c2 = c2.divide(math, 2, RoundingMode.HALF_UP);
            vo.setCollectPrice(c1.toString());
            vo.setOverduePrice(c2.toString());
            list.add(vo);
        }
        return list;
    }

    @Override
    public Page<MoneyWriteOverdue> overdueDetail(MoneyOverdueDetailPageParam overduePageParam) {
        String orgId = overduePageParam.getOrgId();
        Integer pageNum = overduePageParam.getPageNum();
        Integer pageSize = overduePageParam.getPageSize();
        Integer type = overduePageParam.getType();
        String userName = overduePageParam.getUserName();

        QueryWrapper<MoneyWriteOverdue> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(orgId), "org_id", orgId).orderByDesc("create_time");
        queryWrapper.eq(StringUtils.isNotBlank(userName), "user_name", userName);
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, 15);
        if (null == type) {
        } else if (0 == type) {
            queryWrapper.ge("end_time", calendar.getTime());
        } else if (1 == type) {
            queryWrapper.le("end_time", DateUtil.beginOfDay(new Date()));
        } else if (2 == type) {
            queryWrapper.between("end_time", DateUtil.beginOfDay(new Date()), calendar.getTime());
        }

        Page<MoneyWriteOverdue> page = new Page<>(pageNum, pageSize);
        Page<MoneyWriteOverdue> selectPage = writeOverdueMapper.selectPage(page, queryWrapper);
        return selectPage;
    }

    @Override
    public List<MoneyOverdue> listUserName(Map<String, String> paramsMap) {
        String orgId = paramsMap.get("orgId");
        QueryWrapper<MoneyOverdue> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(orgId), "org_id", orgId);
        queryWrapper.groupBy("user_name");
        return overdueMapper.selectList(queryWrapper);
    }

    @Override
    public List<MoneyOverdue>  keHu(MoneyOverdue moneyOverdue) {
        String orgId = moneyOverdue.getOrgId();
        List<MoneyOverdue> moneyOverdues = overdueMapper.selectList(new QueryWrapper<MoneyOverdue>().select("user_name").eq(StringUtils.isNotBlank(orgId), "org_id", orgId).groupBy("user_name"));

        return moneyOverdues;
    }

    /*数组排序*/
    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

            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));
            }
        return sortedJsonArray;
    }
}
