package com.sqx.modules.datacentre.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqx.common.utils.DateUtils;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.dao.UserDao;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.entity.UserMoneyDetails;
import com.sqx.modules.app.service.UserService;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.common.service.CommonInfoService;
import com.sqx.modules.coupon.service.TbCouponUserService;
import com.sqx.modules.datacentre.dao.DataCentreDao;
import com.sqx.modules.datacentre.query.DataCenterQuery;
import com.sqx.modules.datacentre.query.RankListQuery;
import com.sqx.modules.datacentre.query.ShopCenterQuery;
import com.sqx.modules.datacentre.service.DataCentreService;
import com.sqx.modules.errand.entity.Feedback;
import com.sqx.modules.errand.entity.TbIndent;
import com.sqx.modules.order.dao.AppOrderDao;
import com.sqx.modules.order.entity.TbOrder;
import com.sqx.modules.pay.entity.CashOut;
import com.sqx.modules.pay.entity.PayDetails;
import com.sqx.modules.utils.VipExpirationUtil;
import com.sqx.modules.utils.excel.ExcelData;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@Service
@Slf4j
@RequiredArgsConstructor
public class DataCentreServiceImpl implements DataCentreService {

    private final DataCentreDao dataCentreDao;
    private final UserDao userDao;
    private final AppOrderDao appOrderDao;
    private final UserService userService;
    private final CommonInfoService commonInfoService;
    private final TbCouponUserService tbCouponUserService;

    @Override
    public Result dataCentre() {
        String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        HashMap dataCenter = new HashMap();
        //总用户数
        int allCount = dataCentreDao.findAllCount();
        //今日新增用户数
        int dayAddUser = dataCentreDao.findDayAddUser(format);
        //本月新增用户数
        int monthAddUser = dataCentreDao.findMonthAddUser(format);
        //本年新增用户数
        int yearAddUser = dataCentreDao.findYearAddUser(format);
        //今日收入
        BigDecimal dayIncome = dataCentreDao.findDayIncome(format.substring(0,10)+" 00:00:00",DateUtils.dateStrEndTime(format,"day"));
        //本月收入
        BigDecimal monthIncome = dataCentreDao.findDayIncome(format.substring(0,7)+"-01 00:00:00",DateUtils.dateStrEndTime(format,"month"));
        //本年收入
        BigDecimal yearIncome = dataCentreDao.findDayIncome(format.substring(0,4)+"-01-01 00:00:00",DateUtils.dateStrEndTime(format,"year"));
        //今日接单数量
        int indentCount = dataCentreDao.findIndentCount(format.substring(0,10)+" 00:00:00",DateUtils.dateStrEndTime(format,"day"));
        dataCenter.put("allCount", allCount);
        dataCenter.put("dayAddUser", dayAddUser);
        dataCenter.put("monthAddUser", monthAddUser);
        dataCenter.put("yearAddUser", yearAddUser);
        dataCenter.put("dayIncome", dayIncome);
        dataCenter.put("monthIncome", monthIncome);
        dataCenter.put("yearIncome", yearIncome);
        dataCenter.put("indentCount", indentCount);
        return Result.success().put("data", dataCenter);
    }

    @Override
    public Result selectPayOrderAnalyze(DataCenterQuery query) {
        Page<TbOrder> pages=new Page<>(query.getPage(),query.getLimit());
        PageUtils pageUtils = new PageUtils(dataCentreDao.selectPayOrderAnalyze(pages, DateUtils.dateStrEndTime(query)));
        return Result.success().put("data", pageUtils);
    }

    @Override
    public Result selectAllUser(Integer page, Integer limit, String userName, String phone) {
        Page<UserEntity> pages=new Page<>(page,limit);
        PageUtils pageUtils = new PageUtils(userDao.selectUser(pages, userName, phone));
        return Result.success().put("data", pageUtils);
    }

