package com.ruixuan.report.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruixuan.common.core.domain.entity.SysUser;
import com.ruixuan.common.utils.Check;
import com.ruixuan.common.utils.DateUtils;
import com.ruixuan.common.utils.PageUtils;
import com.ruixuan.common.utils.Result;
import com.ruixuan.jinniu.mapper.KuaishouProjectMapper;
import com.ruixuan.report.mapper.KuaishouLiveAccountReportMapper;
import com.ruixuan.report.service.IKuaishouLiveAccountReportService;
import com.ruixuan.report.utils.AccountReportConstants;
import com.ruixuan.report.utils.JsonResourceUtil;
import com.ruixuan.system.service.ISysDeptService;
import com.ruixuan.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 账户报表Service业务层处理
 *
 * @author ruoyi
 * @date 2023-03-22
 */
@Service
public class KuaishouLiveAccountReportServiceImpl implements IKuaishouLiveAccountReportService {
    @Autowired
    private KuaishouLiveAccountReportMapper mapper;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private KuaishouProjectMapper projectMapper;
    @Autowired
    private ISysDeptService deptService;

    @Override
    public JSONObject operateHomePageHead(Long userId) {
        String roleKey = sysUserService.getRoleKeyByUserId(userId);
        List<Long> userList;
        if ("admin".equals(roleKey) || "directorOperations".equals(roleKey)) {
            //查看所有
            userList = null;
        } else if ("operationsManager".equals(roleKey)) {
            //运营经理 可以看自己部门所有人的（自己和下属的）
            Long deptId = deptService.getDeptIdByUserId(userId);
            userList = deptService.getDeptUserListByDeptId(deptId);
        } else {
            userList = Arrays.asList(userId);
        }
        //当前小时
        Integer hour = DateUtils.getNowHour();
        String yesterday = DateUtils.getSubtractTime(new Date(), 1);
        String today = DateUtils.getDate();
        Map<String, Object> map = new HashMap<>();
        map.put("userList", userList);
        map.put("hour", hour);
        map.put("today", today.replace("-", ""));
        map.put("yesterday", yesterday.replace("-", ""));
        JSONObject result = mapper.operateHomePageHead(map);
        result.put("customersNum", mapper.getCustomersNum(map));
        return result;
    }

    @Override
    public List<JSONObject> getProjectCostList(Long userId, String startDate, String endDate) {
        String roleKey = sysUserService.getRoleKeyByUserId(userId);
        List<Long> userList;
        if ("admin".equals(roleKey) || "directorOperations".equals(roleKey)) {
            //查看所有
            userList = null;
        } else if ("operationsManager".equals(roleKey)) {
            //运营经理 可以看自己部门所有人的（自己和下属的）
            Long deptId = deptService.getDeptIdByUserId(userId);
            userList = deptService.getDeptUserListByDeptId(deptId);
        } else {
            userList = Arrays.asList(userId);
        }
        List<Long> projectIds = null;
        if (Check.isNotNull(userList)) {
            //人员参与的项目集
            projectIds = projectMapper.getMyProjectIdsByUserIds(userList);
        }

        //整理入参时间
        Map<String, Object> map = getDateTime(startDate, endDate);
        map.put("projectIds", projectIds);

        String type = map.get("type").toString();
        if ("hourly".equals(type)) {
//            PageUtils.startPage();
            return mapper.getProjectCostListByHourly(map);
        } else {
//            PageUtils.startPage();
            return mapper.getProjectCostListByDaily(map);
        }
    }

