package com.gree.mall.manager.logic.material.manage;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gree.mall.manager.bean.PayDetail;
import com.gree.mall.manager.bean.admin.AdminUserCom;
import com.gree.mall.manager.bean.material.manage.WebsitPartsCreditBean;
import com.gree.mall.manager.bean.material.manage.WebsitPartsCreditItemVO;
import com.gree.mall.manager.bean.material.manage.WebsitPartsCreditVO;
import com.gree.mall.manager.commonmapper.MaterialMapper;
import com.gree.mall.manager.constant.SybConstants;
import com.gree.mall.manager.enums.IsYesNoEnum;
import com.gree.mall.manager.enums.material.*;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.logic.common.AllInPayLogic;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.plus.entity.*;
import com.gree.mall.manager.plus.service.*;
import com.gree.mall.manager.zfire.bean.ZfireParamBean;
import com.gree.mall.manager.zfire.util.FieldUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Service
@RequiredArgsConstructor
public class WebsitPartsCreditLogic {

    private final CommonLogic commonLogic;
    private final MaterialMapper materialMapper;
    private final WebsitPartsWorkerCreditRecordService websitPartsWorkerCreditRecordService;
    private final WebsitPartsSalesService websitPartsSalesService;
    private final WebsitPartsSalesItemService websitPartsSalesItemService;
    private final WebsitSalesPayOrderService websitSalesPayOrderService;
    private final AdminWebsitPayConfigService adminWebsitPayConfigService;
    private final AllInPayLogic allInPayLogic;
    private final AdminWebsitService adminWebsitService;

    public IPage<WebsitPartsCreditVO> gatherPage(ZfireParamBean zfireParamBean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        FieldUtils.materialParam(zfireParamBean, WebsitPartsCreditVO.class, adminUser);
        IPage<WebsitPartsCreditVO> page = materialMapper.websitPartsCreditPage(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean);
        return page;
    }

    public IPage<WebsitPartsCreditItemVO> page(ZfireParamBean zfireParamBean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        FieldUtils.materialParam(zfireParamBean, WebsitPartsCreditItemVO.class, adminUser);
        IPage<WebsitPartsCreditItemVO> page = materialMapper.websitPartsCreditItemPage(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean);
        return page;
    }


    public WebsitPartsCreditBean detail(String id) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        final WebsitPartsWorkerCreditRecord record = websitPartsWorkerCreditRecordService.getById(id);
        if (Objects.isNull(id)) {
            throw new RemoteServiceException("单号不存在");
        }
        final WebsitPartsSales sales = websitPartsSalesService.lambdaQuery()
                .eq(WebsitPartsSales::getCompanyWechatId, adminUser.getCompanyWechatId())
                .eq(WebsitPartsSales::getId, record.getSalesId())
                .one();
        if (Objects.isNull(sales)) {
            throw new RemoteServiceException("单号不存在");
        }
        final WebsitPartsSalesItem item = websitPartsSalesItemService.getById(record.getSalesItemId());
        final WebsitSalesPayOrder payOrder = websitSalesPayOrderService.lambdaQuery()
                .eq(WebsitSalesPayOrder::getOrderId, record.getId())
                .eq(WebsitSalesPayOrder::getPayFlag, true)
                .last("limit 1")
                .one();
        WebsitPartsCreditBean bean = new WebsitPartsCreditBean();
        BeanUtils.copyProperties(sales, bean);
        bean.setCreditStatus(record.getCreditStatus());
        bean.setItemTotalAmount(record.getTotalAmount());
        bean.setItem(item);
        bean.setPayOrder(payOrder);
        if (!bean.getCreditStatus()) {
            bean.setUpdateBy(null);
            bean.setUpdateTime(null);
        }