    @Override
    public Result selectUserById(Long userId) {
        UserEntity userEntity = userDao.selectUserById(userId);
        //本月发单数量， 本月充值金额，
        String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        Integer orderMonth = dataCentreDao.sumOrderMonth(userId, date);
        Integer joinOrderMonth = dataCentreDao.sumJoinOrderMonth(userId, date);
        BigDecimal topUpMonth = dataCentreDao.sumTopUpMonth(userId, date);
        BigDecimal riderMoney = dataCentreDao.sumRiderMoney(userId);
        BigDecimal cashMoney = dataCentreDao.sumCashMoney(userId, date);
        //本月派单数量
        userEntity.setOrderMonth(orderMonth);
        //本月接单数量
        userEntity.setJoinOrderMonth(joinOrderMonth);
        //本月充值金额
        userEntity.setTopUpMonth(topUpMonth);
        //骑手收入
        userEntity.setRiderMoney(riderMoney);
        //本月提现
        userEntity.setCashMoney(cashMoney);
        return Result.success().put("data", userEntity);
    }

    @Override
    public Result selectOrderData(DataCenterQuery oldQuery) {
        DataCenterQuery query=DateUtils.dateStrEndTime(oldQuery);
        HashMap hashMap = new HashMap();
        BigDecimal sumMoney = appOrderDao.selectSumMoney(query);
        int countOrder = appOrderDao.selectCountOrder(query);
        //到店订单数
        int takeCount = dataCentreDao.selectTakeCount(1, query);
        //外卖订单数
        int takeCount2 = dataCentreDao.selectTakeCount(2, query);
        //到店订单金额
        BigDecimal takeMoney = dataCentreDao.selectTakeMoney(1, query);
        //外卖订单金额
        BigDecimal takeMoney1 = dataCentreDao.selectTakeMoney(2, query);
        //退款订单数
        int cancelOrderCount = dataCentreDao.cancelOrderCount(query);
        //退款金额
        BigDecimal cancelOrderMoney = dataCentreDao.cancelOrderMoney(query);
        hashMap.put("sumMoney", sumMoney);
        hashMap.put("countOrder", countOrder);
        hashMap.put("takeCount", takeCount);
        hashMap.put("takeCount2", takeCount2);
        hashMap.put("takeMoney", takeMoney);
        hashMap.put("takeMoney1", takeMoney1);
        hashMap.put("cancelOrderCount", cancelOrderCount);
        hashMap.put("cancelOrderMoney", cancelOrderMoney);
        return Result.success().put("data", hashMap);
    }

    @Override
    public Result selectTopUpStatistics(String date, String dateType) {
        BigDecimal topUpStatistics = dataCentreDao.selectTopUpStatistics(date, dateType);

        return Result.success().put("data", topUpStatistics);
    }

    @Override
    public Result findAllCertification(Integer page,Integer limit,String userName,String phone, String checkCertification,Integer riderStationId) {
        Page<UserEntity> pages=new Page<>(page,limit);
        return Result.success().put("data", new PageUtils(dataCentreDao.findAllCertification(pages, userName, phone,checkCertification, riderStationId)));
    }

    @Transactional
    @Override
    public Result checkCertification(Long userId, String checkCertification, String checkCertificationMessage) {
        dataCentreDao.checkCertification(userId, checkCertification, checkCertificationMessage);
        return Result.success();
    }

    @Override
    public Result findCertification(Long userId) {
        UserEntity certification = dataCentreDao.findCertification(userId);
        return Result.success().put("data", certification);
    }

    @Override
    public Result rankingList(Integer page, Integer limit, String address,String date, String dateType,Integer riderStationId) {
        Page<TbIndent> pages=new Page<>(page,limit);
        PageUtils pageUtils = new PageUtils(dataCentreDao.rankingList(pages, address, date, dateType,riderStationId));
        return Result.success().put("data", pageUtils);
    }

