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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
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.fjhx.tenant.utils.DeptUstil;
import com.ruoyi.common.core.domain.BaseSelectDto;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.wrapper.IWrapper;
import com.ruoyi.common.utils.wrapper.SqlField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
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.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)
        );

        //权限过滤：供应商自己看自己，总公司看全部
        Long companyId = SecurityUtils.getCompanyId();
        if (!Objects.equals(companyId, 100L)) {
            wrapper.eq("si", SupplierInfo::getCompanyId, companyId);
        } else {
            wrapper.eq("si", SupplierInfo::getCompanyId, dto.getCompanyId());
        }

        wrapper.orderByDesc("si", SupplierInfo::getId);

        Page<SupplierInfoVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);

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


        //获取归属公司信息
        List<Long> companyIds = records.stream().map(SupplierInfo::getCompanyId).collect(Collectors.toList());
        Map<Long, String> companyNameMap = DeptUstil.getDeptNameMap(companyIds);

        for (SupplierInfoVo record : records) {
            //赋值生产公司名称
            record.setCompanyName(companyNameMap.get(record.getCompanyId()));
        }

        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;
    }

    @DSTransactional
    @Override
    public void add(SupplierInfoDto supplierInfoDto) {
        CustomizeAreaUtil.setAreaId(supplierInfoDto);
        supplierInfoDto.setCode(CodeEnum.SUPPLIER_INFO.getCode());

        //赋值产品归属公司
        Long companyId = supplierInfoDto.getCompanyId();
        if (ObjectUtil.isEmpty(companyId)) {
            supplierInfoDto.setCompanyId(SecurityUtils.getCompanyId());
        }

        this.save(supplierInfoDto);
        ObsFileUtil.saveFile(supplierInfoDto.getFileList(), supplierInfoDto.getId());
    }

    @DSTransactional
    @Override
    public void edit(SupplierInfoDto supplierInfoDto) {
        CustomizeAreaUtil.setAreaId(supplierInfoDto);
        supplierInfoDto.setCode(null);

        //赋值产品归属公司
        Long companyId = supplierInfoDto.getCompanyId();
        if (ObjectUtil.isEmpty(companyId)) {
            supplierInfoDto.setCompanyId(SecurityUtils.getCompanyId());
        }

        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);
    }
}
