package com.gree.mall.manager.logic.common;

import cn.hutool.core.convert.Convert;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gree.mall.manager.bean.admin.AdminUserCom;
import com.gree.mall.manager.bean.common.SysDictCompanyVO;
import com.gree.mall.manager.bean.common.SysDictVO;
import com.gree.mall.manager.commonmapper.AdminMapper;
import com.gree.mall.manager.constant.SysDictConstant;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.plus.entity.*;
import com.gree.mall.manager.plus.service.*;
import com.gree.mall.manager.utils.RedisUtil;
import com.gree.mall.manager.utils.excel.ExcelUtils;
import com.gree.mall.manager.zfire.bean.ZfireParamBean;
import com.gree.mall.manager.zfire.util.FieldUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


@Service
public class SysDictCompanyLogic {

    @Autowired
    CommonLogic commonLogic;


    @Autowired
    SysDictCompanyService sysDictCompanyService;
    @Autowired
    SysDictRefService sysDictRefService;

    @Autowired
    SysDictTypeCompanyService sysDictTypeCompanyService;
    @Autowired
    AdminMapper adminMapper;
    @Autowired
    BrandService brandService;
    @Autowired
    OrderSmallTypeService orderSmallTypeService;
    @Autowired
    RedisUtil redisUtil;


    /**
     * 字典类型
     *
     * @param open 是否开放业务人配置 , 为空不限制
     * @return
     */
    public List<SysDictTypeCompany> typeList(Boolean open) {
        List<SysDictTypeCompany> list = sysDictTypeCompanyService
                .lambdaQuery()
                .eq(Objects.nonNull(open), SysDictTypeCompany::getOpen, open)
                .list();
        return list;
    }


    /**
     * 字典列表
     */
    public IPage<SysDictCompanyVO> sysDictIPage(ZfireParamBean zfireParamBean) {
        ZfireParamBean zfireParam = FieldUtils.supplyParam(zfireParamBean);
        AdminUserCom adminUser = commonLogic.getAdminUser();
        List<String> companyWechatIds = adminUser.getCompanyWechatIds();

        String dictType = (String)zfireParam.getParamValue("a.dict_type");
        if(StringUtils.equals(dictType, SysDictConstant.BRAND)){
            List<Brand> list = brandService.lambdaQuery().in(CollectionUtils.isNotEmpty(companyWechatIds),Brand::getCompanyWechatId, companyWechatIds).list();
            List<SysDictCompanyVO> records = new ArrayList<>();
            for(Brand brand : list){
                SysDictCompanyVO bean = new SysDictCompanyVO();
                bean.setDictCode(brand.getId());
                bean.setDictValue(brand.getBrandName());
                records.add(bean);
            }
            return new Page<SysDictCompanyVO>().setRecords(records);
        }

        IPage<SysDictCompanyVO> sysDictIPage = adminMapper.sysDictCompanyList(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParam
                , companyWechatIds);
        return sysDictIPage;
    }


    /**
     * 删除字典
     *
     * @param id
     * @param open 是否开放业务, 为空或者false不限制
     */
    public void delete(String id, Boolean open) {
        if (BooleanUtils.isTrue(open)) {
            String dictType = sysDictCompanyService.lambdaQuery()
                    .select(SysDictCompany::getDictType)
                    .eq(SysDictCompany::getSysDictId, id)
                    .oneOpt()
                    .map(SysDictCompany::getDictType)
                    .orElseThrow(() -> new RemoteServiceException("字典值不存在"));
            sysDictTypeCompanyService.lambdaQuery()
                    .select(SysDictTypeCompany::getOpen)
                    .eq(SysDictTypeCompany::getDictType, dictType)
                    .oneOpt()
                    .map(SysDictTypeCompany::getOpen)
                    .filter(item -> item)
                    .orElseThrow(() -> new RemoteServiceException("该字典类型暂不开放配置"));
        }

        SysDictCompany sysDictCompany = sysDictCompanyService.getById(id);
        if(sysDictCompany != null){
            if(sysDictCompany.getDictType().equals(SysDictConstant.ORDER_CHANNEL)){
                if(StringUtils.equals("商城",sysDictCompany.getDictValue())){
                    throw new RemoteServiceException("不可删除【商城】此字典字段");
                }
            }
        }

        sysDictCompanyService.removeById(id);

    }

