package com.fs.hisStore.task;


import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.fs.common.core.redis.RedisCache;
import com.fs.company.service.ICompanyService;
import com.fs.company.vo.RedPacketMoneyVO;
import com.fs.course.mapper.FsCourseRedPacketLogMapper;
import com.fs.erp.domain.ErpDeliverys;
import com.fs.erp.domain.ErpGoods;
import com.fs.erp.domain.ErpOrderQuery;
import com.fs.erp.dto.ErpGoodsQueryRequert;
import com.fs.erp.dto.ErpGoodsQueryResponse;
import com.fs.erp.dto.ErpOrderQueryRequert;
import com.fs.erp.dto.ErpOrderQueryResponse;
import com.fs.erp.service.IErpGoodsService;
import com.fs.erp.service.IErpOrderService;
import com.fs.his.config.FsSysConfig;
import com.fs.his.domain.FsStoreProductAttrValue;
import com.fs.his.dto.ExpressInfoDTO;
import com.fs.his.mapper.FsStoreProductAttrValueMapper;
import com.fs.his.service.IFsExpressService;
import com.fs.his.service.IFsUserService;
import com.fs.his.utils.ConfigUtil;
import com.fs.hisStore.domain.*;
import com.fs.hisStore.dto.DateComparisonConfigDTO;
import com.fs.hisStore.enums.ShipperCodeEnum;
import com.fs.hisStore.mapper.FsStoreOrderItemScrmMapper;
import com.fs.hisStore.mapper.FsStoreOrderScrmMapper;
import com.fs.hisStore.mapper.FsStorePaymentScrmMapper;
import com.fs.hisStore.mapper.FsStoreProductAttrValueScrmMapper;
import com.fs.hisStore.param.*;
import com.fs.hisStore.service.*;
import com.fs.pay.pay.dto.OrderQueryDTO;
import com.fs.pay.service.IPayService;
import com.fs.store.config.StoreConfig;
import com.fs.system.service.ISysConfigService;
import com.fs.ybPay.domain.OrderResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.text.ParseException;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

import static com.fs.hisStore.constants.StoreConstants.DELIVERY;

/**
 * 定时任务调度测试
 *
 * @author fs
 */
@Slf4j
@Component("mallStoreTask")
public class MallStoreTask
{
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private IFsStoreOrderScrmService orderService;
    @Autowired
    private IFsStoreCouponUserScrmService couponUserService;
    @Autowired
    private IFsStoreAfterSalesScrmService afterSalesService;
    @Autowired
    private IFsUserService userService;
    @Autowired
    private IPayService ybPayService;
    @Autowired
    private FsStoreOrderScrmMapper fsStoreOrderMapper;

    @Autowired
    private IFsStoreOrderScrmService fsStoreOrderService;

    @Autowired
    private IFsStoreOrderItemScrmService storeOrderItemService;

    @Autowired
    private FsStorePaymentScrmMapper fsStorePaymentMapper;


    @Autowired
    private IErpGoodsService erpGoodsService;
    @Autowired
    private ISysConfigService configService;
    @Autowired
    private FsStoreProductAttrValueMapper fsStoreProductAttrValueMapper;
    @Autowired
    private FsStorePaymentScrmMapper paymentMapper;
    @Autowired
    private IFsStorePaymentScrmService fsStorePaymentService;
    @Autowired
    private ICompanyService companyService;


    @Autowired
    private IFsExpressService expressService;

    @Autowired
    private FsStoreOrderItemScrmMapper itemMapper;

    @Autowired
    private IFsStoreAfterSalesScrmService fsStoreAfterSalesService;

    @Autowired
    @Qualifier("erpOrderServiceImpl")
    private IErpOrderService gyOrderService;

    @Autowired
    @Qualifier("wdtErpOrderServiceImpl")
    private IErpOrderService wdtOrderService;

    @Autowired
    @Qualifier("hzOMSErpOrderServiceImpl")
    private IErpOrderService hzOMSOrderService;

    @Autowired
    @Qualifier("dfOrderServiceImpl")
    private IErpOrderService dfOrderService;

