package com.crm.custom.service.impl;

import com.crm.custom.dao.mapper.GoldenOrderMapper;
import com.crm.custom.dao.repository.*;
import com.crm.custom.service.GoldenOrderService;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.constant.EmailSendEnum;
import com.crm.rely.backend.core.constant.MapConstants;
import com.crm.rely.backend.core.dto.base.PageDto;
import com.crm.rely.backend.core.dto.base.ResultWithPagerDto;
import com.crm.rely.backend.core.entity.system.email.SysEmailSendEntity;
import com.crm.rely.backend.core.exception.ServiceException;
import com.crm.rely.backend.model.constant.ConfigConstants;
import com.crm.rely.backend.model.constant.EmailTemplateConstants;
import com.crm.rely.backend.model.constant.PayConstants;
import com.crm.rely.backend.model.dto.golden.order.GoldenOrderDetailsDto;
import com.crm.rely.backend.model.dto.golden.order.GoldenOrderListDto;
import com.crm.rely.backend.model.entity.custom.info.CustomInfoEntity;
import com.crm.rely.backend.model.entity.golden.order.GoldenOrderAddEntity;
import com.crm.rely.backend.model.entity.golden.order.GoldenOrderSearchEntity;
import com.crm.rely.backend.model.pojo.table.*;
import com.crm.rely.backend.service.EmailService;
import com.crm.rely.backend.service.MqSendService;
import com.crm.rely.backend.util.DateUtil;
import com.crm.rely.backend.util.GetRandom;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@Service
public class GoldenOrderServiceImpl implements GoldenOrderService {

    @Autowired
    private GoldenOrderMapper mapper;
    @Autowired
    private GoldenOrderRepository repository;
    @Autowired
    private CustomInfoRepository customInfoRepository;
    @Autowired
    private FinanceDepositRepository financeDepositRepository;
    @Autowired
    private GoldenOrderDetailsRepository goldenOrderDetailsRepository;
    @Autowired
    private GoldenGoodsRepository goldenGoodsRepository;
    @Autowired
    private MqSendService mqSendService;
    @Autowired
    private EmailService emailService;


