package com.gxwebsoft.shop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxwebsoft.shop.entity.MerchantCategory;
import com.gxwebsoft.shop.entity.MerchantOfflinePay;
import com.gxwebsoft.shop.entity.OrderGoods;
import com.gxwebsoft.shop.mapper.MerchantMapper;
import com.gxwebsoft.shop.service.*;
import com.gxwebsoft.shop.entity.Merchant;
import com.gxwebsoft.shop.param.MerchantParam;
import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.PageResult;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 商户Service实现
 *
 * @author 科技小王子
 * @since 2024-04-05 00:03:54
 */
@Service
public class MerchantServiceImpl extends ServiceImpl<MerchantMapper, Merchant> implements MerchantService {
    @Resource
    private OrderGoodsService orderGoodsService;
    @Resource
    private MerchantCategoryService merchantCategoryService;
    @Resource
    private MerchantOfflinePayService merchantOfflinePayService;

    @Override
    public PageResult<Merchant> pageRel(MerchantParam param) {
        PageParam<Merchant, MerchantParam> page = new PageParam<>(param);
//        page.setDefaultOrder("sort_number asc, create_time desc");
        List<Merchant> list = baseMapper.selectPageRel(page, param);
        for (Merchant merchant : list) {
            if (param.getWithOrderNum() != null && param.getWithOrderNum()) {
                int orderNum = orderGoodsService.countByMerchant(merchant.getMerchantId());
                int offlinePayNum = merchantOfflinePayService.countByMerchant(merchant.getMerchantId());
                orderNum += offlinePayNum;
                merchant.setOrderNum(orderNum);
//                merchant.setUserNum(orderNum);
            }
        }
        return new PageResult<>(list, page.getTotal());
    }

    @Override
    public List<Merchant> listRel(MerchantParam param) {
        if (param.getWithOrderNum() != null && param.getWithOrderNum()) {
            param.setStatus(0);
        }
        if (param.getTopMerchantCategoryId() != null) {
            List<MerchantCategory> categoryList = merchantCategoryService.listByParentId(param.getTopMerchantCategoryId());
            List<Integer> categoryIds = new ArrayList<>();
            if (!categoryList.isEmpty()) {
                categoryIds = categoryList.stream().map(MerchantCategory::getCategoryId).toList();
                param.setMerchantCategoryIds(categoryIds);
            } else return new ArrayList<>();
        }
        List<Merchant> list = baseMapper.selectListRel(param);
        if (param.getWithOrderNum() != null && param.getWithOrderNum()) {
            if (!list.isEmpty()) {
                List<Integer> merchantIds = list.stream().map(Merchant::getMerchantId).toList();
                List<OrderGoods> orderGoodsList = orderGoodsService.countByMerchantIds(merchantIds);
                List<MerchantOfflinePay> offlinePayList = merchantOfflinePayService.countByMerchantIds(merchantIds);
                for (Merchant merchant : list) {
                    OrderGoods orderGoods = orderGoodsList.stream().filter(og -> og.getMerchantId().equals(merchant.getMerchantId())).findFirst().orElse(null);
                    MerchantOfflinePay offlinePay = offlinePayList.stream().filter(og -> og.getMerchantId().equals(merchant.getMerchantId())).findFirst().orElse(null);
                    int orderNum = orderGoods == null ? 0 : orderGoods.getTotalNum();
//                    int orderNum = orderGoodsService.countByMerchant(merchant.getMerchantId());
//                    int offlinePayNum = merchantOfflinePayService.countByMerchant(merchant.getMerchantId());
                    int offlinePayNum = offlinePay == null ? 0 : offlinePay.getTotalNum();
                    orderNum += offlinePayNum;
                    merchant.setOrderNum(orderNum);
                }
            }
        }
        // 排序
        PageParam<Merchant, MerchantParam> page = new PageParam<>();
//        page.setDefaultOrder("sort_number asc, create_time desc");
        return page.sortRecords(list);
    }

    @Override
    public Merchant getByIdRel(Integer merchantId) {
        MerchantParam param = new MerchantParam();
        param.setMerchantId(merchantId);
        return param.getOne(baseMapper.selectListRel(param));
    }


    @Override
    public Merchant getByIdRel(Integer merchantId, MerchantParam param) {
        QueryWrapper<Merchant> wrapper = new QueryWrapper<>();
        wrapper.eq("merchant_id", merchantId);

        if (param.getLat() != null) {
            String distanceSql = "ACOS(SIN(( " + param.getLat() + " * 3.1415) / 180 ) * SIN((lat * 3.1415) / 180 ) + " +
                    "COS(( " + param.getLat() + " * 3.1415) / 180) * COS((lat * 3.1415) / 180 ) * COS(( " + param.getLng() + " * 3.1415) / 180 - " +
                    "(lng * 3.1415) / 180 ) ) * 6380" +
                    " as distance";
            wrapper.select("*", distanceSql);
        } else wrapper.select("*");
        wrapper.last("limit 1");
        return getOne(wrapper);
    }


    @Override
    public Merchant getByUserId(Integer userId) {
        MerchantParam param = new MerchantParam();
        param.setUserId(userId);
        return param.getOne(baseMapper.selectListRel(param));
    }

    @Override
    public List<Merchant> listByDistance(String lat, String lng, String shopType) {
        String distanceSql = "ACOS(SIN(( " + lat + " * 3.1415) / 180 ) * SIN((lat * 3.1415) / 180 ) + " +
                "COS(( " + lat + " * 3.1415) / 180) * COS((lat * 3.1415) / 180 ) * COS(( " + lng + " * 3.1415) / 180 - " +
                "(lng * 3.1415) / 180 ) ) * 6380" +
                " as distance";
        return list(
                new QueryWrapper<Merchant>()
                        .select("*", distanceSql)
                        .eq("shop_type", shopType)
                        .eq("deleted", 0)
                        .orderByDesc("distance")
        );
    }

}