    @Autowired
    @Qualifier("JSTErpOrderServiceImpl")
    private IErpOrderService jSTOrderService;

    @Autowired
    @Qualifier("k9OrderScrmServiceImpl")
    private IErpOrderService k9OrderService;

    @Autowired
    private ConfigUtil configUtil;

    @Autowired
    private FsCourseRedPacketLogMapper fsCourseRedPacketLogMapper;


    @Autowired
    IErpOrderService erpOrderService;

    //@Autowired
    //private IFsUserWatchCourseStatisticsService fsUserWatchCourseStatisticsService;

    //@Autowired
    //private IFsUserWatchStatisticsService fsUserWatchStatisticsService;

    //@Autowired
    //private IFsUserOnlineStateService fsUserOnlineStateService;

    public void PushErp() throws ParseException {
        List<Long> ids;
        // 开启审核
        if (getAuditSwitch()) {
            ids = fsStoreOrderMapper.selectFsStoreOrderNoCreateOmsAndReviewed();
        } else {
            ids = fsStoreOrderMapper.selectFsStoreOrderNoCreateOms();
        }
        for (Long id : ids) {
            fsStoreOrderService.createOmsOrder(id);
        }
    }

    /**
     * 获取是否需要订单审核
     * @return boolean
     */
    private boolean getAuditSwitch() {
        try {
            String json = configService.selectConfigByKey("store.config");
            StoreConfig config = JSONUtil.toBean(json,StoreConfig.class);
            return config.getAuditSwitch() == 1;
        } catch (Exception e) {
            return false;
        }
    }

    public void redPacketSubMoney() throws Exception
    {
        List<RedPacketMoneyVO> redPacketMoneyVOS = fsCourseRedPacketLogMapper.selectFsCourseRedPacketLogByCompany();
        for (RedPacketMoneyVO redPacketMoneyVO : redPacketMoneyVOS) {
            companyService.subtractCompanyMoney(redPacketMoneyVO.getMoney(),redPacketMoneyVO.getCompanyId());
        }
    }

    public void redPacketAddMoney() throws Exception
    {
        List<RedPacketMoneyVO> redPacketMoneyVOS = fsCourseRedPacketLogMapper.selectFsCourseAddRedPacketLogByCompany();
        for (RedPacketMoneyVO redPacketMoneyVO : redPacketMoneyVOS) {
            companyService.addRedPacketCompanyMoney(redPacketMoneyVO.getMoney(),redPacketMoneyVO.getCompanyId());
        }
    }

    //每5分钟执行一次
    public void deliveryOp()
    {
        List<FsStoreOrderScrm> list = fsStoreOrderMapper.selectUpdateExpress();
        for (FsStoreOrderScrm order : list){
            ErpOrderQueryRequert request = new ErpOrderQueryRequert();
            request.setCode(order.getExtendOrderId());
            IErpOrderService erpOrderService = getErpOrderService();
            ErpOrderQueryResponse response = erpOrderService.getScrmOrder(request);
            if (erpOrderService != dfOrderService) {
                if(response.getOrders()!=null && !response.getOrders().isEmpty()){
                    for(ErpOrderQuery orderQuery : response.getOrders()){
                        if(orderQuery.getDeliverys()!=null&&orderQuery.getDeliverys().size()>0){
                            for(ErpDeliverys delivery:orderQuery.getDeliverys()){
                                if(delivery.getDelivery()&&StringUtils.isNotEmpty(delivery.getMail_no())){
                                    //更新商订单状态 删除REDIS
                                    orderService.deliveryOrder(order.getOrderCode(),delivery.getMail_no(),delivery.getExpress_code(),delivery.getExpress_name());
                                    redisCache.deleteObject(DELIVERY+":"+order.getExtendOrderId());
                                }
                            }

                        }
                    }

                }
            }
        }

    }


    //定时任务刷新微信订单结算状态
    public void refreshOrderSettlementStatus(){
        fsStoreOrderService.refreshOrderSettlementStatus();
    }