    @Override
    public Result selectShopCenter(ShopCenterQuery query) {
        HashMap hashMap = new HashMap();
        //新增门店数量
        int newShopCount = dataCentreDao.selectNewShopCount(query);
        //门店收益排行榜
        Page<TbOrder> pages=new Page<>(query.getPage(),query.getLimit());
        //计算年月日开始结束时间
        DataCenterQuery dataCenterQuery=query;
        dataCenterQuery=DateUtils.dateStrEndTime(dataCenterQuery);
        query.setStartTime(dataCenterQuery.getStartTime());
        query.setEndTime(dataCenterQuery.getEndTime());
        IPage<TbOrder> tbOrderIPage = dataCentreDao.selectRankingList(pages, query);
        for(int i = 0;i<query.getLimit();i++){
            Integer a = ((query.getPage()-1)*query.getLimit())+i+1;
            if(tbOrderIPage.getRecords().size()>i){
                tbOrderIPage.getRecords().get(i).setRank(a);
            }
        }
        PageUtils pageUtils = new PageUtils(tbOrderIPage);
        hashMap.put("newShopCount", newShopCount);
        hashMap.put("pageUtils", pageUtils);
        TbOrder tbOrder=dataCentreDao.selectRankingListAmount(query);
        hashMap.put("moneyAmount", tbOrder.getShopMoney());
        hashMap.put("shopIncomeMoney", tbOrder.getShopIncomeMoney());
        return Result.success().put("data", hashMap);
    }

    @Override
    public ExcelData excelShopCenter(ShopCenterQuery query) {
        List<TbOrder> tbOrderList = dataCentreDao.excelShopCenter(query);
        ExcelData data = new ExcelData();
        data.setName("商家收益排行");
        data.setTitles(WalletDetailExportTitle());
        List<List<Object>> rows = new ArrayList<>();
        for (TbOrder tbOrder:tbOrderList ){
            List<Object> row = new ArrayList<>();
            row.add(tbOrder.getShopId());
            row.add(tbOrder.getShopName());
            row.add(tbOrder.getShopTypeName());
            row.add(tbOrder.getRank());
            row.add(tbOrder.getShopMoney());
            row.add(tbOrder.getShopIncomeMoney());
            rows.add(row);
        }
        data.setRows(rows);
        return data;
    }

    private List<String> WalletDetailExportTitle() {
        return Arrays.asList(
                "编号",
                "店铺名称",
                "商铺类型",
                "排名",
                "收益",
                "实际收入");
    }
    @Override
    public Result selectUserCenter(DataCenterQuery query) {
        HashMap hashMap = new HashMap();
        int userCount = dataCentreDao.allUserCount(query);
        int phoneUserCount = dataCentreDao.phoneUserCount(query);
        hashMap.put("allUserCount", userCount);
        hashMap.put("phoneUserCount", phoneUserCount);
        return Result.success().put("data", hashMap);
    }

    @Override
    public Result selectUserFeedback(String userEmail, Integer page, Integer limit) {
        Page<Feedback> pages=new Page<>(page,limit);
        PageUtils pageUtils = new PageUtils(dataCentreDao.selectUserFeedback(pages, userEmail));
        return Result.success().put("data", pageUtils);
    }

    @Override
    public Result findUserAddIndent(Long userId, Integer page, Integer limit) {
        Page<TbIndent> pages=new Page<>(page,limit);
        PageUtils pageUtils = new PageUtils(dataCentreDao.findUserAddIndent(pages, userId));
        return Result.success().put("data", pageUtils);
    }

    @Override
    public Result findUserReceivingIndent(Long userId, Integer page, Integer limit) {
        Page<TbIndent> pages=new Page<>(page,limit);
        PageUtils pageUtils = new PageUtils(dataCentreDao.findUserReceivingIndent(pages, userId));
        return Result.success().put("data", pageUtils);
    }

    @Override
    public Result findTopUpMoney(Long userId, Integer page, Integer limit, String startTime, String endTime){
        Page<PayDetails> pages=new Page<>(page,limit);
        PageUtils pageUtils = new PageUtils(dataCentreDao.findTopUpMoney(pages, userId, startTime, endTime));
        return Result.success().put("data", pageUtils);
    }

    @Override
    public Result findWithdrawMoney(Long userId, Integer page, Integer limit){
        Page<CashOut> pages=new Page<>(page,limit);
        PageUtils pageUtils = new PageUtils(dataCentreDao.findWithdrawMoney(pages, userId));
        return Result.success().put("data", pageUtils);
    }

