package com.iformall.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.iformall.common.ErrorCode;
import com.iformall.common.IdWorker;
import com.iformall.common.Result;
import com.iformall.common.ResultData;
import com.iformall.domain.po.WxMall;
import com.iformall.domain.po.WxMerchant;
import com.iformall.domain.po.WxMerchantBUser;
import com.iformall.domain.po.WxMerchantTradeDaily;
import com.iformall.domain.vo.WxMerchantTradeDailyVo;
import com.iformall.mapper.WxMerchantTradeDailyMapper;
import com.iformall.mapper.WxShopMapper;
import com.iformall.service.*;
import com.iformall.utils.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class WxMerchantTradeDailyServiceImpl implements WxMerchantTradeDailyService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    WxMerchantTradeDailyMapper wxMerchantTradeDailyMapper;

    @Autowired
    WxMerchantBUserService wxMerchantBUserService;

    @Autowired
    WxMerchantService wxMerchantService;

    @Autowired
    WxMallService wxMallService;

    @Autowired
    ExcelService excelService;

    @Autowired
    WxShopMapper wxShopMapper;


    @Override
    public PageInfo<WxMerchantTradeDaily> listAsPage(WxMerchantTradeDaily record, Integer pageIndex, Integer pageSize) {
        return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxMerchantTradeDailyMapper.findList(record));
    }

    @Override
    public WxMerchantTradeDaily getById(Long id) {
        return wxMerchantTradeDailyMapper.selectById(id);
    }

    @Override
    public void saveOrUpdate(WxMerchantTradeDaily record) {
        if (record.getId() == null) {
            //record.setId(UUID.randomUUID().toString().replaceAll("-", ""));
            final IdWorker idWorker = IdWorker.get();
            record.setId(idWorker.nextId());
            record.setCreateDate(new Date());
            record.setUpdateDate(new Date());
            wxMerchantTradeDailyMapper.insert(record);
        } else {
            record.setUpdateDate(new Date());
            wxMerchantTradeDailyMapper.updateById(record);
        }
    }

    @Override
    public void deleteById(Long id) {
        wxMerchantTradeDailyMapper.deleteById(id);
    }

    @Override
    public ResultData saveDailyTradingVolume(Long userId, Integer volume) {

        WxMerchantBUser user = wxMerchantBUserService.getById(userId);

        if (user == null)
            return new ResultData(ErrorCode.USER_IS_EMPTY);

        WxMerchant merchant = wxMerchantService.getById(user.getMerchantId());

        if (merchant == null)
            return new ResultData(ErrorCode.MERCHANT_INFO_NOT_FOUND);

        WxMall mall = wxMallService.getByTenantId(merchant.getTenantId());
        if (mall == null)
            return new ResultData(ErrorCode.MERCHANT_INFO_NOT_FOUND);


        WxMerchantTradeDaily wxMerchantTradeDaily = new WxMerchantTradeDaily();

        wxMerchantTradeDaily.setMerchantId(merchant.getId());

        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        wxMerchantTradeDaily.setReportDate(fmt.format(new Date()));


        List<WxMerchantTradeDaily> tradeList = wxMerchantTradeDailyMapper.findList(wxMerchantTradeDaily);

        if (tradeList.size() > 0) {
            wxMerchantTradeDaily = tradeList.get(0);
            wxMerchantTradeDaily.setTradeAmt(volume + "");
            wxMerchantTradeDaily.setUpdateDate(new Date());
            wxMerchantTradeDailyMapper.updateById(wxMerchantTradeDaily);
            return new ResultData(wxMerchantTradeDaily);
        }

        final IdWorker idWorker = IdWorker.get();
        wxMerchantTradeDaily.setId(idWorker.nextId());
        wxMerchantTradeDaily.setTenantId(merchant.getTenantId());
        wxMerchantTradeDaily.setMerchantId(merchant.getId());
        wxMerchantTradeDaily.setbUserId(userId);
        wxMerchantTradeDaily.setTradeAmt(volume + "");
        wxMerchantTradeDaily.setCreateDate(new Date());
        wxMerchantTradeDaily.setUpdateDate(new Date());
        wxMerchantTradeDailyMapper.insert(wxMerchantTradeDaily);

        return new ResultData(wxMerchantTradeDaily);

    }


    @Override
    public PageInfo<WxMerchantTradeDailyVo> listAsPageVo(WxMerchantTradeDaily record, Integer pageIndex, Integer pageSize) {
        return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxMerchantTradeDailyMapper.findVoList(record));
    }

    @Override
    public ResultData update(WxMerchantTradeDaily tradeDaily) {

        WxMerchantTradeDaily wxMerchantTradeDaily = new WxMerchantTradeDaily();
        wxMerchantTradeDaily.setMerchantId(tradeDaily.getMerchantId());
        wxMerchantTradeDaily.setReportDate(tradeDaily.getReportDate());

        List<WxMerchantTradeDaily> tradeList = wxMerchantTradeDailyMapper.findList(wxMerchantTradeDaily);

        if (tradeList.size() > 0) {
            wxMerchantTradeDaily = tradeList.get(0);
            wxMerchantTradeDaily.setUpdateDate(new Date());
            wxMerchantTradeDaily.setTradeAmt(tradeDaily.getTradeAmt() + "");
            wxMerchantTradeDaily.setTradeCount(tradeDaily.getTradeCount());
            wxMerchantTradeDaily.setProof(tradeDaily.getProof());
            wxMerchantTradeDailyMapper.updateById(wxMerchantTradeDaily);
            return new ResultData(wxMerchantTradeDaily);
        }

        final IdWorker idWorker = IdWorker.get();
        wxMerchantTradeDaily.setId(idWorker.nextId());
        wxMerchantTradeDaily.setTenantId(tradeDaily.getTenantId());
        wxMerchantTradeDaily.setMerchantId(tradeDaily.getMerchantId());
        wxMerchantTradeDaily.setTradeAmt(tradeDaily.getTradeAmt() + "");
        wxMerchantTradeDaily.setCreateDate(new Date());
        wxMerchantTradeDaily.setUpdateDate(new Date());
        wxMerchantTradeDaily.setTradeCount(tradeDaily.getTradeCount());
        wxMerchantTradeDaily.setProof(tradeDaily.getProof());
        wxMerchantTradeDailyMapper.insert(wxMerchantTradeDaily);

        return new ResultData(Result.SUCCESS);
    }

    @Override
    public ResultData queryTradeDaily(WxMerchantTradeDaily tradeDaily) {
        WxMerchantTradeDaily wxMerchantTradeDaily = new WxMerchantTradeDaily();
        wxMerchantTradeDaily.setMerchantId(tradeDaily.getMerchantId());
        wxMerchantTradeDaily.setReportDate(tradeDaily.getReportDate());
        List<WxMerchantTradeDaily> tradeList = wxMerchantTradeDailyMapper.findList(wxMerchantTradeDaily);
        wxMerchantTradeDaily = tradeList.size() > 0 ? tradeList.get(0) : new WxMerchantTradeDaily();
        return new ResultData(wxMerchantTradeDaily);
    }

    @Override
    public void exportData(WxMerchantTradeDaily tradeDaily, HttpServletRequest request, HttpServletResponse response) {
        //没有商户ID导出全部数据
        List<WxMerchantTradeDailyVo> list = wxMerchantTradeDailyMapper.findVoList(tradeDaily);

        list.stream().forEach(m -> {
            //商铺信息
            m.setShopVos(wxShopMapper.findShopVoList(m.getMerchantId()));
        });
        //商铺信息

        excelService.exportExcel(list, "商户解单数据", "商户解单数据", WxMerchantTradeDailyVo.class, "商户解单数据.xlsx", response, false);
    }

    @Override
    public ResultData summary(WxMerchantTradeDaily record) {
        List<WxMerchantTradeDailyVo> voList = wxMerchantTradeDailyMapper.findVoList(record);
        Integer tradeAmt = voList.stream().collect(Collectors.summingInt(WxMerchantTradeDailyVo::getTradeAmt));
        Integer tradeCount = voList.stream().collect(Collectors.summingInt(WxMerchantTradeDailyVo::getTradeCount));
        Map<String, Object> data = new HashMap<>();
        data.put("tradeAmt", tradeAmt);
        data.put("tradeCount", tradeCount);
        return new ResultData(data);
    }

    @Override
    public ResultData getVolumeOfMonth(Long merchantId) {

        WxMerchant merchant = wxMerchantService.getById(merchantId);
        if (merchant == null)
            return new ResultData(ErrorCode.MERCHANT_INFO_NOT_FOUND);
        WxMerchantTradeDaily wxMerchantTradeDaily = new WxMerchantTradeDaily();
        wxMerchantTradeDaily.setMerchantId(merchantId);
        String startTime = DateUtils.getTimeBefore(29, new Date());
        String endTime = DateUtils.getSystemTime("yyyy-MM-dd");
        wxMerchantTradeDaily.setStartTime(startTime);
        wxMerchantTradeDaily.setEndTime(endTime);
        List<WxMerchantTradeDailyVo> recordList = wxMerchantTradeDailyMapper.findVoList(wxMerchantTradeDaily);
        Map<String, WxMerchantTradeDailyVo> recordMap = recordList.stream().collect(Collectors.toMap(WxMerchantTradeDailyVo::getReportDate, r -> r));

        List<WxMerchantTradeDailyVo> tradeList = new ArrayList<>();
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat fmtv = new SimpleDateFormat("MM/dd");
        for (int i = 0; i < 30; i++) {
            cal.setTime(new Date());
            cal.add(Calendar.DAY_OF_YEAR, -i);
            WxMerchantTradeDailyVo trade = recordMap.get(fmt.format(cal.getTime()));
            if (trade != null) {
                trade.setReportDate(fmtv.format(cal.getTime()));
                trade.setTenantId(null);
                trade.setMerchantId(null);
                trade.setMerchantName(null);
                tradeList.add(trade);
            } else {
                trade = new WxMerchantTradeDailyVo();
                trade.setTradeAmt(0);
                trade.setReportDate(fmtv.format(cal.getTime()));
                tradeList.add(trade);
            }
            cal.clear();
        }
        Collections.reverse(tradeList);
        return new ResultData(tradeList);
    }

    @Override
    public ResultData getVolumeTotalOfMonth(String tenantId) {


        WxMerchantTradeDaily wxMerchantTradeDaily = new WxMerchantTradeDaily();
        wxMerchantTradeDaily.setTenantId(tenantId);

        List<WxMerchantTradeDaily> recordList = wxMerchantTradeDailyMapper.findTotalListOfMonth(wxMerchantTradeDaily);
        Map<String, WxMerchantTradeDaily> recordMap = recordList.stream().collect(Collectors.toMap(WxMerchantTradeDaily::getReportDate, r -> r));

        List<WxMerchantTradeDaily> tradeList = new ArrayList<>();
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat fmtv = new SimpleDateFormat("MM/dd");
        for (int i = 0; i < 30; i++) {
            cal.setTime(new Date());
            cal.add(Calendar.DAY_OF_MONTH, -i);
            System.out.println(fmt.format(cal.getTime()));
            WxMerchantTradeDaily trade = recordMap.get(fmt.format(cal.getTime()));
            if (trade != null) {
                trade.setReportDate(fmtv.format(cal.getTime()));
                tradeList.add(trade);
            } else {
                trade = new WxMerchantTradeDaily();
                trade.setTradeAmt("0");
                trade.setReportDate(fmtv.format(cal.getTime()));
                tradeList.add(trade);
            }
            cal.clear();
        }

        Collections.reverse(tradeList);
        return new ResultData(tradeList);
    }

    @Override
    public ResultData getVolume(WxMerchantTradeDaily merchantTradeDaily, Long userId) {
        WxMerchantBUser user = wxMerchantBUserService.getById(userId);
        if (user == null)
            return new ResultData(ErrorCode.USER_IS_EMPTY);
        WxMerchant merchant = wxMerchantService.getById(user.getMerchantId());
        if (merchant == null)
            return new ResultData(ErrorCode.MERCHANT_INFO_NOT_FOUND);
        WxMall mall = wxMallService.getByTenantId(merchant.getTenantId());
        if (mall == null)
            return new ResultData(ErrorCode.MERCHANT_INFO_NOT_FOUND);

        WxMerchantTradeDaily wxMerchantTradeDaily = new WxMerchantTradeDaily();
        wxMerchantTradeDaily.setMerchantId(merchant.getId());

        if (merchantTradeDaily.getReportDate() != null) {
            wxMerchantTradeDaily.setReportDate(merchantTradeDaily.getReportDate());
        } else {
            SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
            wxMerchantTradeDaily.setReportDate(fmt.format(new Date()));
        }

        List<WxMerchantTradeDaily> tradeList = wxMerchantTradeDailyMapper.findList(wxMerchantTradeDaily);

        if (tradeList.size() > 0) {
            wxMerchantTradeDaily = tradeList.get(0);
            return new ResultData(wxMerchantTradeDaily);
        }

        return new ResultData(ErrorCode.DALIY_REPORT_VOLUME_TODAY_NULL);

    }

    @Override
    public ResultData getVolumeOfWeek(Long userId) {

        WxMerchantBUser user = wxMerchantBUserService.getById(userId);

        if (user == null)
            return new ResultData(ErrorCode.USER_IS_EMPTY);

        WxMerchant merchant = wxMerchantService.getById(user.getMerchantId());

        if (merchant == null)
            return new ResultData(ErrorCode.MERCHANT_INFO_NOT_FOUND);

        WxMall mall = wxMallService.getByTenantId(merchant.getTenantId());
        if (mall == null)
            return new ResultData(ErrorCode.MERCHANT_INFO_NOT_FOUND);


        WxMerchantTradeDaily wxMerchantTradeDaily = new WxMerchantTradeDaily();

        wxMerchantTradeDaily.setMerchantId(merchant.getId());

        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        wxMerchantTradeDaily.setReportDate(fmt.format(new Date()));

        return new ResultData(wxMerchantTradeDailyMapper.findListOfWeek(wxMerchantTradeDaily));

    }

}