    @Override
    public ResultWithPagerDto<GoldenOrderListDto> searchPageList(GoldenOrderSearchEntity entity) throws ServiceException {
        Integer count = mapper.countList(entity);
        PageDto pageDto = PageDto.format(entity, count);
        if (count == null || count <= 0) {
            return ResultWithPagerDto.success(pageDto);
        }
        List<GoldenOrderTable> tables = mapper.pageList(entity);
        if (tables == null || tables.size() <= 0) {
            throw new ServiceException(Constants.SYSTEM_ERROR);
        }
        List<String> serialList = new ArrayList<>();
        for (GoldenOrderTable table : tables) {
            serialList.add(table.getSerial());
        }

        Map<String,List<GoldenOrderDetailsDto>> map = new HashMap<>();
        List<GoldenOrderDetailsDto> detailsDtos = mapper.getListBySerial(serialList);
        for (GoldenOrderDetailsDto dto : detailsDtos) {
            List<GoldenOrderDetailsDto> dtos = null;
            if (map.containsKey(dto.getSerial())) {
                dtos = map.get(dto.getSerial());
            }else {
                dtos = new ArrayList<>();
            }
            dtos.add(dto);

            map.put(dto.getSerial(), dtos);
        }


        List<GoldenOrderListDto> dtos = new ArrayList<>(tables.size());
        for (GoldenOrderTable table : tables) {
            GoldenOrderListDto dto = transformSearchListDto(table);
            dto.setDetails(map.get(table.getSerial()));
            dtos.add(dto);
        }

        return ResultWithPagerDto.success(pageDto, dtos);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void completeOrder(Long id) throws ServiceException {
        GoldenOrderTable table = repository.findFirstById(id);
        if (table == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        if (table.getStatus() != PayConstants.ORDER_UP_PAY_STATUS) {
            throw ServiceException.exception("不能确认订单");
        }

        CustomInfoTable customTable =  customInfoRepository.findFirstById(table.getCustomId());
        if (customTable == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }

        FinanceDepositTable depositTable = financeDepositRepository.findFirstBySerial(table.getSerial());
        if (depositTable == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }

        table.setStatus(PayConstants.ORDER_PAY_STATUS);
        table.setPayTime(new Date());
        table.setModifyTime(new Date());
        repository.save(table);

        depositTable.setStatus(PayConstants.MANAGER_COMPLETED_STATUS);
        depositTable.setModifyTime(new Date());
        financeDepositRepository.save(depositTable);

        BigDecimal totalSpendingAmount = customTable.getTotalSpendingAmount() == null ? BigDecimal.ZERO : customTable.getTotalSpendingAmount();
        customTable.setTotalSpendingAmount(totalSpendingAmount.add(table.getAmount()));
        customInfoRepository.save(customTable);

        List<GoldenOrderDetailsTable> detailsTables =  goldenOrderDetailsRepository.getBySerial(table.getSerial());
        for (GoldenOrderDetailsTable detailsTable : detailsTables) {
            sendCustomGoldenOrderEmail(table.getPayName(),detailsTable.getDownload(),customTable.getEmail());
        }

        if (customTable.getTotalSpendingAmount().compareTo(new BigDecimal(5000)) >= 0) {
            mqSendService.send(ConfigConstants.CUSTOM_REWARD_RECORD, customTable.getId());
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelOrder(Long id) throws ServiceException {
        GoldenOrderTable table = repository.findFirstById(id);
        if (table == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        if (table.getStatus() != PayConstants.ORDER_UP_PAY_STATUS) {
            throw ServiceException.exception("cancel_error");
        }

        table.setStatus(PayConstants.ORDER_PAY_CANCEL_STATUS);
        table.setModifyTime(new Date());
        repository.save(table);

    }

    @Override
    public void generated(GoldenOrderAddEntity entity, CustomInfoEntity infoEntity) throws ServiceException {
        GoldenGoodsTable goodsTable = goldenGoodsRepository.getFirstById(entity.getGoodsId());
        if (goodsTable == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        if (goodsTable.getGoodsPrice().compareTo(BigDecimal.ZERO) > 0) {
            throw ServiceException.exception("请下单购买！");
        }

        GoldenOrderDetailsTable details = mapper.getByCustomIdAndGoodsId(infoEntity.getId(),entity.getGoodsId());
        if (details != null) {
            throw ServiceException.exception("课程已购买");
        }

        String orderNo = GetRandom.getOrderNo(PayConstants.DEPOSIT_HEAD);
        GoldenOrderTable table = new GoldenOrderTable();
        table.setSerial(orderNo);
        table.setCId(infoEntity.getCId());
        table.setCustomId(infoEntity.getId());
        table.setEmail(infoEntity.getEmail());
        table.setStatus(PayConstants.ORDER_PAY_STATUS);
        table.setAmount(BigDecimal.ZERO);
        table.setCurrency("USD");
        table.setTransformAmount(BigDecimal.ZERO);
        table.setTransformCurrency("USD");
        table.setPayName(infoEntity.getName());
        table.setPayPhone(infoEntity.getPhone());
        table.setPayTime(new Date());
        table.setAddTime(new Date());
        repository.save(table);

        GoldenOrderDetailsTable detailsTable = new GoldenOrderDetailsTable();
        BeanUtils.copyProperties(goodsTable, detailsTable);
        detailsTable.setId(null);
        detailsTable.setGoodsId(goodsTable.getId());
        detailsTable.setSerial(orderNo);
        detailsTable.setCustomId(infoEntity.getId());
        goldenOrderDetailsRepository.save(detailsTable);

        sendCustomGoldenOrderEmail(infoEntity.getName(), detailsTable.getDownload(), infoEntity.getEmail());

    }

    private GoldenOrderListDto transformSearchListDto(GoldenOrderTable table) {
        GoldenOrderListDto dto = new GoldenOrderListDto();
        BeanUtils.copyProperties(table, dto);
        return dto;
    }

    private void sendCustomGoldenOrderEmail(String name, String download, String email) throws ServiceException {

        //构建map 用于后面邮件模版替换
        Map<String, String> map = new HashMap<>(3);

        map.put(MapConstants.NAME, name);

        map.put(ConfigConstants.DOWNLOAD_URL, download);
        map.put(MapConstants.DATE_TIME, DateUtil.formatTime(new Date()));

        SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity();
        sysEmailSendEntity.setSubject("Trading Education");
        sysEmailSendEntity.setEmailSendEnum(EmailSendEnum.CUSTOM_ORDER_SUCCESS);
        sysEmailSendEntity.setMap(map);
        sysEmailSendEntity.setTemplateName(EmailTemplateConstants.CUSTOM_ORDER_SUCCESS_CN);

        sysEmailSendEntity.setUsers(email);
        try {
            emailService.sendEmail(sysEmailSendEntity);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