    @Override
    public Result findplatformMoney(String dateType, String date) {
        HashMap hashMap = new HashMap();
        BigDecimal indentMoney = dataCentreDao.billMoney(dateType, date);
        BigDecimal riderMoney = dataCentreDao.riderMoney(dateType, date);
        BigDecimal platformMoney = dataCentreDao.platformMoney(dateType, date);
        hashMap.put("indentMoney",indentMoney);
        hashMap.put("riderMoney",riderMoney);
        hashMap.put("platformMoney",platformMoney);
        return Result.success().put("data", hashMap);
    }

    @Override
    public Result selectCashDeposit(String phone, Integer type, Integer page, Integer limit, Long userId) {
        Page<UserMoneyDetails> pages=new Page<>(page,limit);
        PageUtils pageUtils = new PageUtils(dataCentreDao.selectCashDeposit(pages, phone, type, userId));
        return Result.success().put("data", pageUtils);
    }

    @Override
    public Result tcwmplatformMoney(String date, String dateType) {
        HashMap<String, Object> hashMap = new HashMap();
        //总收入
        BigDecimal allBigDecimal = dataCentreDao.tcwmplatformMoney(date, dateType);
        //商家收入
        BigDecimal shopBigDecimal = dataCentreDao.tcwmShopMoney(date, dateType);
        //商铺收入
        BigDecimal adminBigDecimal = allBigDecimal.subtract(shopBigDecimal);
        hashMap.put("allBigDecimal", allBigDecimal);
        hashMap.put("adminBigDecimal", adminBigDecimal);
        hashMap.put("shopBigDecimal", shopBigDecimal);
        return Result.success().put("data",hashMap);
    }

    @Override
    public Result selectFeedbackList(Integer page, Integer limit, Integer type) {
        Page<Feedback> pages = new Page<>(page, limit);
        PageUtils pageUtils = new PageUtils(dataCentreDao.selectFeedbackList(pages, type));
        return Result.success().put("data", pageUtils);
    }

    @Transactional
    @Override
    public Result presenterVip(Long userId) {
        UserEntity user = userDao.selectById(userId);
        if(user.getIsVip() ==1 && VipExpirationUtil.isVipValid(user.getVipExpirationTime())){
            return Result.error("该用户已经是会员，不能重复添加！");
        }

        // 读取配置
        CommonInfo one = commonInfoService.findOne(314);
        CommonInfo one1 = commonInfoService.findOne(315);
        CommonInfo one2 = commonInfoService.findOne(316);

        // 会员失效时间
        String expirationTime = VipExpirationUtil.getFutureTimeWithDays(Integer.valueOf(one.getValue()));

        // 更新用户为会员
        userService.updateUserToVip(userId, expirationTime);

        // 新增会员专属优惠券
        for(int i = 0;i<Integer.valueOf(one1.getValue());i++){
            tbCouponUserService.addAfterVipBuySuccess(userId, new BigDecimal(one2.getValue()), one.getValue(), expirationTime);
        }
        return Result.success();
    }
    @Override
    public ExcelData excelRankingList(RankListQuery query) {
        List<TbIndent> tbOrderList = dataCentreDao.excelRankList(query);
        ExcelData data = new ExcelData();
        data.setName("骑手排行");
        List<String> titleList=Arrays.asList(
                "排名",
                "骑手昵称",
                "骑手姓名",
                "骑手余额",
                "地区 ",
                "骑手所在站点",
                "总收益");
        data.setTitles(titleList);
        List<List<Object>> rows = new ArrayList<>();
        for (TbIndent tbOrder:tbOrderList ){
            List<Object> row = new ArrayList<>();
            row.add(tbOrder.getRankNum());
            row.add(tbOrder.getNickName());
            row.add(tbOrder.getRiderNickName());
            row.add(tbOrder.getRiderBalance());
            row.add(tbOrder.getUserProvince()+tbOrder.getUserCity()+tbOrder.getUserDistrict());
            row.add(tbOrder.getStationName());
            row.add(tbOrder.getMoneyOrder());
            rows.add(row);
        }
        data.setRows(rows);
        return data;
    }

    @Override
    public Result updateCertification(UserEntity userEntity) {
        userDao.updateById(userEntity);
        return Result.success();
    }
}
