package com.cool.store.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.cool.store.context.LoginUserInfo;
import com.cool.store.dao.HyPartnerUserInfoDAO;
import com.cool.store.dao.LineInfoDAO;
import com.cool.store.dao.LinePayDAO;
import com.cool.store.dao.ShopStageInfoDAO;
import com.cool.store.entity.*;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.MessageEnum;
import com.cool.store.enums.WorkflowSubStageEnum;
import com.cool.store.enums.WorkflowSubStageStatusEnum;
import com.cool.store.enums.point.PayBusinessTypeEnum;
import com.cool.store.enums.point.PayTypeEnum;
import com.cool.store.enums.point.ShopSubStageStatusEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.FranchiseFeeMapper;
import com.cool.store.mapper.LineInfoMapper;
import com.cool.store.mapper.ShopInfoMapper;
import com.cool.store.request.LinePaySubmitRequest;
import com.cool.store.service.LinePayService;
import com.cool.store.utils.poi.DateUtils;
import com.cool.store.utils.poi.StringUtils;
import com.cool.store.utils.poi.constant.Constants;
import com.cool.store.vo.LinePayVO;
import com.cool.store.vo.PartnerUserInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Author wxp
 * @Date 2024/3/28 13:48
 * @Version 1.0
 */
@Service
@Slf4j
public class LinePayServiceImpl implements LinePayService {

    @Resource
    private LinePayDAO linePayDAO;

    @Resource
    private LineInfoDAO lineInfoDAO;

    @Resource
    FranchiseFeeMapper franchiseFeeMapper;

    @Resource
    ShopStageInfoDAO shopStageInfoDAO;

    @Resource
    CommonService commonService;

    @Resource
    ShopInfoMapper shopInfoMapper;

    @Override
    public LinePayVO getLinePayInfo(Long lineId, Integer businessType, Long shopId) {
        LinePayVO result = null;
        LinePayDO linePayDO = linePayDAO.getByLineIdAndPayTypeAndShopId(lineId, businessType, shopId);
        if (linePayDO != null) {
            result = new LinePayVO();
            BeanUtil.copyProperties(linePayDO, result);
            LineInfoDO lineInfo = lineInfoDAO.getLineInfo(lineId);
            result.setPartnerName(lineInfo != null ? lineInfo.getUsername() : "");
            result.setMobile(lineInfo != null ? lineInfo.getMobile() : "");
        }
        return result;
    }