    /**
     * 字典详情
     */
    public SysDictCompany detail(String id) {
        return sysDictCompanyService.getById(id);
    }


    /**
     * 字典查询，key = dictCode  value = dictObject
     * @param type
     * @return
     */
    public Map<String, SysDictCompany> dictByTypeOfCode(String type,String companyWechatId){
        List<SysDictCompany> sysDicts = this.dictByType(type,true,companyWechatId);
        Map<String, SysDictCompany> sysDictMap = sysDicts.stream().collect(Collectors.toMap(v -> v.getDictCode(), Function.identity()));
        return sysDictMap;
    }
    public SysDictCompany dictByTypeOfCode(String type,String dictCode,String companyWechatId){
        List<SysDictCompany> sysDicts = this.dictByType(type,true,companyWechatId);
        Map<String, SysDictCompany> sysDictMap = sysDicts.stream().collect(Collectors.toMap(v -> v.getDictCode(), Function.identity()));
        return sysDictMap.get(dictCode);
    }

    /**
     * 字典查询，key = dictValue value = dictObject
     * @param type
     * @return
     */
    public Map<String, SysDictCompany> dictByTypeOfValue(String type,String companyWechatId){
        List<SysDictCompany> sysDicts = this.dictByType(type,true,companyWechatId);
        Map<String, SysDictCompany> sysDictMap = sysDicts.stream().collect(Collectors.toMap(v -> v.getDictValue(), Function.identity()));
        return sysDictMap;
    }
    public SysDictCompany dictByTypeOfValue(String type,String dictValue,String companyWechatId){
        List<SysDictCompany> sysDicts = this.dictByType(type,true,companyWechatId);
        Map<String, SysDictCompany> sysDictMap = sysDicts.stream().collect(Collectors.toMap(v -> v.getDictValue(), Function.identity()));
        return sysDictMap.get(dictValue);
    }


    /**
     * 品牌字典map
     * @param companyWechatId
     * @return
     */
    public Map<String, Brand> brandMapOfName(String companyWechatId){
        Map<String, Brand> brandMap = brandService.lambdaQuery()
                .eq(Brand::getCompanyWechatId,companyWechatId)
                .list().stream().collect(Collectors.toMap(Brand::getBrandName, v -> v));
        return brandMap;
    }

    /**
     * 品牌字典map
     * @param companyWechatId
     * @return
     */
    public Map<String, OrderSmallType> orderSmallTypeMap(String companyWechatId){
        Map<String, OrderSmallType> brandMap = orderSmallTypeService.lambdaQuery()
                .eq(OrderSmallType::getCompanyWechatId,companyWechatId)
                .list().stream().collect(Collectors.toMap(OrderSmallType::getOrderSmallTypeText, v -> v));
        return brandMap;
    }


    /**
     * 字典值查询
     *
     * @param type
     * @param open 是否开放业务, 为空查询所有
     * @return
     */
    public List<SysDictCompany> dictByType(String type, Boolean open,String companyWechatId) {
        SysDictTypeCompany dictType = sysDictTypeCompanyService.lambdaQuery()
                .eq(SysDictTypeCompany::getDictType, type)
                .eq(Objects.nonNull(open), SysDictTypeCompany::getOpen, open)
                .one();
        if (dictType == null) {
            return Collections.emptyList();
        }
        List<SysDictCompany> dictList = sysDictCompanyService.lambdaQuery()
                .eq(SysDictCompany::getDictType, type)
                .eq(SysDictCompany::getCompanyWechatId,companyWechatId)
                .orderByDesc(SysDictCompany::getSortNum)
                .list();

        return dictList;
    }