    public void storeProdUpdateCostPrice()
    {
        String json=configService.selectConfigByKey("store.config");
        StoreConfig config=JSONUtil.toBean(json,StoreConfig.class);

        List<FsStoreProductAttrValue> values = fsStoreProductAttrValueMapper.selectFsStoreProductAttrValueList(new FsStoreProductAttrValue());
        for (FsStoreProductAttrValue value : values) {
            ErpGoodsQueryRequert query = new ErpGoodsQueryRequert();
            query.setCode(value.getBarCode());
            ErpGoodsQueryResponse goods = erpGoodsService.getGoods(query);
            List<ErpGoods> items = goods.getItems();

            if (items!=null&&items.size()>0){
                ErpGoods erpGoods = items.get(0);
                BigDecimal salesPrice = erpGoods.getSales_price();
                if (salesPrice!=null&&salesPrice.compareTo(BigDecimal.ZERO) != 0){
                    BigDecimal divide = salesPrice.multiply(new BigDecimal(config.getSalesPriceRate())).divide(new BigDecimal("100"));
                    System.out.println("代理价格"+divide);
                    System.out.println("成本价"+salesPrice);
                    FsStoreProductAttrValue va = new FsStoreProductAttrValue();
                    va.setCost(salesPrice);
                    va.setAgentPrice(divide);
                    va.setId(value.getId());
                    fsStoreProductAttrValueMapper.updateFsStoreProductAttrValue(va);
                }
            }
            System.out.println(goods);
        }
    }


    @Autowired
    private FsStoreProductAttrValueScrmMapper fsStoreProductAttrValueScrmMapper;

    public void storeProdUpdateCostPriceScrm()
    {
        String json=configService.selectConfigByKey("store.config");
        StoreConfig config=JSONUtil.toBean(json,StoreConfig.class);

        List<FsStoreProductAttrValueScrm> values = fsStoreProductAttrValueScrmMapper.selectFsStoreProductAttrValueList(new FsStoreProductAttrValueScrm());
        for (FsStoreProductAttrValueScrm value : values) {
            ErpGoodsQueryRequert query = new ErpGoodsQueryRequert();
            query.setCode(value.getBarCode());
            ErpGoodsQueryResponse goods = erpGoodsService.getGoodsScrm(query);
            List<ErpGoods> items = goods.getItems();

            if (items!=null&&items.size()>0){
                ErpGoods erpGoods = items.get(0);
                BigDecimal salesPrice = erpGoods.getSales_price();
                if (salesPrice!=null&&salesPrice.compareTo(BigDecimal.ZERO) != 0){
                    BigDecimal divide = salesPrice.multiply(new BigDecimal(config.getSalesPriceRate())).divide(new BigDecimal("100"));
                    System.out.println("代理价格"+divide);
                    System.out.println("成本价"+salesPrice);
                    FsStoreProductAttrValueScrm va = new FsStoreProductAttrValueScrm();
                    va.setCost(salesPrice);
                    va.setAgentPrice(divide);
                    va.setId(value.getId());
                    fsStoreProductAttrValueScrmMapper.updateFsStoreProductAttrValue(va);
                }
            }
            System.out.println(goods);
        }
    }
    public void couponOp()
    {
        couponUserService.updateFsCouponByExpire();

    }


    //退款自动处理 24小时未审核自动审核通过 每小时执行一次
    public void refundOp()
    {
        //获取所有退款申请
        List<FsStoreAfterSalesScrm> list=afterSalesService.selectFsStoreAfterSalesByDoAudit();
        if(list!=null){
            for(FsStoreAfterSalesScrm afterSales:list){
                //仅退款
                if(afterSales.getServiceType().equals(0)){
                    FsStoreAfterSalesAudit1Param audit1Param=new FsStoreAfterSalesAudit1Param();
                    audit1Param.setSalesId(afterSales.getId());
                    audit1Param.setOperator("平台");
                    afterSalesService.audit1(audit1Param);
                }
            }
        }
    }


    //每天执行一次
    public void userMoneyOp()
    {
        List<FsStoreOrderScrm> list=orderService.selectFsStoreOrderListByFinish7Day();
        if(list!=null){
            for(FsStoreOrderScrm order:list){
                userService.addMoney(order);
            }
        }
    }