    @Override
    public Boolean skipPay(Long lineId, LoginUserInfo user) {
        log.info("skipPay lineId:{},操作人:{}",lineId,user.getName());
        LineInfoDO lineInfo = lineInfoDAO.getLineInfo(lineId);
        if (lineInfo == null) {
            throw  new ServiceException(ErrorCodeEnum.LINE_ID_IS_NOT_EXIST);
        }
        if ( !WorkflowSubStageStatusEnum.PAY_DEPOSIT_45.getCode().equals(lineInfo.getWorkflowSubStageStatus())) {
            throw  new ServiceException(ErrorCodeEnum.LINE_STATUS_NOT_ALLOW_OPERATE);
        }
        lineInfo.setWorkflowSubStage(WorkflowSubStageEnum.SIGN_INTENT_AGREEMENT.getCode());
        lineInfo.setWorkflowSubStageStatus(WorkflowSubStageStatusEnum.SIGN_INTENT_AGREEMENT_70.getCode());
        lineInfo.setUpdateTime(new Date());
        lineInfo.setUpdateUserId(user.getUserId());
        lineInfoDAO.insertOrUpdate(lineInfo);
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long submitPayInfo(LinePaySubmitRequest request, PartnerUserInfoVO partnerUser) {
        log.info("submitPayInfo request：{}，partnerUser：{}", JSONObject.toJSONString(request), JSONObject.toJSONString(partnerUser));
        if (Objects.isNull(request.getPayBusinessType())){
            request.setPayBusinessType(Constants.ZERO_INTEGER);
        }
        LineInfoDO lineInfo = new LineInfoDO();
        if (request.getLineId() != null) {
            lineInfo = lineInfoDAO.getLineInfo(request.getLineId());
        }
        LinePayDO linePayDO = linePayDAO.getByLineIdAndPayTypeAndShopId(request.getLineId(), request.getPayBusinessType(), request.getShopId());
        linePayDO = checkAndFill(linePayDO, request, partnerUser);
        Long payId = linePayDO.getId();
        if (PayBusinessTypeEnum.FRANCHISE_FEE.getCode().equals(request.getPayBusinessType()) && payId != null) {
            FranchiseFeeDO franchiseFeeDO = franchiseFeeMapper.selectByShopId(request.getShopId());
            if (Objects.isNull(franchiseFeeDO)) {
                throw new ServiceException(ErrorCodeEnum.UNISSUED_STATEMENT);
            }
            franchiseFeeDO.setPayId(payId);
            franchiseFeeMapper.updateByPrimaryKeySelective(franchiseFeeDO);
            shopStageInfoDAO.updateShopStageInfo(request.getShopId(), ShopSubStageStatusEnum.SHOP_SUB_STAGE_STATUS_72);
            Map<String, String> requestMap = new HashMap<>();
            ShopInfoDO shopInfoDO = shopInfoMapper.selectByPrimaryKey(request.getShopId());
            requestMap.put("storeName",shopInfoDO.getShopName());
            requestMap.put("partnerName",lineInfo.getUsername());
            requestMap.put("partnerMobile",lineInfo.getMobile());
            requestMap.put("lineId",String.valueOf(lineInfo.getId()));
            requestMap.put("shopId",String.valueOf(shopInfoDO.getId()));
            //commonService.sendMessage(Arrays.asList(lineInfo.getInvestmentManager()), MessageEnum.MESSAGE_18,requestMap);
        }
        if (PayBusinessTypeEnum.INTENT_MONEY.getCode().equals(request.getPayBusinessType())) {
            lineInfo.setWorkflowSubStage(WorkflowSubStageEnum.PAY_DEPOSIT.getCode());
            lineInfo.setWorkflowSubStageStatus(WorkflowSubStageStatusEnum.PAY_DEPOSIT_50.getCode());
            lineInfoDAO.insertOrUpdate(lineInfo);
            Map<String, String> requestMap = new HashMap<>();
            requestMap.put("partnerUsername",lineInfo.getUsername());
            requestMap.put("payTime",DateUtils.parseDateToStr(DateUtils.SPECIAL_DATE_START, linePayDO.getPayTime()));
            requestMap.put("lineId",String.valueOf(lineInfo.getId()));
//            commonService.sendMessage(Arrays.asList(lineInfo.getInvestmentManager()), MessageEnum.MESSAGE_5,requestMap);
        }
        return payId == null ? null : payId;
    }

    private LinePayDO checkAndFill(LinePayDO linePayDO,
                              LinePaySubmitRequest request,
                              PartnerUserInfoVO partnerUser) {
        if (Objects.isNull(linePayDO)) {
            linePayDO = new LinePayDO();
            fillLinePay(Boolean.TRUE, linePayDO, request, partnerUser);
            Long aLong = linePayDAO.addLinePay(linePayDO);
            return linePayDO;
        } else {
            fillLinePay(Boolean.FALSE, linePayDO, request, partnerUser);
            linePayDAO.updateLinePay(linePayDO);
            return linePayDO;
        }
    }

    private void fillLinePay(Boolean isAdd, LinePayDO linePayDO, LinePaySubmitRequest request, PartnerUserInfoVO partnerUser) {
        linePayDO.setPayType(request.getPayType());
        linePayDO.setPayUserName(request.getPayUserName());
        linePayDO.setPayAccount(request.getPayAccount());
        linePayDO.setBankCode(request.getBankCode());
        linePayDO.setBankName(request.getBankName());
        linePayDO.setBranchBankCode(request.getBranchBankCode());
        linePayDO.setBranchBankName(request.getBranchBankName());
        linePayDO.setPayTime(DateUtils.dateTime("yyyy-MM-dd HH:mm:ss",request.getPayTime()));
        linePayDO.setPayPic(request.getPayPic());
        linePayDO.setPromisePic(request.getPromisePic());
        linePayDO.setPayStatus(WorkflowSubStageStatusEnum.PAY_DEPOSIT_50.getCode());
        linePayDO.setPayBusinessType(request.getPayBusinessType());
        if (Objects.nonNull(request.getShopId())) {
            linePayDO.setShopId(request.getShopId());
        }
        if (isAdd) {
            linePayDO.setPartnerId(partnerUser.getPartnerId());
            linePayDO.setLineId(request.getLineId());
            linePayDO.setCreateTime(new Date());
            linePayDO.setCreateUserId(partnerUser.getPartnerId());
            linePayDO.setDeleted(false);
        } else {
            linePayDO.setUpdateTime(new Date());
            if (Objects.nonNull(partnerUser)) {
                linePayDO.setUpdateUserId(partnerUser.getPartnerId());
            }
        }
        linePayDO.setAmount(request.getAmount());
    }

}