    public void saveOpenDict(SysDictCompany param) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        sysDictTypeCompanyService.lambdaQuery()
                .select(SysDictTypeCompany::getDictType)
                .eq(SysDictTypeCompany::getDictType, param.getDictType())
                .eq(SysDictTypeCompany::getOpen, true)
                .oneOpt()
                .orElseThrow(() -> new RemoteServiceException("暂不开放该字典类型配置"));
        checkRepeatDictCode(param.getDictType(), param.getDictValue(), param.getCompanyWechatId());
        if(adminUser != null) {
            param.setCompanyName(adminUser.getCompanyName());
            param.setCompanyWechatId(adminUser.getCompanyWechatId());
        }
        param.setDictCode(IdWorker.getIdStr());
        sysDictCompanyService.save(param);
    }

    public void updateOpenDict(SysDictCompany param) {
        String dictType = sysDictCompanyService.lambdaQuery()
                .select(SysDictCompany::getDictType)
                .eq(SysDictCompany::getSysDictId, param.getSysDictId())
                .oneOpt()
                .map(SysDictCompany::getDictType)
                .orElseThrow(() -> new RemoteServiceException("字典类型错误,修改失败"));
        sysDictTypeCompanyService.lambdaQuery()
                .select(SysDictTypeCompany::getDictType)
                .eq(SysDictTypeCompany::getDictType, dictType)
                .eq(SysDictTypeCompany::getOpen, true)
                .oneOpt()
                .orElseThrow(() -> new RemoteServiceException("暂不开放该字典类型配置"));
        
        SysDictCompany sysDictCompany = sysDictCompanyService.getById(param.getSysDictId());
        if(sysDictCompany != null){
            if(sysDictCompany.getDictType().equals(SysDictConstant.ORDER_CHANNEL)){
                if(StringUtils.equals("商城",sysDictCompany.getDictValue())){
                    throw new RemoteServiceException("不可编辑【商城】此字典字段");
                }
            }
        }
        sysDictCompanyService.updateById(param);
    }

    private void checkRepeatDictCode(String dictType, String value, String companyWechatId) {
        Integer count = sysDictCompanyService.lambdaQuery()
                .eq(SysDictCompany::getDictType, dictType)
                .eq(SysDictCompany::getDictValue, value)
                .eq(SysDictCompany::getCompanyWechatId, companyWechatId)
                .count();
        if (count > 0) {
            throw new RemoteServiceException(value + "重复存在");
        }
    }


    public void addType(SysDictType param) {
        param.insert();
    }

    public void updateType(SysDictType param) {
        param.updateById();
    }

    public void delType(String id, boolean b) {
        sysDictTypeCompanyService.removeById(id);
    }

    public SysDictTypeCompany detailType(String id) {
        return sysDictTypeCompanyService.getById(id);
    }

    public List<SysDictCompany> getSysDictList(String dictType) {
        List<SysDictCompany> list = sysDictCompanyService.lambdaQuery().eq(SysDictCompany::getDictType, dictType).list();
        return list;
    }

    @Transactional(rollbackFor = Exception.class)
    public void importExcel(List<Object> objects, HttpServletRequest request) {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        List<SysDictCompany> sysDictCompanyList = new ArrayList<>();

        List<SysDictTypeCompany> list = sysDictTypeCompanyService.lambdaQuery().list();

        for (Object o : objects) {
            List<Object> row = (List<Object>) o;

            SysDictCompany sysDictCompany = new SysDictCompany();

            List<SysDictTypeCompany> sysDictTypeCompanies = list.stream()
                    .filter(item -> item.getRemark().equals(Convert.toStr(row.get(0)))).collect(Collectors.toList());

            if (!CollectionUtils.isEmpty(sysDictTypeCompanies)) {
                sysDictCompany.setDictType(sysDictTypeCompanies.get(0).getDictType());
            } else {
                throw new RemoteServiceException("没有这个类型" + sysDictCompany.getDictType());
            }

            if (row.get(2).equals("开启"))
                sysDictCompany.setStatus("ON");
            else
                sysDictCompany.setStatus("OFF");

            sysDictCompany.setDictValue(Convert.toStr(row.get(1)));
            if (row.size() > 4) {
                sysDictCompany.setRemark(Convert.toStr(row.get(3)));
                sysDictCompany.setSortNum(Convert.toInt(row.get(4)));
            }

            sysDictCompany.setCompanyName(adminUser.getCompanyName());
            sysDictCompany.setCompanyWechatId(adminUser.getCompanyWechatId());
            sysDictCompany.setDictCode(IdWorker.getIdStr());

            checkRepeatDictCode(sysDictCompany.getDictType(), sysDictCompany.getDictValue(), sysDictCompany.getCompanyWechatId());

            sysDictCompanyList.add(sysDictCompany
            );

        }


        sysDictCompanyService.saveBatch(sysDictCompanyList);
    }
}