        return bean;
    }

    public PayDetail generateCode(String id, String payConfigId) {
        WebsitPartsWorkerCreditRecord record = websitPartsWorkerCreditRecordService.getById(id);
        if (Objects.isNull(record)) {
            throw new RemoteServiceException("记账记录不存在");
        }
        if (record.getCreditStatus()) {
            throw new RemoteServiceException("已收款记录");
        }
        final AdminWebsitPayConfig payConfig = adminWebsitPayConfigService.getById(payConfigId);
        if (Objects.isNull(payConfig) || !payConfig.getStatus()) {
            throw new RemoteServiceException("支付配置信息异常");
        }

        // 通联扫码支付
        WebsitSalesPayOrder payOrder = new WebsitSalesPayOrder();
        payOrder.setId(IdWorker.getIdStr())
                .setCompanyWechatId(record.getCompanyWechatId())
                .setCompanyWechatName(record.getCompanyWechatName())
                .setGoodsType(WebsitGoodsTypeEnum.P.getKey())
                .setWebsitId(record.getWebsitId())
                .setWebsitName(record.getWebsitName())
                .setOrderId(record.getId())
                .setOutTradeNo(payOrder.getId())
                .setPayType(PayTypeEnum.ALLINPAY.getKey())
                .setOrderCreateTime(record.getCreateTime())
                .setPayValue(record.getTotalAmount())
                .setOrgId(payConfig.getOrgId())
                .setMchNo(payConfig.getMchNo())
                .setAppid(payConfig.getAppid())
                .setOrderType(PayOrderTypeEnum.S.getKey())
                .setRunTime(DateUtil.offsetSecond(DateUtil.date(), 15))
                .setOrderSource(SalesPayOrderSourceEnum.P_SALES.getKey())
                .setIsDeliver(false);

        //生成失效时间
        Date createDate = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(createDate);
        calendar.set(Calendar.SECOND, calendar.get(Calendar.SECOND) + 360);
        payOrder.setTimeExpire(calendar.getTime());
        // 请求通联得到结果
        Map<String, String> resMap = allInPayLogic.serviceUnifiedOrder(payOrder, SybConstants.PAY_TYPE_W01);

        if (!resMap.get("trxstatus").equals("0000")) {
            throw new RemoteServiceException("通联统一支付接口执行失败：" + resMap.get("errmsg"));
        }

        payOrder.setOrderNo(resMap.get("trxid"))
                .insert();

        PayDetail payDetail = new PayDetail();
        payDetail.setCodeUrl(resMap.get("payinfo"));
        payDetail.setId(payOrder.getId());
        payDetail.setPayAmount(record.getTotalAmount());
        payDetail.setTimeExpire(payOrder.getTimeExpire());
        log.info("通联支付payDetail:{}", JSONObject.toJSONString(payDetail));
        return payDetail;
    }

    public void changeCash(String id) {
        WebsitPartsWorkerCreditRecord record = websitPartsWorkerCreditRecordService.getById(id);
        AdminWebsit websit = adminWebsitService.getById(record.getWebsitId());
        if (!websit.getPartsIsCash()) {
            throw new RemoteServiceException("当前配件网点不支付现金方式");
        }
        if (record.getCreditStatus()) {
            throw new RemoteServiceException("已收款记录");
        }
        record.setCreditStatus(PartsCreditEnum.END.getValue())
                .setRecAmountMode(PayTypeEnum.CASH.getKey())
                .updateById();

        new WebsitSalesPayOrder()
                .setCompanyWechatId(record.getCompanyWechatId())
                .setCompanyWechatName(record.getCompanyWechatName())
                .setGoodsType(WebsitGoodsTypeEnum.P.getKey())
                .setWebsitId(record.getWebsitId())
                .setWebsitName(record.getWebsitName())
                .setOrderId(record.getId())
                .setPayType(PayTypeEnum.CASH.getKey())
                .setPayFlag(IsYesNoEnum.YES.getKey())
                .setOrderCreateTime(record.getCreateTime())
                .setPayValue(record.getTotalAmount())
                .setPayTime(DateUtil.date())
                .setOrderType(PayOrderTypeEnum.S.getKey())
                .setOrderSource(SalesPayOrderSourceEnum.PARTS_CREDIT.getKey())
                .insert();
    }

    public void update(String id, String remark) {
        websitPartsWorkerCreditRecordService.lambdaUpdate()
                .set(WebsitPartsWorkerCreditRecord::getRemark, remark)
                .eq(WebsitPartsWorkerCreditRecord::getId, id)
                .update();
    }
}