    @Override
    public Result getOperationsGroupCostList(Long userId, String startDate, String endDate, Integer pageNum, Integer pageSize) {
        String roleKey = sysUserService.getRoleKeyByUserId(userId);
        List<Long> managerIds;
        if ("admin".equals(roleKey) || "directorOperations".equals(roleKey)) {
            //查看所有
            managerIds = sysUserService.getUserIdByRoleKey("operationsManager");
        } else if ("operationsManager".equals(roleKey)) {
            //运营经理 可以看自己部门所有人的（自己和下属的）
            managerIds = Arrays.asList(userId);
        } else {
            return Result.success();
        }
        //整理入参时间
        Map<String, Object> map = getDateTime(startDate, endDate);
        String type = map.get("type").toString();
        List<JSONObject> list = new ArrayList<>();
        for (Long managerId : managerIds) {
            Long deptId = deptService.getDeptIdByUserId(managerId);
            List<Long> userList = deptService.getDeptUserListByDeptId(deptId);
            map.put("userList", userList);
            //人员参与的项目集
            SysUser sysUser = sysUserService.selectUserById(managerId);
            map.put("operateNum", userList.size());
            JSONObject result = new JSONObject();
            List<Long> projectIds = projectMapper.getMyProjectIdsByUserIds(userList);
            result.put("userId", managerId);
            result.put("userName", sysUser.getNickName());
            result.put("operateNum", userList.size());
            result.put("projectNum", projectIds.size());
            JSONObject data = new JSONObject();
            if ("hourly".equals(type)) {
                data = mapper.getOperationsGroupCostByHourly(map);
            } else {
                data = mapper.getOperationsGroupCostByDaily(map);
            }
            result.put("costTotal", data.getBigDecimal("costTotal"));
            result.put("perCost", data.getBigDecimal("perCost"));
            result.put("roi", data.getBigDecimal("roi"));
            result.put("yesCostTotal", data.getBigDecimal("yesCostTotal"));
            list.add(result);
        }
        JSONObject all = new JSONObject();
        all.put("userName", "汇总");
        all.put("projectNum", "-");
        Double operateNum = list.stream().mapToDouble(value -> value.getDouble("operateNum")).reduce(Double::sum).getAsDouble();
        all.put("operateNum", new BigDecimal(operateNum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
        Double costTotal = list.stream().mapToDouble(value -> value.getDouble("costTotal")).reduce(Double::sum).getAsDouble();
        all.put("costTotal", new BigDecimal(costTotal).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
        Double yesCostTotal = list.stream().mapToDouble(value -> value.getDouble("yesCostTotal")).reduce(Double::sum).getAsDouble();
        all.put("yesCostTotal", new BigDecimal(yesCostTotal).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());

        Integer days = (Integer) map.get("days");
        //人均消耗 总花费/天数/人数
        Double avePeople = costTotal == 0 ? 0 : costTotal / days / operateNum;
        all.put("perCost", new BigDecimal(avePeople).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
        if (Check.isNotNull(yesCostTotal) && new BigDecimal(yesCostTotal).compareTo(new BigDecimal("0")) > 0) {
            DecimalFormat decimalFormat = new DecimalFormat("0.00%");
            Double yearOnYearD = (costTotal - yesCostTotal) / yesCostTotal;
            all.put("roi", new BigDecimal(yearOnYearD).multiply(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
        } else {
            all.put("roi", "0.0");
        }
        list.add(all);
        return Result.success(list);

    }

    @Override
    public List<JSONObject> getOperateCostList(Long userId, String startDate, String endDate) {
        String roleKey = sysUserService.getRoleKeyByUserId(userId);
        List<Long> userList;
        if ("admin".equals(roleKey) || "directorOperations".equals(roleKey)) {
            //查看所有
            userList = null;
        } else if ("operationsManager".equals(roleKey)) {
            //运营经理 可以看自己部门所有人的（自己和下属的）
            Long deptId = deptService.getDeptIdByUserId(userId);
            userList = deptService.getDeptUserListByDeptId(deptId);
        } else {
            userList = Arrays.asList(userId);
        }
        //整理入参时间
        Map<String, Object> map = getDateTime(startDate, endDate);
        map.put("userList", userList);

        List<JSONObject> result;
        String type = map.get("type").toString();
        if ("hourly".equals(type)) {
//            PageUtils.startPage();
            result = mapper.getOperateCostListByHourly(map);
            result.add(mapper.getOperateCostTotalByHourly(map));
        } else {
//            PageUtils.startPage();
            result = mapper.getOperateCostListByDaily(map);
            result.add(mapper.getOperateCostTotalByDaily(map));
        }
        return result;
    }

    @Override
    public JSONObject getOperateCostTrendChartList(Long userId, String queryType, String startDate, String endDate) {
        String roleKey = sysUserService.getRoleKeyByUserId(userId);
        List<Long> userList;
        if ("1".equals(queryType)) {
            userList = Arrays.asList(userId);
        } else {
            if ("admin".equals(roleKey) || "directorOperations".equals(roleKey)) {
                //查看所有
                userList = null;
            } else if ("operationsManager".equals(roleKey)) {
                //运营经理 可以看自己部门所有人的（自己和下属的）
                Long deptId = deptService.getDeptIdByUserId(userId);
                userList = deptService.getDeptUserListByDeptId(deptId);
            } else {
                userList = Arrays.asList(userId);
            }
        }

        //整理入参时间
        Map<String, Object> map = getDateTime(startDate, endDate);
        map.put("userList", userList);

        JSONObject result = new JSONObject();
        String type = map.get("type").toString();
        if (startDate.equals(endDate)) {
            List<JSONObject> todayInfo = mapper.getOperateCostTrendChartListByHourly(map);
            completeHour(todayInfo);
            result.put("todayInfo", todayInfo);
            map.put("today", map.get("yesterday"));
            List<JSONObject> yesterdayInfo = mapper.getOperateCostTrendChartListByHourly(map);
            completeHour(yesterdayInfo);
            result.put("yesterdayInfo", yesterdayInfo);
        } else {
            List<JSONObject> dailyData = mapper.getOperateCostTrendChartListByDaily(map);
            List<String> allDates = DateUtils.getAllDatesOfTwoTimes(startDate, endDate);
            if (Check.isNull(dailyData) || allDates.size() != dailyData.size()) {
                completeDate(dailyData, allDates);
            }
            result.put("info", dailyData);
        }
        return result;
    }

    @Override
    public JSONObject getStatisticalReportHead(JSONObject request) {
        //整理入参时间
        Map<String, Object> map = getDateTime(request.getString("startDate"), request.getString("endDate"));
        map.put("accountIdList", request.getJSONArray("accountIdList"));

        String type = map.get("type").toString();
        if ("hourly".equals(type)) {
            return mapper.getStatisticalReportHeadByHourly(map);
        } else {
            return mapper.getStatisticalReportHeadByDaily(map);
        }
    }

    @Override
    public List<JSONObject> getvisitorStatisticsTrendChartList(JSONObject request) {
        String startDate = request.getString("startDate");
        String endDate = request.getString("endDate");
        //整理入参时间
        Map<String, Object> map = getDateTime(startDate, endDate);
        map.put("accountIdList", request.getJSONArray("accountIdList"));
        if (startDate.equals(endDate)) {
            List<JSONObject> list = mapper.getvisitorStatisticsTrendChartListByHourly(map);
            completeHour(list);
            return list;
        } else {
            List<JSONObject> list = mapper.getvisitorStatisticsTrendChartListByDaily(map);
            List<String> allDates = DateUtils.getAllDatesOfTwoTimes(startDate, endDate);
            if (Check.isNull(list) || allDates.size() != list.size()) {
                completeDate(list, allDates);
            }
            return list;
        }
    }

    @Override
    public List<JSONObject> nodeAccountCost(JSONObject request) {
        Integer hour = request.getInteger("hour");
        Map<String, Object> map = new HashMap<>();
        map.put("date", request.getString("date").replace("-", ""));
        map.put("accountIdList", request.getJSONArray("accountIdList"));
        if (Check.isNotNull(hour)) {
            map.put("hour", hour);
            return mapper.getNodeAccountsCostByHourly(map);
        } else {
            return mapper.getNodeAccountsCostByDaily(map);
        }
    }

    @Override
    public List<JSONObject> getAccountDataReport(Long userId, String accountIdList, String startDate, String endDate) {
        //整理入参时间
        Map<String, Object> map = getDateTime(startDate, endDate);
        map.put("accountIdList", JSONArray.parseArray(accountIdList));
        String type = map.get("type").toString();
        String filedAll = JsonResourceUtil.joinAllFiled(AccountReportConstants.getKuaishouAccountReport());
        System.out.println(filedAll);
        map.put("filedAll", filedAll);
        if (startDate.equals(endDate)) {
            PageUtils.startPage();
            return mapper.getAccountDataReportByHourly(map);
        } else {
            PageUtils.startPage();
            return mapper.getAccountDataReportByDaily(map);
        }
    }

    @Override
    public List<JSONObject> exportAccountDataReport(JSONObject request) {
        String startDate = request.getString("startDate");
        String endDate = request.getString("endDate");
        //整理入参时间
        Map<String, Object> map = getDateTime(startDate, endDate);
        map.put("accountIdList", request.getJSONArray("accountIdList"));
        String type = map.get("type").toString();
        String filedAll = JsonResourceUtil.joinAllFiled(AccountReportConstants.getKuaishouAccountReport());
        map.put("filedAll", filedAll);
        List<JSONObject> list = null;
        if (startDate.equals(endDate)) {
            list = mapper.getAccountDataReportByHourly(map);
        } else {
            list = mapper.getAccountDataReportByDaily(map);
        }
        BigDecimal ten = new BigDecimal("10");
        // 花费、成本、GMV以及相关字段 除以 10
        list.forEach(data -> {
            data.put("costTotal", data.getBigDecimal("costTotal").divide(ten));
            data.put("adShow1kCost", data.getBigDecimal("adShow1kCost").divide(ten));
            data.put("actionbarClickCost", data.getBigDecimal("actionbarClickCost").divide(ten));
            data.put("conversionCostEsp", data.getBigDecimal("conversionCostEsp").divide(ten));
            data.put("gmv", data.getBigDecimal("gmv").divide(ten));
            data.put("t0Gmv", data.getBigDecimal("t0Gmv").divide(ten));
            data.put("t1Gmv", data.getBigDecimal("t1Gmv").divide(ten));
            data.put("t7Gmv", data.getBigDecimal("t7Gmv").divide(ten));
            data.put("t15Gmv", data.getBigDecimal("t15Gmv").divide(ten));
            data.put("t30Gmv", data.getBigDecimal("t30Gmv").divide(ten));
            data.put("t0OrderCntCost", data.getBigDecimal("t0OrderCntCost").divide(ten));
            data.put("reservationCost", data.getBigDecimal("reservationCost").divide(ten));
            data.put("liveAudienceCost", data.getBigDecimal("liveAudienceCost").divide(ten));
            data.put("fansT0Gmv", data.getBigDecimal("fansT0Gmv").divide(ten));
            data.put("fansT1Gmv", data.getBigDecimal("fansT1Gmv").divide(ten));
            data.put("fansT7Gmv", data.getBigDecimal("fansT7Gmv").divide(ten));
            data.put("fansT15Gmv", data.getBigDecimal("fansT15Gmv").divide(ten));
            data.put("fansT30Gmv", data.getBigDecimal("fansT30Gmv").divide(ten));
            data.put("fansT1Gmv", data.getBigDecimal("fansT1Gmv").divide(ten));
        });
        return list;
    }

    @Override
    public Result getReportFields() {
        List<JSONObject> fieldsNames = JsonResourceUtil.getFieldsNames(AccountReportConstants.getKuaishouAccountReport());
        return Result.success(fieldsNames);
    }

    @Override
    public Result addKuaishouFields(JSONObject request) {
        mapper.replaceKuaishouFields(request);
        return Result.success();
    }

    @Override
    public Result getKuaishouFieldsByUserId(Long userId, String columnType) {
        JSONObject o = mapper.getKuaishouFieldsByUserId(userId, columnType);
        return Result.success(o);
    }


    /*补全数据，排序 */
    private void completeDate(List<JSONObject> list, List<String> allDates) {
        String listStr = JSONObject.toJSONString(list);
        for (String date : allDates) {
            if (!listStr.contains(date)) {
                JSONObject obj = new JSONObject();
                obj.put("time", date);
                obj.put("costTotal", 0);
                list.add(obj);
            }
        }
        //排序
        Collections.sort(list, new Comparator<JSONObject>() {
            @Override
            public int compare(JSONObject o1, JSONObject o2) {
                return o1.getString("time").compareTo(o2.getString("time"));
            }
        });
    }


    /*补全小时数据，排序 */
    private void completeHour(List<JSONObject> list) {
        List<Integer> newDayList = new ArrayList<>();
        for (JSONObject data : list) {
            newDayList.add(data.getInteger("time"));
        }
        List<Integer> dayList = new ArrayList<>();
        for (int i = 0; i <= 23; i++) {
            dayList.add(i);
        }
        for (Integer hour : dayList) {
            if (!newDayList.contains(hour)) {
                JSONObject obj = new JSONObject();
                obj.put("time", hour);
                obj.put("costTotal", 0);
                list.add(obj);
            }
        }
    }

    /*根据入参时间，整理上个时间周期，并判断查询日报OR时报*/
    private Map<String, Object> getDateTime(String startDate, String endDate) {
        Map<String, Object> map = new HashMap<>();
        //当前小时
        String today = DateUtils.getDate();
        if (today.equals(endDate) && startDate.equals(endDate)) {
            /* 开始日期和结束日期都是今天*/
            Integer hour = DateUtils.getNowHour();
            String yesterday = DateUtils.getSubtractTime(new Date(), 1);
            map.put("hour", hour);
            map.put("today", today.replace("-", ""));
            map.put("yesterday", yesterday.replace("-", ""));
            map.put("days", 1);
            map.put("type", "hourly");
        } else if (!today.equals(endDate) && startDate.equals(endDate)) {
            /* 开始日期和结束日期相同，但不是当日日期*/
            String previousDay = DateUtils.getSubtractTime(DateUtils.parseDate(startDate), 1);
            map.put("startDate", startDate.replace("-", ""));
            map.put("endDate", endDate.replace("-", ""));
            map.put("lastStart", previousDay.replace("-", ""));
            map.put("lastEnd", previousDay.replace("-", ""));
            map.put("days", 1);
            map.put("type", "daily");
            //折线图时使用↓
            map.put("today", startDate.replace("-", ""));
            map.put("yesterday", previousDay.replace("-", ""));
        } else {
            /*多日日期*/
            int days = DateUtils.differentDaysByMillisecond(DateUtils.parseDate(startDate), DateUtils.parseDate(endDate)) + 1;
            String lastStart = DateUtils.getSubtractTime(DateUtils.parseDate(startDate), days);
            String lastEnd = DateUtils.getSubtractTime(DateUtils.parseDate(endDate), days);
            map.put("startDate", startDate.replace("-", ""));
            map.put("endDate", endDate.replace("-", ""));
            map.put("lastStart", lastStart.replace("-", ""));
            map.put("lastEnd", lastEnd.replace("-", ""));
            map.put("days", days);
            map.put("type", "daily");
        }
        return map;
    }

}