    //每30秒执行一次
    public void orderItemSyncOp(){
        List<FsStoreOrderScrm> list = fsStoreOrderService.selectFsStoreOrderItemJson();
        for(FsStoreOrderScrm storeOrder:list){
            FsStoreOrderItemScrm parmOrderItem=new FsStoreOrderItemScrm();
            parmOrderItem.setOrderId(storeOrder.getId());
            List<FsStoreOrderItemScrm> listOrderItem=storeOrderItemService.selectFsStoreOrderItemList(parmOrderItem);
            if(listOrderItem.size()>0){
                String itemJson= JSONUtil.toJsonStr(listOrderItem);
                storeOrder.setItemJson(itemJson);
                fsStoreOrderMapper.uploadItemJson(storeOrder);
            }
        }
    }

    public void returnDeliveryId(){
        IErpOrderService erpOrderService = getErpOrderService();
        List<String> list = fsStoreOrderMapper.selectErpCode();
        for (String s : list) {
            ErpOrderQueryRequert request = new ErpOrderQueryRequert();
            request.setCode(s);
            ErpOrderQueryResponse response = erpOrderService.getOrder(request);
            if(response.getOrders()!=null&&response.getOrders().size()>0){
                    for(ErpOrderQuery orderQuery : response.getOrders()){
                        if(orderQuery.getDeliverys()!=null&&orderQuery.getDeliverys().size()>0){
                            for(ErpDeliverys delivery:orderQuery.getDeliverys()){
                                if(delivery.getDelivery()&&StringUtils.isNotEmpty(delivery.getMail_no())){
                                    FsStoreOrderScrm order = new FsStoreOrderScrm();
                                    order.setExtendOrderId(s);
                                    order.setDeliveryId(delivery.getMail_no());
                                    order.setStatus(2);
                                    fsStoreOrderMapper.updateDelivery(order);
                                }
                            }
                        }
                    }
                }


        }

    }

    public void changeStatus(){
        List<Long> list  = fsStoreOrderMapper.selectOrderId();
        for (Long orderId : list){
            FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderById(orderId);
            String lastFourNumber = "";
            if (order.getDeliverySn().equals(ShipperCodeEnum.SF.getValue())) {
                lastFourNumber = order.getUserPhone();
                if (lastFourNumber.length() == 11) {
                    lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
                }
            }
            ExpressInfoDTO dto=expressService.getExpressInfo(order.getOrderCode(),order.getDeliverySn(),order.getDeliveryId(),lastFourNumber);
            FsStoreOrderScrm map=new FsStoreOrderScrm();
            map.setDeliveryStatus(Integer.parseInt(dto.getState()));
            map.setId(order.getId());
            map.setDeliveryType(dto.getStateEx());
            fsStoreOrderMapper.updateFsStoreOrder(map);
        }
    }



    public void subCompanyMoney(){
        List<Long> list = paymentMapper.selectPaymentIds();
        for (Long paymentId : list){
            FsStorePaymentScrm payment=fsStorePaymentService.selectFsStorePaymentById(paymentId);
            if(payment.getCompanyId()!=null&&payment.getCompanyId()>0){
                companyService.subCompanyPaymentMoney(payment);
            }
        }
    }


    public void updateOrderItem() throws ParseException {
        List <Long> ids = itemMapper.selectOrderIdByNoErp();
        for (Long id:ids){
            fsStoreOrderService.createOmsOrder(id);
        }
    }



    //每天执行一次
    public void syncExpress()
    {
        List<Long> ids =fsStoreOrderMapper.selectSyncExpressIds();

        for (Long id : ids) {
            FsStoreOrderExpressEditParam param =new FsStoreOrderExpressEditParam();
            param.setOrderId(id);
            fsStoreOrderService.syncExpress(param);
        }

    }

