package cn.pluss.platform.bill.impl;

import cn.pluss.platform.bill.BillSendRecordService;
import cn.pluss.platform.entity.BillSendRecord;
import cn.pluss.platform.entity.MerchantBaseInfo;
import cn.pluss.platform.entity.UserApp;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.export.BillStatisticsService;
import cn.pluss.platform.mapper.BillSendRecordMapper;
import cn.pluss.platform.merchant.MerchantBaseInfoService;
import cn.pluss.platform.service.EmailService;
import cn.pluss.platform.task.BillStatisticsHandler;
import cn.pluss.platform.userApp.UserAppService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.Setter;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Djh
 * @since 2021-05-10
 */
@Service
public class BillSendRecordServiceImpl extends ServiceImpl<BillSendRecordMapper, BillSendRecord> implements BillSendRecordService {


    /**
     * 电子邮箱格式校验正则
     */
    public final static String EMAIL_REG = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";

    /**
     * 最大目标邮箱个数
     */
    public final static int MAX_EMAIL_TARGET = 3;

    /**
     * 一天最大生成报表次数
     */
    public final static int MAX_EMAIL_DAY_COUNT = 3;

    /**
     * 报表生成最低间隔时间
     */
    public final static Long MIN_DURING = 60 * 1000L;

    @Setter(onMethod_ = {@Autowired})
    private BillStatisticsService billStatisticsService;

    @Setter(onMethod_ = {@Autowired})
    private EmailService emailService;

    @Setter(onMethod_ = {@Autowired})
    private UserAppService userAppService;

    @Setter(onMethod_ = {@Autowired})
    private MerchantBaseInfoService merchantBaseInfoService;

    @Setter(onMethod_ = {@Autowired, @Lazy})
    private BillStatisticsHandler billStatisticsHandler;

    @Override
    public void reqBill(BillSendRecord entity) {
        if (entity.getUserId() == null) {
            throw new MsgException("缺少用户id");
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date currentDate = new Date();
        String currentDateStr = sdf.format(currentDate);

        if (entity.getStartTime() == null) {
            throw new MsgException("缺少开始时间");
        }

        String startDate = sdf.format(entity.getEndTime());

        if (startDate.compareTo(currentDateStr) > 0) {
            throw new MsgException("非法的开始时间");
        }

        // 将起始时间设置为一天的开始
        Calendar instance = Calendar.getInstance();
        instance.setTime(entity.getStartTime());
        instance.set(Calendar.HOUR_OF_DAY, 0);
        instance.set(Calendar.MINUTE, 0);
        instance.set(Calendar.SECOND, 0);
        instance.set(Calendar.MILLISECOND, 0);
        entity.setStartTime(instance.getTime());

        if (entity.getEndTime() == null) {
            throw new MsgException("缺少截止时间");
        }


        String endDate = sdf.format(entity.getEndTime());

        if (endDate.compareTo(currentDateStr) >= 0) {
            entity.setEndTime(currentDate);
        }

        if (entity.getEmail() == null) {
            throw new MsgException("缺少目标邮箱");
        }

        Pattern p = Pattern.compile(EMAIL_REG);

        String[] split = entity.getEmail().split(",");
        if (split.length > MAX_EMAIL_TARGET) {
            throw new MsgException("最多指定三个邮箱");
        }

        for (String email: split) {
            Matcher matcher = p.matcher(email);
            if (!matcher.matches()) {
                throw new MsgException("存在不合法邮箱，请检查邮箱格式是否正确");
            }
        }


        UserApp userApp = userAppService.queryUserAppByToken();
        if (!entity.getUserId().equals(userApp.getUserId())) {
            throw new MsgException("拒绝访问");
        }

        String date = sdf.format(currentDate);

        // 报表次数限制
        QueryWrapper<BillSendRecord> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("userId", entity.getUserId());
        queryWrapper1.likeRight("createTime", date);
        Integer todayCount = baseMapper.selectCount(queryWrapper1);
        if (todayCount >= MAX_EMAIL_DAY_COUNT) {
            throw new MsgException("账单报表一天只能生成3次");
        }

        // 报表时间间隔
        QueryWrapper<BillSendRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId", entity.getUserId());
        queryWrapper.orderByDesc("createTime");
        queryWrapper.last("limit 1");
        BillSendRecord one = getOne(queryWrapper);
        if (one != null) {
            long during = System.currentTimeMillis() - one.getCreateTime().getTime();
            if (during < MIN_DURING) {
                throw new MsgException("操作过于频繁, 请于一分钟后再操作");
            }
        }

        entity.setStatus("0");
        save(entity);

        billStatisticsHandler.execute(entity);
    }

    @Override
    public XSSFWorkbook createBill(BillSendRecord entity) {
        UserApp userApp = new UserApp();
        userApp.setUserId(entity.getUserId());
        userApp = userAppService.queryUserApp(userApp);

        String merchantCode = userApp.getMerchantCode();
        Date startTime = entity.getStartTime();
        Date endTime= entity.getEndTime();

        XSSFWorkbook workBook = billStatisticsService.createBillStatisticsSheet(null, merchantCode, startTime, endTime);
        workBook = billStatisticsService.createBillListSheet(workBook, merchantCode, startTime, endTime);
        workBook = billStatisticsService.createMemberBillStatisticsSheet(workBook, merchantCode, startTime, endTime);
        workBook = billStatisticsService.createMemberBillListSheet(workBook, merchantCode, startTime, endTime);
        workBook = billStatisticsService.createStaffBillStatisticsSheet(workBook, merchantCode, startTime, endTime);

        return workBook;
    }

    @Override
    public void sendBill(BillSendRecord entity, XSSFWorkbook workbook) {
        MerchantBaseInfo merchantBaseInfo = new MerchantBaseInfo();
        merchantBaseInfo.setUserId(entity.getUserId() + "");
        merchantBaseInfo = merchantBaseInfoService.queryMerchantBaseInfo(merchantBaseInfo);

        String[] tos = entity.getEmail().split(",");
        // 抄送邮件设置为自己
        String[] ccs = new String[]{"caiwu@shouyinbei.com"};

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        String title = merchantBaseInfo.getAlias() + "_" + sdf.format(entity.getStartTime()) + "~" + sdf.format(entity.getEndTime()) + "账单报表";
        String content = "账单明细，请查看附件";

        emailService.sendEmail(tos, ccs, title, content, workbook, title + ".xlsx");
    }
}
