package com.fjhx.supply.service.supplier.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.stream.CollectorUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.area.utils.CustomizeAreaUtil;
import com.fjhx.common.constant.SourceConstant;
import com.fjhx.file.utils.ObsFileUtil;
import com.fjhx.supply.entity.supplier.dto.SupplierInfoDto;
import com.fjhx.supply.entity.supplier.dto.SupplierInfoSelectDto;
import com.fjhx.supply.entity.supplier.po.SupplierInfo;
import com.fjhx.supply.entity.supplier.vo.SupplierInfoVo;
import com.fjhx.supply.mapper.supplier.SupplierInfoMapper;
import com.fjhx.supply.service.supplier.SupplierInfoService;
import com.fjhx.supply.utils.CodeEnum;
import com.fjhx.tenant.entity.dict.dto.DictTenantDataSelectDto;
import com.fjhx.tenant.entity.dict.vo.DictTenantDataVo;
import com.fjhx.tenant.service.dict.DictTenantDataService;
import com.obs.services.internal.ServiceException;
import com.ruoyi.common.core.domain.BaseSelectDto;
import com.ruoyi.common.utils.wrapper.IWrapper;
import com.ruoyi.common.utils.wrapper.SqlField;
import org.apache.commons.collections4.ListUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * <p>
 * 供应商 服务实现类
 * </p>
 *
 * @author
 * @since 2023-03-17
 */
@DS(SourceConstant.SUPPLY)
@Service
public class SupplierInfoServiceImpl extends ServiceImpl<SupplierInfoMapper, SupplierInfo> implements SupplierInfoService {

    @Autowired
    private DictTenantDataService dictTenantDataService;

    @Override
    public Page<SupplierInfoVo> getPage(SupplierInfoSelectDto dto) {
        IWrapper<SupplierInfo> wrapper = getWrapper();
        wrapper.orderByDesc("si", SupplierInfo::getId);
        wrapper.eq("si", SupplierInfo::getType, dto.getType());
        wrapper.like("si",SupplierInfo::getCode,dto.getCode());
        wrapper.like("si",SupplierInfo::getName,dto.getName());
        wrapper.eq("si",SupplierInfo::getCountryId,dto.getCountryId());
        wrapper.eq("si",SupplierInfo::getProvinceId,dto.getProvinceId());
        wrapper.eq("si",SupplierInfo::getCityId,dto.getCityId());
        wrapper.keyword(dto,
                new SqlField("si", SupplierInfo::getName),
                new SqlField("si", SupplierInfo::getCode)
        );
        Page<SupplierInfoVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);