    public void returnPayStatus() {
        List<String> ids =fsStorePaymentMapper.selectPayStatusIds();
        for (String id : ids) {
            OrderQueryDTO o = new OrderQueryDTO();
            o.setUpOrderId(id);
            OrderResult orderResult = ybPayService.getOrder(o);
            if ("0".equals(orderResult.getState())){
                String[] order=orderResult.getLowOrderId().split("-");
                if(orderResult.getStatus().equals("100")){
                    switch (order[0]) {
                        case "store":
                            orderService.payConfirm(1,null,order[1], o.getUpOrderId(),orderResult.getBankTrxId(),orderResult.getBankOrderId());
                        case "store_remain":
                            orderService.payRemainConfirm( order[1], o.getUpOrderId(),orderResult.getBankTrxId(),orderResult.getBankOrderId());
                        case "payment":
                            fsStorePaymentService.payConfirm(order[1],o.getUpOrderId(),orderResult.getBankTrxId(),orderResult.getBankOrderId());
                    }

                }
            }

        }

    }

    public void AddTuiMoney()
    {
        List<Long> ids =fsStoreOrderMapper.selectAddTuiMoney();
        for (Long id : ids) {
            FsStoreOrderAddTuiMoneyParam param = new FsStoreOrderAddTuiMoneyParam();
            param.setOrderId(id);
            fsStoreOrderService.addTuiMoney(param);
        }

    }


    public void selectPayMoneyLessOne(){
        List<FsStoreOrderScrm> list = fsStoreOrderMapper.selectPayMoneyLessOne();
        for (FsStoreOrderScrm order : list){
            FsStoreAfterSalesParam param = new FsStoreAfterSalesParam();
            param.setOrderCode(order.getOrderCode());
            param.setServiceType(0);
            param.setRefundAmount(order.getPayMoney());
            param.setReasons("超时未处理，自动申请退款");
            List<FsStoreAfterSalesProductParam> productParams = new ArrayList<>();
            List <FsStoreOrderItemScrm> items = fsStoreOrderMapper.selectOrderItem(order.getId());
            for (FsStoreOrderItemScrm item : items){
                FsStoreAfterSalesProductParam param1 = new FsStoreAfterSalesProductParam();
                param1.setProductId(item.getProductId());
                param1.setNum(item.getNum());
                productParams.add(param1);
            }
            param.setProductList(productParams);
            fsStoreAfterSalesService.autoApplyForAfterSales(order.getUserId(),param);
        }
    }

    public  void deleteCustomer(){

    }

    private IErpOrderService getErpOrderService(){
        //判断是否开启erp
        IErpOrderService erpOrderService = null;
        FsSysConfig erpConfig = configUtil.getSysConfig();
        Integer erpOpen = erpConfig.getErpOpen();
        if (erpOpen != null && erpOpen == 1) {
            //判断erp类型
            Integer erpType = erpConfig.getErpType();
            if (erpType != null) {
                if (erpType == 1) {
                    //管易
                    erpOrderService = gyOrderService;
                } else if (erpType == 2) {
                    //旺店通
                    erpOrderService = wdtOrderService;
                } else if (erpType == 3) {
                    //代服
                    erpOrderService = hzOMSOrderService;
                } else if (erpType == 4) {
                    //瀚智
                    erpOrderService = dfOrderService;
                } else if (erpType == 5) {
                    erpOrderService = jSTOrderService;
                }else if (erpType == 6) {
                    erpOrderService = k9OrderService;
                }
            }
        }
        return erpOrderService;
    }

    /**
     * 添加看课汇总统计
     */
    /*public void insertWatchStatistics(){
        *//***************************************进入营期会员看课汇总统计定时任务****************************************//*
        fsUserWatchStatisticsService.insertStatistics();
        *//***************************************营期会员看课汇总统计定时任务结束***************************************//*
    }*/

    /**
     * 添加看课明细统计
     */
    /*public void insertWatchCourseStatistics(){
        *//***************************************进入营期会员看课明细统计定时任务*******************************//*
        fsUserWatchCourseStatisticsService.insertWatchCourseStatistics();
        *//***************************************进入营期会员看课明细统计定时任务结束**********************************************//*
    }*/

    /**
     * 定时查询未上线的用户
     */
    /*public void insertUserNotOnline(){
        fsUserOnlineStateService.insertUserNotOnline();
    }*/

