package com.gree.mall.manager.logic.workorder;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
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.workorder.IncreOrderVO;
import com.gree.mall.manager.bean.workorder.PgIncreOrderBean;
import com.gree.mall.manager.bean.workorder.WebsitOrderSettleCountVO;
import com.gree.mall.manager.bean.workorder.WorkerOrderSettleCountVO;
import com.gree.mall.manager.commonmapper.CommonMapper;
import com.gree.mall.manager.enums.*;
import com.gree.mall.manager.enums.workorder.IncreEnum;
import com.gree.mall.manager.enums.workorder.IncrePayTypeEnum;
import com.gree.mall.manager.enums.workorder.SourceChannelEnum;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.logic.common.WechatLogic;
import com.gree.mall.manager.plus.entity.*;
import com.gree.mall.manager.plus.service.*;
import com.gree.mall.manager.utils.IpUtil;
import com.gree.mall.manager.utils.StringUtil;
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.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class IncreOrderSettleLogic {

    private final CommonLogic commonLogic;
    private final CommonMapper commonMapper;
    private final PgIncreOrderService pgIncreOrderService;
    private final PgIncreService pgIncreService;
    private final PgIncreItemService pgIncreItemService;
    private final WechatLogic wechatLogic;
    private final WebsitSalesService websitSalesService;

    private final GoodsCategoryService goodsCategoryService;

    private final BrandService brandService;
    private final PgIncreWebsitService pgIncreWebsitService;



    public IPage<IncreOrderVO> list(ZfireParamBean zfireParamBean, Boolean isSettleList) {
        FieldUtils.supplyParam(zfireParamBean, IncreOrderVO.class, commonLogic.getAdminUser());
        zfireParamBean.setAdminWebsitIds(zfireParamBean.getAdminWebsitIds());
        IPage<IncreOrderVO> page = commonMapper.increOrderSettleList(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean, isSettleList);

        return page;
    }


    public PgIncreOrderBean detail(String id) {
        PgIncreOrder increOrder = pgIncreOrderService.getById(id);
        PgIncreOrderBean bean = new PgIncreOrderBean();
        BeanUtils.copyProperties(increOrder, bean);
        PgIncre incre = pgIncreService.getById(increOrder.getPgIncreId());
        PgIncreItem increItem = pgIncreItemService.getById(increOrder.getPgIncreItemId());
        bean.setIncre(incre);
        bean.setIncreItem(increItem);
        return bean;
    }

    @Transactional
    public void refund(String id) {
        PgIncreOrder increOrder = pgIncreOrderService.getById(id);
        if (Objects.isNull(increOrder) || !increOrder.getSettleStatus().equals(OrderShareStatusEnum.ING.toString())) {
            throw new RemoteServiceException("单号不存在");
        }
        DateTime offsetDay = DateUtil.parseDateTime(DateUtil.formatDate(DateUtil.offsetDay(increOrder.getPayTime(), 7)) + " 23:59:59");
        if (DateUtil.date().getTime() > offsetDay.getTime()) {
            throw new RemoteServiceException("已超过7天, 不能操作退款");
        }
        increOrder.setRefundNo(IdWorker.getIdStr());

        wechatLogic.refund(increOrder.getTranscationId(),increOrder.getRefundNo(), increOrder.getAmount().doubleValue(),
                increOrder.getAmount().doubleValue(), increOrder.getCompanyWechatId(), OrderInfoSourceEnum.A.getRemark());
//        if (increOrder.getPayType().equals(IncrePayTypeEnum.A.getValue())) {
//            wechatLogic.increRefund(null, increOrder.getTranscationId(),increOrder.getRefundNo(), increOrder.getAmount().doubleValue(),
//                    increOrder.getAmount().doubleValue(), increOrder.getCompanyWechatId());
//        } else {
//            wechatLogic.increRefund(increOrder.getPayNo(), null,increOrder.getRefundNo(), increOrder.getAmount().doubleValue(),
//                    increOrder.getAmount().doubleValue(), increOrder.getCompanyWechatId());
//        }


        increOrder.setSettleStatus(OrderShareStatusEnum.CANCEL.toString())
                .setPayStatus(PayStatusEnum.REFUND.getKey())
                .setRefundTime(DateUtil.date())
                .updateById();
    }

    @Transactional
    public void confirm(List<String> ids) {
        AdminUserCom adminUser = commonLogic.getAdminUser();


        List<PgIncreOrder> increOrders = pgIncreOrderService.lambdaQuery()
                .in(PgIncreOrder::getId, ids)
                .eq(PgIncreOrder::getSettleStatus, OrderSharePageEnum.ING.getKey())
                .list();
        for (PgIncreOrder order : increOrders) {
            wechatLogic.shareAmount(order);
        }

//        pgIncreOrderService.lambdaUpdate()
//                .set(PgIncreOrder::getUpdateBy, adminUser.getNickName())
//                .set(PgIncreOrder::getUpdateTime, DateUtil.date())
//                .set(PgIncreOrder::getSettleStatus, OrderShareStatusEnum.OVER.toString())
//                .eq(PgIncreOrder::getSettleStatus, OrderSharePageEnum.ING.getKey())
//                .eq(PgIncreOrder::getPayStatus, PayStatusEnum.PAID.getKey())
//                .in(PgIncreOrder::getId, ids)
//                .update();


    }

    public IPage<WebsitOrderSettleCountVO> countList(ZfireParamBean zfireParamBean) {

        FieldUtils.supplyParam(zfireParamBean, WebsitOrderSettleCountVO.class, commonLogic.getAdminUser());
        zfireParamBean.setAdminWebsitIds(zfireParamBean.getAdminWebsitIds());

//        if (CollectionUtil.isEmpty(zfireParamBean.getParams())) {
//            return new Page<WebsitOrderSettleCountVO>();
//        }

//        int cut = 0;
//        for (QueryParamBean param : zfireParamBean.getParams()) {
//            if (param.getParam().equals("a.pay_time") && (param.getCompare().equals(">=") || param.getCompare().equals("<=")) && (Objects.nonNull(param.getValue()))) {
//                cut++;
//            }
//        }
//
//        if (cut < 2) {
//            return new Page<WebsitOrderSettleCountVO>();
//        }

        IPage<WebsitOrderSettleCountVO> page = commonMapper.websitOrderSettleCountList(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean);

        return page;
    }

    public IPage<WorkerOrderSettleCountVO> countWorkerList(ZfireParamBean zfireParamBean) {
        FieldUtils.supplyParam(zfireParamBean, WorkerOrderSettleCountVO.class, commonLogic.getAdminUser());
        zfireParamBean.setAdminWebsitIds(zfireParamBean.getAdminWebsitIds());

        IPage<WorkerOrderSettleCountVO> page = commonMapper.workerOrderSettleCountList(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean);

        return page;
    }

    @Transactional
    public void add(PgIncreOrder order) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        PgIncre incre = pgIncreService.getById(order.getPgIncreId());

        if (Objects.isNull(incre)) {
            throw new RemoteServiceException("增值服务方案不存在, 请检查");
        }

        this.checkOrderParams(order);
        String companyId = null;
        String companyName = null;
        if (Objects.nonNull(adminUser.getAdminCompanyWechat())) {
            companyId = adminUser.getAdminCompanyWechat().getCompanyWechatId();
            companyName = adminUser.getAdminCompanyWechat().getCompanyName();
        }
        if (incre.getUsedType().equals(IncreEnum.YEAR.getKey())) {
            order.setServiceEndTime(DateUtil.offset(DateUtil.date(), DateField.YEAR, order.getLimitNum()));
        }

        order.setSettleStatus(null)
                .setId("YB"+IdWorker.getIdStr())
                .setPayStatus(PayStatusEnum.WAIT.getKey())
                .setOrderChannel(SourceChannelEnum.SELF.getKey())
                .setCompanyWechatId(companyId)
                .setWebsitAmount(order.getAmount())
                .setCompanyWechatName(companyName)
                .setFlag(ExamineStatusEnum.WAIT.getKey())
                .insert();
    }

    private void checkOrderParams(PgIncreOrder order) {
        if (StringUtils.isBlank(order.getUserName())) {
            throw new RemoteServiceException("客户名称不能为空");
        }
        if (StringUtils.isBlank(order.getUserMobile())) {
            throw new RemoteServiceException("客户电话不能为空");
        }
        if (StringUtils.isBlank(order.getUserAddress())) {
            throw new RemoteServiceException("客户地址不能为空");
        }
        if (Objects.isNull(order.getIncreType())) {
            throw new RemoteServiceException("请选择服务类型");
        }
        if (StringUtils.isBlank(order.getBrandId())) {
            throw new RemoteServiceException("请选择产品品牌");
        }
        if (StringUtils.isBlank(order.getMainId())) {
            throw new RemoteServiceException("请选择产品大类");
        }
        if (StringUtils.isBlank(order.getIncreContent())) {
            throw new RemoteServiceException("请选择服务内容");
        }
        if (Objects.isNull(order.getAmount())) {
            throw new RemoteServiceException("服务金额不能为空");
        }
        if (order.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
            throw new RemoteServiceException("服务金额必须大于0");
        }
        if (StringUtils.isBlank(order.getWebsitId())) {
            throw new RemoteServiceException("请选择销售网点");
        }
        if (Objects.isNull(order.getPayType())) {
            throw new RemoteServiceException("请选择支付方式");
        }
        if (StringUtils.isBlank(order.getInsideCode())) {
            throw new RemoteServiceException("内机条码不能为空");
        }
        if (Objects.isNull(order.getInvoiceAmount())) {
            throw new RemoteServiceException("发票价格不能为空");
        }
        if (Objects.isNull(order.getInsureTime())) {
            throw new RemoteServiceException("原保到期不能为空");
        }
        if (StringUtils.isBlank(order.getInsideCodeImg())) {
            throw new RemoteServiceException("内机条码图片不能为空");
        }
        if (StringUtils.isBlank(order.getMachineImg())) {
            throw new RemoteServiceException("机器铭牌图片不能为空");
        }
        if (StringUtils.isBlank(order.getBuyCertImg())) {
            throw new RemoteServiceException("购机凭证图片不能为空");
        }
    }

    @Transactional
    public void examine(PgIncreOrder order) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        PgIncreOrder oldOrder = pgIncreOrderService.getById(order.getId());

        if (!oldOrder.getFlag().equals(ExamineStatusEnum.WAIT.getKey())) {
            throw new RemoteServiceException("订单非\"待审批\"状态, 不能审批");
        }

        if (!(ExamineStatusEnum.OK.getKey() + ExamineStatusEnum.FAIL.getKey()).contains(order.getFlag())) {
            throw new RemoteServiceException("请选择审批结果");
        }

        if (order.getFlag().equals(ExamineStatusEnum.OK.getKey())
                && IncrePayTypeEnum.C.getKey().equals(order.getPayType().toString())) {
            oldOrder.setPayStatus(PayStatusEnum.PAID.getKey())
                    .setSettleStatus(OrderShareStatusEnum.OVER.toString());

            oldOrder.setPayTime(new Date());
            oldOrder.setPayNo(order.getId());
        }

        if (order.getFlag().equals(ExamineStatusEnum.FAIL.getKey())) {
            oldOrder.setPayStatus(PayStatusEnum.CANCEL.getKey());
        }



        oldOrder.setExamineRemark(order.getExamineRemark())
                .setFlag(order.getFlag())
                .setExamineBy(adminUser.getNickName())
                .setServiceNo(order.getId())
                .setExamineTime(DateUtil.date())
                .updateById();
    }

    public PayDetail pay(String id, HttpServletRequest request) throws Exception {
        String ip = IpUtil.getIpAddr(request);
        PgIncreOrder order = pgIncreOrderService.getById(id);
        if (!order.getFlag().equals(ExamineStatusEnum.OK.getKey())) {
            throw new RemoteServiceException("订单未\"审批通过\"");
        }
        return wechatLogic.paymentNATIVE(id, order.getAmount(), "", "N", ip, order.getCompanyWechatId());
    }


    public List<PgIncreItem> getIncreItem(String brand, String mainName) {

        AdminUserCom adminUser = commonLogic.getAdminUser();
        List<PgIncre> list = pgIncreService.lambdaQuery()
                .eq(PgIncre::getStatus, true)
                .eq(PgIncre::getCompanyWechatId, adminUser.getCompanyWechatId()).list();

        List<String> collect = list.stream().map(PgIncre::getId).collect(Collectors.toList());

        List<PgIncreItem> pgIncreItems = pgIncreItemService.lambdaQuery().in(PgIncreItem::getIncreId, collect)
                .eq(!StringUtil.isEmpty(brand),PgIncreItem::getBrandName, brand)
                .eq(!StringUtil.isEmpty(mainName),PgIncreItem::getMainName, mainName)
                .list();

        return pgIncreItems;
    }


    public List<GoodsCategory> getCategoryList(String brandName) {

        AdminUserCom adminUser = commonLogic.getAdminUser();

        List<PgIncre> list = pgIncreService.lambdaQuery()
                .select(PgIncre::getId)
                .eq(PgIncre::getStatus, true)
                .eq(PgIncre::getCompanyWechatId, adminUser.getCompanyWechatId()).list();

        List<String> collect = list.stream().map(PgIncre::getId).collect(Collectors.toList());

        if (CollectionUtils.isEmpty(collect))
            return new ArrayList<>();

        List<PgIncreItem> pgIncreItems = pgIncreItemService.lambdaQuery()
                .select(PgIncreItem::getMainId)
                .in(PgIncreItem::getIncreId, collect)
                .eq(!StringUtil.isEmpty(brandName),PgIncreItem::getBrandName, brandName)
                .list();
        List<String> collectCategoty = pgIncreItems.stream().map(PgIncreItem::getMainId).collect(Collectors.toList());

        if (CollectionUtils.isEmpty(collectCategoty))
            return new ArrayList<>();

        return goodsCategoryService.lambdaQuery()
                .in(GoodsCategory::getCategoryId,collectCategoty)
                .eq(GoodsCategory::getType,2)
                .eq(GoodsCategory::getDel,0)
                .eq(GoodsCategory::getLevel, 1)
                .in(GoodsCategory::getCompanyWechatId,adminUser.getCompanyWechatId())
                .orderByAsc(GoodsCategory::getSortNum)
                .list();
    }


    public List<Brand> getBrand() {

        AdminUserCom adminUser = commonLogic.getAdminUser();


        List<PgIncre> list = pgIncreService.lambdaQuery()
                .select(PgIncre::getId)
                .eq(PgIncre::getStatus, true)
                .eq(PgIncre::getCompanyWechatId, adminUser.getCompanyWechatId()).list();

        List<String> collect = list.stream().map(PgIncre::getId).collect(Collectors.toList());

        if (CollectionUtils.isEmpty(collect))
            return new ArrayList<>();

        List<PgIncreItem> pgIncreItems = pgIncreItemService.lambdaQuery()
                .select(PgIncreItem::getBrandId)
                .in(PgIncreItem::getIncreId, collect)
                .list();
        List<String> collectCategoty = pgIncreItems.stream().map(PgIncreItem::getBrandId).collect(Collectors.toList());

        if (CollectionUtils.isEmpty(collectCategoty))
            return new ArrayList<>();

        return brandService.lambdaQuery()
                .eq(Brand::getStatus,1)
                .in(Brand::getId,collectCategoty)
                .eq(Brand::getCompanyWechatId,adminUser.getCompanyWechatId()).orderByAsc(Brand::getSortNum).list();
    }


    public List<PgIncreWebsit> getWebsit(String increId) {

        return pgIncreWebsitService.lambdaQuery().eq(PgIncreWebsit::getPgIncreId,increId).list();

    }
}