        List<SupplierInfoVo> records = page.getRecords();
        if (records.size() == 0) {
            return page;
        }
        CustomizeAreaUtil.setAreaName(records);
        return page;
    }

    /**
     * 供应商分页维多利亚用
     */
    @Override
    public Page<SupplierInfoVo> getPageByWdly(SupplierInfoSelectDto dto) {
        IWrapper<SupplierInfo> wrapper = getWrapper();
        wrapper.orderByDesc("si", SupplierInfo::getId);
        wrapper.eq("si", SupplierInfo::getType, dto.getType());
        wrapper.keyword(dto,
                new SqlField("si", SupplierInfo::getName),
                new SqlField("si", SupplierInfo::getCode)
        );
        //根据账期过滤
        Integer accountPeriodType = dto.getAccountPeriodType();
        if (ObjectUtil.isNotEmpty(accountPeriodType)) {
            if (1 == accountPeriodType) {
                wrapper.isNotNull("json_unquote( si.victoriatourist_json -> '$.accountPeriod' )");
                wrapper.apply("json_unquote( si.victoriatourist_json -> '$.accountPeriod' ) !=''");
                wrapper.apply("json_unquote( si.victoriatourist_json -> '$.accountPeriod' ) !='0'");
            } else {
                wrapper.isNull("json_unquote( si.victoriatourist_json -> '$.accountPeriod' )");
                wrapper.or();
                wrapper.apply("json_unquote( si.victoriatourist_json -> '$.accountPeriod' ) =''");
                wrapper.or();
                wrapper.apply("json_unquote( si.victoriatourist_json -> '$.accountPeriod' ) ='0'");
            }
        }
        Page<SupplierInfoVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);

        List<SupplierInfoVo> records = page.getRecords();
        if (records.size() == 0) {
            return page;
        }
        CustomizeAreaUtil.setAreaName(records);
        return page;
    }

    @Override
    public SupplierInfoVo detail(Long id) {
        SupplierInfo SupplierInfo = this.getById(id);
        SupplierInfoVo result = BeanUtil.toBean(SupplierInfo, SupplierInfoVo.class);
        CustomizeAreaUtil.setAreaName(result);
        return result;
    }

    @Override
    public SupplierInfoVo detailByWdly(Long id) {
        SupplierInfoVo result = detail(id);

        //辅助前端 将账期和退换货期限 两个字段转为字符串
        JSONObject json = ObjectUtil.isNotEmpty(result.getVictoriatouristJson()) ? JSONObject.parseObject(result.getVictoriatouristJson()) : new JSONObject();
        json.put("accountPeriod",json.getString("accountPeriod"));
        json.put("returnPeriod",json.getString("returnPeriod"));
        result.setVictoriatouristJson(JSONObject.toJSONString(json,JSONWriter.Feature.WriteLongAsString));
        return result;
    }

    @DSTransactional
    @Override
    public void add(SupplierInfoDto supplierInfoDto) {
        CustomizeAreaUtil.setAreaId(supplierInfoDto);
        supplierInfoDto.setCode(CodeEnum.SUPPLIER_INFO.getCode());
        this.save(supplierInfoDto);
        ObsFileUtil.saveFile(supplierInfoDto.getFileList(), supplierInfoDto.getId());
    }

    @DSTransactional
    @Override
    public void edit(SupplierInfoDto supplierInfoDto) {
        CustomizeAreaUtil.setAreaId(supplierInfoDto);
        supplierInfoDto.setCode(null);
        this.updateById(supplierInfoDto);
        ObsFileUtil.editFile(supplierInfoDto.getFileList(), supplierInfoDto.getId());
    }

    @DSTransactional
    @Override
    public void delete(Long id) {
        this.removeById(id);
        ObsFileUtil.removeFile(id);
    }

    /**
     * 供应商统计
     */
    @Override
    public Map<String, Object> supplierStatistics(BaseSelectDto dto) {
        //存放供应商统计数据
        Map<String,Object> map = new HashMap<>();
        //存放供应商类型数据列表
        List<Map<String,Object>> list = new ArrayList<>();

        QueryWrapper<SupplierInfo> query = Wrappers.query();
        //为-1则说明没有查到供应商的数据（如果为null的话后面list转map报错）
        query.select("ifnull(type,-1) type,count(*) count");
        query.groupBy("type");
        //查询供应商统计
        List<SupplierInfo> supplierInfoList = baseMapper.selectList(query);
        Map<String, List<SupplierInfo>> supplierInfoMap = supplierInfoList.stream().collect(Collectors.groupingBy(SupplierInfo::getType));

        //赋值合计数据
        Integer amount = supplierInfoList.stream().map(SupplierInfo::getCount).reduce(Integer::sum).orElse(0);
        map.put("amount",amount);

        //切换数据源
        DynamicDataSourceContextHolder.push(SourceConstant.BASE);
        //获取供应商类型字典数据
        List<DictTenantDataVo> dictTenantDataVoList = getDict("supplier_type");
        DynamicDataSourceContextHolder.poll();

        if (ObjectUtil.isEmpty(dictTenantDataVoList)){
            throw new ServiceException("数据有误：没有配置供应商类型字典，请先配置");
        }

        //赋值
        for (DictTenantDataVo dictTenantDataVo : dictTenantDataVoList) {
            //设置初始值
            Map<String,Object> supplierMap = new HashMap<>();
            supplierMap.put("type",dictTenantDataVo.getDictValue());
            supplierMap.put("count",0);

            //赋值数量
            List<SupplierInfo> supplierInfos = supplierInfoMap.get(dictTenantDataVo.getDictKey());
            if (ObjectUtil.isNotEmpty(supplierInfos)){
                supplierMap.put("count",supplierInfos.get(0).getCount());
            }
            list.add(supplierMap);
        }
        map.put("supplierInfoList",list);
        return map;
    }

    //根据字典编码获取字典的数据
    private List<DictTenantDataVo> getDict(String code){
        DictTenantDataSelectDto dto = new DictTenantDataSelectDto();
        dto.setDictCode(code);
        return dictTenantDataService.getList(dto);
    }
}
