package com.sckw.order.serivce;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sckw.core.common.enums.enums.DictEnum;
import com.sckw.core.common.enums.enums.DictTypeEnum;
import com.sckw.core.exception.BusinessException;
import com.sckw.core.model.constant.Global;
import com.sckw.core.model.page.PageRes;
import com.sckw.core.utils.BeanUtils;
import com.sckw.core.utils.CollectionUtils;
import com.sckw.core.utils.IdWorker;
import com.sckw.core.utils.StringUtils;
import com.sckw.core.web.context.LoginUserHolder;
import com.sckw.order.dao.KwpWantBuyAddressMapper;
import com.sckw.order.dao.KwpWantBuyMapper;
import com.sckw.order.dao.KwpWantBuyTradingMapper;
import com.sckw.order.model.*;
import com.sckw.order.model.vo.req.AddWantBuyParam;
import com.sckw.order.model.vo.req.UpdateWantBuyParam;
import com.sckw.order.model.vo.req.WantBuyDels;
import com.sckw.order.model.vo.req.WantBuySelectParam;
import com.sckw.order.model.vo.res.*;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.system.api.model.dto.res.EntCacheResDto;
import com.sckw.system.api.model.dto.res.SysDictResDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @desc: 求购service
 * @author: yzc
 * @date: 2023-06-25 14:54
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class KwpWantBuyService {
    @DubboReference(version = "2.0.0", group = "design", check = false)
    private RemoteSystemService remoteSystemService;
    private final KwpWantBuyMapper kwpWantBuyMapper;
    private final KwpWantBuyTradingMapper kwpWantBuyTradingMapper;
    private final KwpWantBuyAddressMapper kwpWantBuyAddressMapper;
    private final KwoWantBuyAddressService kwoWantBuyAddressService;
    private final KwoWantBuyTradingService kwoWantBuyTradingService;

    /**
     * @desc: 求购大厅列表查询
     * @author lt
     * @Date 11:50 2023/8/1 0001
    **/
    public PageRes<WantBuySelectRes> buyHallList(WantBuySelectParam wantBuySelectParam){
        // 如果有求购方式的查询条件，需要先查询出求购方式的id
        if (StringUtils.isNotBlank(wantBuySelectParam.getTrading())) {
            List<String> longList = stringToLongList(wantBuySelectParam.getTrading());
            wantBuySelectParam.setTradings(longList);
        }
        // 商品分类筛选处理
        if (StringUtils.isNotBlank(wantBuySelectParam.getGoodsType()) && StringUtils.isNotBlank(wantBuySelectParam.getGoodsTypeValue())) {
            List<String> goodsTypes = goodsTypeHandle(wantBuySelectParam);
            wantBuySelectParam.setGoodsTypeValueSearch(goodsTypes);
        }

        // 分页查询求购列表
        PageHelper.startPage(wantBuySelectParam.getPage(), wantBuySelectParam.getPageSize());
        List<WantBuySelectRes> wantBuyDto = kwpWantBuyMapper.queryBuyHallList(wantBuySelectParam);

        if (CollectionUtils.isEmpty(wantBuyDto)) {
            return new PageRes<>();
        }

        // 获取供应企业信息
        List<Long> supplyEntIds = wantBuyDto.stream()
                .map(WantBuySelectRes::getEntId)
                .collect(Collectors.toList());
        // 通过企业id查询企业信息
        List<EntCacheResDto> entList = remoteSystemService.queryEntCacheByIds(supplyEntIds);
        Map<Long, String> entMap = entList.stream()
                .collect(Collectors.toMap(EntCacheResDto::getId, EntCacheResDto::getFirmName, (k1, k2) -> k1));

        // 对求购列表进行数据处理
        wantBuyDto.forEach(wantBuySelectRes -> {
            List<String> tradings = wantBuySelectRes.getWantBuyTradings().stream()
                    .map(wantBuyTradingRes -> DictEnum.getLabel(DictTypeEnum.TRADE_TYPE.getType(), wantBuyTradingRes.getTrading()))
                    .collect(Collectors.toList());
            wantBuySelectRes.setTradings(String.join(Global.COMMA, tradings));
            wantBuySelectRes.setGoodsTypeLabel(DictEnum.getLabel(DictTypeEnum.PRODUCT_NAME_TYPE.getType(), wantBuySelectRes.getGoodsType()));
            wantBuySelectRes.setStatusLabel(DictEnum.getLabel(DictTypeEnum.GOODS_STATUS.getType(), String.valueOf(wantBuySelectRes.getStatus())));
            wantBuySelectRes.setEntName(Objects.nonNull(entMap.get(wantBuySelectRes.getEntId())) ? entMap.get(wantBuySelectRes.getEntId()) : null);
        });

        return new PageRes<>(new PageInfo<>(wantBuyDto));
    }

    /**
     * @desc 求购列表查询
     * @author lt
     * @Date 11:50 2023/8/1 0001
    **/
    public PageRes<WantBuySelectRes> select(WantBuySelectParam wantBuySelectParam) {

        if (StringUtils.isNotBlank(wantBuySelectParam.getTrading())) {
            List<String> longList = stringToLongList(wantBuySelectParam.getTrading());
            wantBuySelectParam.setTradings(longList);
        }
        if (StringUtils.isNotBlank(wantBuySelectParam.getStatus())) {
            wantBuySelectParam.setStatus(wantBuySelectParam.getStatus());
        }

        //商品分类筛选处理
        if (StringUtils.isNotBlank(wantBuySelectParam.getGoodsType()) && StringUtils.isNotBlank(wantBuySelectParam.getGoodsTypeValue())) {
            List<String> goodsTypes = goodsTypeHandle(wantBuySelectParam);
            wantBuySelectParam.setGoodsTypeValueSearch(goodsTypes);
        }
        PageHelper.startPage(wantBuySelectParam.getPage(), wantBuySelectParam.getPageSize());
        List<WantBuySelectRes> wantBuyDto = kwpWantBuyMapper.pageSelect(wantBuySelectParam);
        if (CollectionUtils.isEmpty(wantBuyDto)) {
            return new PageRes<>();
        }
        // 获取供应企业信息
        List<Long> supplyEntIds = wantBuyDto.stream()
                .map(WantBuySelectRes::getEntId)
                .collect(Collectors.toList());
        // 通过企业id查询企业信息
        List<EntCacheResDto> entList = remoteSystemService.queryEntCacheByIds(supplyEntIds);
        Map<Long, String> entMap = entList.stream()
                .collect(Collectors.toMap(EntCacheResDto::getId, EntCacheResDto::getFirmName, (k1, k2) -> k1));
        //把查询出来的集合wantBuyTradings里面对的tranding 转成字符串放在String里面
        wantBuyDto.forEach(wantBuySelectRes -> {
            List<String> tradings = wantBuySelectRes.getWantBuyTradings().stream()
                    .map(wantBuyTradingRes -> DictEnum.getLabel(DictTypeEnum.TRADE_TYPE.getType(), wantBuyTradingRes.getTrading()))
                    .collect(Collectors.toList());
            wantBuySelectRes.setTradings(String.join(Global.COMMA, tradings));
            wantBuySelectRes.setGoodsTypeLabel(DictEnum.getLabel(DictTypeEnum.PRODUCT_NAME_TYPE.getType(), wantBuySelectRes.getGoodsType()));
            wantBuySelectRes.setStatusLabel(DictEnum.getLabel(DictTypeEnum.GOODS_STATUS.getType(), String.valueOf(wantBuySelectRes.getStatus())));
            wantBuySelectRes.setEntName(Objects.nonNull(entMap.get(wantBuySelectRes.getEntId())) ? entMap.get(wantBuySelectRes.getEntId()) : null);
        });

        return new PageRes<>(new PageInfo<>(wantBuyDto));
    }

    /**
     * @Desc 求购列表查询
     * @param wantBuySelectParam
     * @return
     */
    private List<String> goodsTypeHandle(WantBuySelectParam wantBuySelectParam) {
        List<SysDictResDto> goodsTypeList = remoteSystemService.queryDictBottom(wantBuySelectParam.getGoodsType(), wantBuySelectParam.getGoodsTypeValue());
        if (CollectionUtils.isNotEmpty(goodsTypeList)) {
            return  goodsTypeList.stream().map(SysDictResDto::getValue).toList();
        }
        return null;
    }

    /**
     * @Desc 字符串转数组
     * @return
     */
    private List<String> stringToLongList(String str) {
        if (StringUtils.isBlank(str)) {
            return null;
        }
// 使用逗号分隔字符串，并去除两端空格
        String[] stringArray = str.split(Global.COMMA);
        return Arrays.asList(stringArray);
    }

    /**
     * @Desc 求购草稿新增
     * @Author lt
     * @Param
     * @Return
     * @Date 11:56 2023/7/25 0025
     **/
    public void addDraft(AddWantBuyParam param) {
        Integer status = Integer.valueOf(DictEnum.GOODS_STATUS_0.getValue());  //保存草稿
        String message = "求购草稿";
        addWantBuy(param, message, status);

    }

    /**
     * @Desc 求购上架新增
     * @Author lt
     * @Param
     * @Return
     * @Date 11:57 2023/7/25 0025
     **/
    public void addShelves(AddWantBuyParam param) {
        Integer status = Integer.valueOf(DictEnum.GOODS_STATUS_1.getValue());   //上架
        String message = "求购上架";
        addWantBuy(param, message, status);
    }

    /**
     * @desc 新增求购统一方法
     * @author lt
     * @Date 11:52 2023/8/1 0001
    **/
    @Transactional(rollbackFor = Exception.class)
    public void addWantBuy(AddWantBuyParam param, String message, Integer status) {
        Date currentDate = new Date();
        Long entId = LoginUserHolder.getEntId();
        if (Objects.isNull(entId)) {
            throw new BusinessException("企业ID不存在，请重新登录");
        }
//        KwoWantBuy kwoWantBuy = BeanUtils.copyProperties(param, KwoWantBuy.class);
        KwoWantBuy kwoWantBuy = new KwoWantBuy();
        Long userId = LoginUserHolder.getUserId();
        kwoWantBuy.setEntId(LoginUserHolder.getEntId())
                .setName(param.getName()).setGoodsType(param.getGoodsType())
                .setSpec(param.getSpec()).setPrice(param.getPrice())
                .setAmount(param.getAmount()).setContacts(param.getContacts())
                .setPhone(param.getPhone()).setId(new IdWorker(1L).nextId())
                .setRemark(param.getRemark()).setStatus(status).setCreateBy(userId)
                .setCreateTime(currentDate).setUpdateBy(userId)
                .setUpdateTime(currentDate).setDelFlag(Global.NO);
        kwpWantBuyMapper.insert(kwoWantBuy);
        if (Objects.isNull(kwoWantBuy.getId())) {
            throw new BusinessException(message + "失败");
        }
        /*
        支付方式添加
         */
        List<String> list = param.getTradings();
        if (list != null && !list.isEmpty()) {
            Date currentDateTime = new Date();
            List<KwoWantBuyTrading> tradingList = list.stream()
                    .map(item -> {
                        KwoWantBuyTrading kwoWantBuyTrading = new KwoWantBuyTrading();
                        kwoWantBuyTrading.setWantBuyId(kwoWantBuy.getId());
                        kwoWantBuyTrading.setTrading(item);
                        kwoWantBuyTrading.setCreateBy(userId);
                        kwoWantBuyTrading.setCreateTime(currentDateTime);
                        kwoWantBuyTrading.setUpdateTime(currentDateTime);
                        kwoWantBuyTrading.setStatus(status);
                        return kwoWantBuyTrading;
                    })
                    .collect(Collectors.toList());
            kwoWantBuyTradingService.insertBatch(tradingList);
        }
        /*
        地址信息添加,如果存在地址信息-新增入库
         */
        if (Objects.nonNull(param.getAddressInfo())) {
            KwoWantBuyAddress address = new KwoWantBuyAddress();
            Long idWorker = new IdWorker(1L).nextId();
            address.setWantBuyId(kwoWantBuy.getId());
            address.setName(param.getAddressInfo().getName());
            address.setType(param.getAddressInfo().getType());
            address.setContacts(param.getAddressInfo().getContacts());
            address.setPhone(param.getAddressInfo().getPhone());
            address.setCityCode(param.getAddressInfo().getCityCode());
            address.setCityName(param.getAddressInfo().getCityName());
            address.setDetailAddress(param.getAddressInfo().getDetailAddress());
            address.setLat(param.getAddressInfo().getLat());
            address.setLng(param.getAddressInfo().getLng());
            address.setFence(param.getAddressInfo().getFence());
            address.setId(idWorker);
            address.setCreateBy(LoginUserHolder.getUserId());
            address.setCreateTime(new Date());
            address.setUpdateTime(new Date());
            kwpWantBuyAddressMapper.insert(address);
        }
    }

    /**
     * @Desc: 求购上架
     * @Author: lt
     * @Date: 13:38 2023/7/25 0025
     **/
    public void putOnShelves(Long id) {
        KwoWantBuy kwoWantBuy = kwpWantBuyMapper.selectById(id);
        if (Objects.isNull(kwoWantBuy)) {
            throw new BusinessException("求购信息不存在");
        }
        if (kwoWantBuy.getStatus().equals(Integer.valueOf(DictEnum.GOODS_STATUS_1.getValue()))) {
            throw new BusinessException("求购信息已上架");
        }
        kwoWantBuy.setStatus(Integer.valueOf(DictEnum.GOODS_STATUS_1.getValue()));
        kwpWantBuyMapper.updateById(kwoWantBuy);
    }

    /**
     * @desc 求购批量下架
     * @author lt
     * @Date 14:56 2023/7/25 0025
     **/
    public void batchTakeOffShelves(WantBuyDels param) {
        if (BeanUtils.isEmpty(param)) {
            throw new BusinessException("请提供需要下架的产品");
        }
        List<String> ids = List.of(param.getIds().split(Global.COMMA));
        //1.查询ids所属产品只有status=1的才能下架,如果存在其它状态的则不能下架
        LambdaUpdateWrapper<KwoWantBuy> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(KwoWantBuy::getDelFlag, Global.NO).in(KwoWantBuy::getId, ids);
        updateWrapper.set(KwoWantBuy::getStatus, DictEnum.GOODS_STATUS_2.getValue())
                .set(KwoWantBuy::getUpdateBy, LoginUserHolder.getUserId())
                .set(KwoWantBuy::getUpdateTime, new Date());
        kwpWantBuyMapper.update(null, updateWrapper);
    }

    /**
     * @desc 求购删除
     * @author lt
     * @Date 10:15 2023/8/1 0001
    **/
    @Transactional(rollbackFor = Exception.class)
    public void dels(WantBuyDels param) {
        List<String> ids = List.of(param.getIds().split(Global.COMMA));
        LambdaUpdateWrapper<KwoWantBuy> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(KwoWantBuy::getId, ids).eq(KwoWantBuy::getDelFlag, Global.NO)
                .set(KwoWantBuy::getDelFlag, Global.YES)
                .set(KwoWantBuy::getUpdateBy, LoginUserHolder.getUserId())
                .set(KwoWantBuy::getUpdateTime, new Date());
        kwpWantBuyMapper.update(null, updateWrapper);
        //删除地址信息
        kwoWantBuyAddressService.delAddressByWantBuyIds(ids);
        //删除支付方式
        kwoWantBuyTradingService.delTradingByWantBuyids(ids);

    }

    /**
     * @desc 求购详情查询
     * @author lt
     * @Date 10:15 2023/8/1 0001
    **/
    public WantBuyDetailRes detail(Long id) {
        //先判断求购订单是否存在
        KwoWantBuy kwoWantBuy = kwpWantBuyMapper.selectById(id);
        if (Objects.isNull(kwoWantBuy)) {
            throw new BusinessException("求购信息不存在");
        }
        WantBuyDetailRes responseData = BeanUtils.copyProperties(kwoWantBuy, WantBuyDetailRes.class);
        //TODO 还未定义好求购状态(从表里面拿还是enum)
        responseData.setStatusLabel(DictEnum.getLabel(DictTypeEnum.GOODS_STATUS.getType(), String.valueOf(responseData.getStatus())));
        //求购地址信息
        KwoWantBuyAddress address = kwpWantBuyAddressMapper.selectOne(new LambdaQueryWrapper<KwoWantBuyAddress>()
                .eq(KwoWantBuyAddress::getWantBuyId, id).eq(KwoWantBuyAddress::getDelFlag, Global.NO));
        if (Objects.nonNull(address)) {
            WantBuyAddressDetailRes wantBuyAddressInfo = BeanUtils.copyProperties(address, WantBuyAddressDetailRes.class);
            wantBuyAddressInfo.setTypeLabel(DictEnum.getLabel(DictTypeEnum.TORDER_ADDRESS_TYPE.getType(), String.valueOf(wantBuyAddressInfo.getType())));
            System.out.println(wantBuyAddressInfo);
            responseData.setAddressInfo(wantBuyAddressInfo);
        }
        //获取求购企业信息
        EntCacheResDto entCacheResDto = remoteSystemService.queryEntCacheById(kwoWantBuy.getEntId());
        if (Objects.nonNull(entCacheResDto)) {
            responseData.setEntName(entCacheResDto.getFirmName());
        }
        //求购支付方式集合
        List<KwoWantBuyTrading> tradingList = kwoWantBuyTradingService.getByWantBuyId(id);
        if (Objects.nonNull(tradingList) && !tradingList.isEmpty()) {
            List<String> tradings = tradingList.stream().map(KwoWantBuyTrading::getTrading).collect(Collectors.toList());
            responseData.setTradings(tradings);
            //改成stream流的方式
            List<String> result = tradings.stream()
                    .map(trading -> DictEnum.getLabel(DictTypeEnum.TRADE_TYPE.getType(), trading))
                    .collect(Collectors.toList());
            String tradingLabels = String.join(Global.COMMA, result);
            //获取到的是一个集合,需要转换成字符串
            responseData.setTradingLabels(tradingLabels);
        }
        return responseData;
    }

    /**
     * @desc: 更新求购信息
     * @author lt
     * @Date 15:20 2023/7/26 0026
     **/
    public void update(UpdateWantBuyParam param) {
        Long id = param.getId();
        KwoWantBuy kwoWantBuy = selectOneById(id);
        if (Objects.isNull(kwoWantBuy)) throw new BusinessException("求购信息不存在");
        //1.更新求购信息
        Date currentDate = new Date();
        Long userId = LoginUserHolder.getUserId();
        KwoWantBuy wantBuy = BeanUtils.copyProperties(param, KwoWantBuy.class);
        wantBuy.setUpdateBy(userId);
        wantBuy.setUpdateTime(currentDate);
        kwpWantBuyMapper.updateById(wantBuy);
        //int i = kwpWantBuyMapper.updateById(wantBuy);
        //2.更新求购地址信息,判断是否存在地址信息

        if (Objects.nonNull(param.getAddressInfo())) {
            //判断是否存在地址信息
            LambdaQueryWrapper<KwoWantBuyAddress> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(KwoWantBuyAddress::getWantBuyId, id).eq(KwoWantBuyAddress::getDelFlag, Global.NO);
            KwoWantBuyAddress kwoWantBuyAddress = kwpWantBuyAddressMapper.selectOne(queryWrapper);
            //存在地址信息则更新,不存在则新增

            KwoWantBuyAddress kwoWantBuyAddress1 = BeanUtils.copyProperties(param.getAddressInfo(), KwoWantBuyAddress.class);
            kwoWantBuyAddress1.setUpdateTime(currentDate);
            kwoWantBuyAddress1.setUpdateBy(userId);
            if (Objects.nonNull(kwoWantBuyAddress)) {
                kwoWantBuyAddress1.setId(kwoWantBuyAddress.getId());
                kwpWantBuyAddressMapper.updateById(kwoWantBuyAddress1);
            } else {
                //不存在则新增地址信息
                kwoWantBuyAddress1.setWantBuyId(id);
                kwoWantBuyAddress1.setCreateTime(currentDate);
                kwoWantBuyAddress1.setCreateBy(userId);
                kwpWantBuyAddressMapper.insert(kwoWantBuyAddress1);
            }
        }
        //3.更新求购支付方式
        List<String> tradings = param.getTradings();
        if (CollectionUtils.isNotEmpty(tradings)) {
            kwoWantBuyTradingService.deleteByWantBuyid(id);
            ArrayList<KwoWantBuyTrading> list = new ArrayList<>(param.getTradings().size());
            for (String trading : tradings) {
                KwoWantBuyTrading kwoWantBuyTrading = new KwoWantBuyTrading();
                kwoWantBuyTrading.setWantBuyId(id);
                kwoWantBuyTrading.setTrading(trading);
                kwoWantBuyTrading.setCreateTime(currentDate);
                kwoWantBuyTrading.setUpdateTime(currentDate);
                kwoWantBuyTrading.setCreateBy(userId);
                list.add(kwoWantBuyTrading);
            }
            kwpWantBuyTradingMapper.insertBatch(list);
        }


    }

    /**
     * @Desc: 根据id查询求购信息
     * @param id
     * @return
     */
    public KwoWantBuy selectOneById(Long id) {
        LambdaQueryWrapper<KwoWantBuy> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(KwoWantBuy::getId, id)
                .eq(KwoWantBuy::getDelFlag, Global.NO);
        return kwpWantBuyMapper.selectOne(queryWrapper);
    }

    /**
     * @Desc: 查询求购角标统计数量
     * @param
     * @return
     */
    public Map statistic(WantBuySelectParam params) {
        if (StringUtils.isNotBlank(params.getTrading())) {
            List<String> longList = stringToLongList(params.getTrading());
            params.setTradings(longList);
        }
        if (StringUtils.isNotBlank(params.getStatus())) {
            params.setStatus(params.getStatus());
        }
        //商品分类筛选处理
        if (StringUtils.isNotBlank(params.getGoodsType()) && StringUtils.isNotBlank(params.getGoodsTypeValue())) {
            List<String> goodsTypes = goodsTypeHandle(params);
            params.setGoodsTypeValueSearch(goodsTypes);
        }
        /**统计数据**/
        List<TableTopRes> counts = kwpWantBuyMapper.statisticsCount(params);
        long tatol = counts.size();
        System.out.println(counts);

        /**全部数据-处理**/
        List<TableTopRes> countList = new ArrayList();
        TableTopRes allCount = new TableTopRes();
//        allCount.setValue(String.valueOf(DictEnum.GOODS_STATUS_0));
        allCount.setTotal(tatol);
        allCount.setName("全部");
        countList.add(allCount);

        /**数据处理**/
        Map<String, Integer> statusMap = new HashMap<>();
        statusMap.put("保存", Integer.valueOf(DictEnum.GOODS_STATUS_0.getValue()));
        statusMap.put("下架", Integer.valueOf(DictEnum.GOODS_STATUS_2.getValue()));
        statusMap.put("上架", Integer.valueOf(DictEnum.GOODS_STATUS_1.getValue()));
        for (Map.Entry<String, Integer> entry : statusMap.entrySet()) {
            System.out.println(entry.getKey() + "--->" + entry.getValue());
            TableTopRes count = new TableTopRes();
            int smlTotal = 0;
            for (TableTopRes topCount : counts) {
                if (topCount.getValue() != null && !topCount.getValue().isEmpty() && Integer.parseInt(topCount.getValue()) == entry.getValue()) {
                    smlTotal++;
                }
            }
            count.setName(entry.getKey());
            count.setValue(String.valueOf(entry.getValue()));
            count.setTotal(smlTotal);
            countList.add(count);
        }

        /**数据组装**/
        Map tableCount = new HashMap();
        tableCount.put("tableTop", countList);
        tableCount.put("tableBottom", tatol);
        return tableCount;
    }
}