    /**
     * 提醒证件到期任务
     * */
    @Autowired
    private JdbcTemplate jdbcTemplate;
    public void remindCertValidation() {
        log.info("提醒店铺证件到期任务执行... 当前时间: {}", LocalTime.now());

        // 从配置表获取需要比较的表和字段
        List<DateComparisonConfigDTO> tablesToCheck = jdbcTemplate.query(
                "SELECT table_name, date_column,in_advance,user_column,phone_column,remind_words,platform,cert_type" +
                        " FROM date_comparison_config",(rs, rowNum)->{
                    return DateComparisonConfigDTO.builder()
                            .tableName(rs.getString("table_name"))//表名
                            .certType(rs.getString("cert_type"))//证件类型
                            .dateColumn(rs.getString("date_column"))//日期字段
                            .userColumn(rs.getString("user_column"))//用户字段
                            .remindWords(rs.getString("remindWords"))//提醒内容
                            .phoneColumn(rs.getString("phone_column"))//提醒手机
                            .inAdvance(rs.getInt("inAdvance"))//提前天数
                            .platform(rs.getString("platform")).build();//平台
                });

        tablesToCheck.forEach(dto -> {
            //获取证件失效日期字段小于当前时间加提前天数的用户和电话号码
            String sql = String.format("SELECT %s , %s " +
                            "FROM %s " +
                            "WHERE %s >= DATE_SUB(CURDATE(), INTERVAL %d DAY)",
                            dto.getUserColumn(),
                            dto.getPhoneColumn(),
                            dto.getTableName(),
                            dto.getDateColumn(),
                            dto.getInAdvance()
                            );
            List<Map<String, Object>> users = jdbcTemplate.queryForList(sql);
            users.forEach(user -> {
                String userName = (String) user.get(dto.getUserColumn());
                String phone = (String) user.get(dto.getPhoneColumn());
                String remindWords = String.format("【%s平台提示】尊敬的%s用户，店铺%s证件即将到期，请及时处理！",
                        dto.getPlatform(),
                        userName,
                        dto.getCertType());
                // 使用phone发送remindWords短信
                // TODO 发送通知
            });
        });

    }

    /**
     * 禁用店铺
     * */
    public void disable() {
        log.info("禁用店铺任务执行... 当前时间: {}", LocalTime.now());
        // 从配置表获取需要禁用的表和字段
        List<DateComparisonConfigDTO> toDisable = jdbcTemplate.query(
                "SELECT table_name, date_column,invalid_expression,status_column" +
                        " FROM date_comparison_config " +
                        " WHERE is_do_invalid = '1'",(rs, rowNum)-> DateComparisonConfigDTO.builder()
                                .tableName(rs.getString("table_name"))//表名
                                .dateColumn(rs.getString("date_column"))//日期字段
                                .invalidExpression(rs.getString("invalid_expression"))//失效表达式
                                .statusColumn(rs.getString("status_column"))//状态字段
                                .build());

        toDisable.forEach(dto -> {
            //更新证件失效日期字段小于当前时间的数据
            String sql = String.format("UPDATE %s " +
                    "SET %s = %s " +
                    "WHERE %s < CURDATE()",
                    dto.getTableName(),
                    dto.getStatusColumn(),
                    dto.getInvalidExpression(),
                    dto.getDateColumn());
            jdbcTemplate.update(sql);
        });
    }

    public void getOrderDeliveryStatus()
    {
        IErpOrderService erpOrderService = getErpOrderService();
        List<FsStoreOrderScrm> orders = null;
        if (erpOrderService != null && erpOrderService == dfOrderService) {
            orders = fsStoreOrderMapper.selectShippedOrder();
            if (orders != null && !orders.isEmpty()) {
                List<CompletableFuture<Void>> futures = new ArrayList<>();
                for (FsStoreOrderScrm order : orders) {
                    CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                        erpOrderService.getOrderScrmDeliveryStatus(order);
                    });
                    futures.add(future);
                }
                CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
            }
        }
    }

}
