package com.zcloud.basic.info.persistence.repository.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.cola.dto.MultiResponse;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.cola.exception.BizException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jjb.saas.framework.auth.model.SSOUser;
import com.jjb.saas.framework.auth.utils.AuthContext;
import com.jjb.saas.framework.repository.common.PageHelper;
import com.jjb.saas.framework.repository.repo.impl.BaseRepositoryImpl;
import com.jjb.saas.system.client.tenanttype.facade.TenantTypeFacade;
import com.jjb.saas.system.client.tenanttype.response.TenantTypeCO;
import com.jjb.saas.system.client.unit.facade.UnitFacade;
import com.jjb.saas.system.client.unit.request.OpeUnitAddCmd;
import com.jjb.saas.system.client.unit.request.OpeUnitUpdateCmd;
import com.jjb.saas.system.client.user.facade.UserFacade;
import com.zcloud.basic.info.domain.enums.CorpTypeEnum;
import com.zcloud.basic.info.domain.enums.CorpUseFlagEnum;
import com.zcloud.basic.info.domain.enums.MenuEnum;
import com.zcloud.basic.info.persistence.dataobject.CorpInfoDO;
import com.zcloud.basic.info.persistence.mapper.CorpInfoMapper;
import com.zcloud.basic.info.persistence.repository.CorpInfoRepository;
import com.zcloud.basic.info.utils.Query;
import com.zcloud.gbscommon.utils.PageQueryHelper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * web-infrastructure
 *
 * @Author zhaokai
 * @Date 2025-10-29 16:02:17
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class CorpInfoRepositoryImpl extends BaseRepositoryImpl<CorpInfoMapper, CorpInfoDO> implements CorpInfoRepository {
    private final CorpInfoMapper corpInfoMapper;

    @DubboReference
    private UnitFacade unitFacade;
    @DubboReference
    private UserFacade userFacade;

    @DubboReference
    private TenantTypeFacade tenantTypeFacade;


    @Override
    public PageResponse<CorpInfoDO> listPage(Map<String, Object> params) {
        IPage<CorpInfoDO> iPage = new Query<CorpInfoDO>().getPage(params);
        QueryWrapper<CorpInfoDO> queryWrapper = new QueryWrapper<>();
        String menuPerms = "";
        initParams(queryWrapper, menuPerms, params);
        IPage<CorpInfoDO> result = corpInfoMapper.selectUserPage(iPage, queryWrapper, menuPerms);
        return PageHelper.pageToResponse(result, result.getRecords());
    }
    @Override
    public PageResponse<CorpInfoDO> listBasicPage(Map<String, Object> params) {
        IPage<CorpInfoDO> iPage = new Query<CorpInfoDO>().getPage(params);
        QueryWrapper<CorpInfoDO> queryWrapper = new QueryWrapper<>();
        String menuPerms = "";
        initParams(queryWrapper, menuPerms, params);
        IPage<CorpInfoDO> result = corpInfoMapper.selectUserBasicPage(iPage, queryWrapper, menuPerms);
        return PageHelper.pageToResponse(result, result.getRecords());
    }
    private void initParams(QueryWrapper<CorpInfoDO> queryWrapper, String menuPerms, Map<String, Object> params){
        queryWrapper = PageQueryHelper.createPageQueryWrapper(queryWrapper, params);
        List<Integer> enterpriseType = CorpTypeEnum.getCodesByEnterpriseType((Integer) params.get("enterpriseType"));
        if (CollUtil.isNotEmpty(enterpriseType)) {
            queryWrapper.in("type", enterpriseType);
        }
        //排除自己的企业,1：排除
        if(params.get("exCludeSelf") != null && (Integer) params.get("exCludeSelf") == 1){
            queryWrapper.ne("id", AuthContext.getTenantId());
        }

        if (params.get("enterpriseTypeList") != null
                && params.get("enterpriseTypeList") instanceof List){
            List<Integer> enterpriseTypeList = (List<Integer>) params.get("enterpriseTypeList");
            if (enterpriseTypeList !=  null && enterpriseTypeList.size() > 0){
                List<Integer> entTypeList = CorpTypeEnum.getCodesByEnterpriseType(enterpriseTypeList);
                if (CollUtil.isNotEmpty(entTypeList)) {
                    queryWrapper.in("type", entTypeList);
                }
            }
        }

        queryWrapper.orderByAsc("corp_order").orderByDesc("create_time");

        if (!ObjectUtils.isEmpty(params.get("menuPath"))) {
            menuPerms = MenuEnum.getMenuKeyByPath(params.get("menuPath").toString());
        }
        queryWrapper.eq("delete_enum", "FALSE");
    }
    @Override
    public PageResponse<CorpInfoDO> listPageNoPms(Map<String, Object> params) {
        IPage<CorpInfoDO> iPage = new Query<CorpInfoDO>().getPage(params);
        QueryWrapper<CorpInfoDO> queryWrapper = new QueryWrapper<>();
        queryWrapper = PageQueryHelper.createPageQueryWrapper(queryWrapper, params);
        List<Integer> enterpriseType = CorpTypeEnum.getCodesByEnterpriseType((Integer) params.get("enterpriseType"));
        if (CollUtil.isNotEmpty(enterpriseType)) {
            queryWrapper.in("type", enterpriseType);
        }
        queryWrapper.orderByAsc("corp_order").orderByDesc("create_time");
        String menuPerms = "";
        if (!ObjectUtils.isEmpty(params.get("menuPath"))) {
            menuPerms = MenuEnum.getMenuKeyByPath(params.get("menuPath").toString());
        }
        queryWrapper.eq("delete_enum", "FALSE");
        IPage<CorpInfoDO> result = corpInfoMapper.selectUserPageNoPms(iPage, queryWrapper, menuPerms);
        return PageHelper.pageToResponse(result, result.getRecords());
    }

    @Override
    public List<CorpInfoDO> listAll(Map<String, Object> params) {
        QueryWrapper<CorpInfoDO> queryWrapper = new QueryWrapper<>();
        queryWrapper = PageQueryHelper.createPageQueryWrapper(queryWrapper, params);
        List<Integer> enterpriseType = CorpTypeEnum.getCodesByEnterpriseType((Integer) params.get("enterpriseType"));
        if (CollUtil.isNotEmpty(enterpriseType)) {
            queryWrapper.in("type", enterpriseType);
        }
        if (params.get("enterpriseTypeList") != null
                && params.get("enterpriseTypeList") instanceof List){
            List<Integer> enterpriseTypeList = (List<Integer>) params.get("enterpriseTypeList");
            if (enterpriseTypeList !=  null && enterpriseTypeList.size() > 0){
                List<Integer> entTypeList = CorpTypeEnum.getCodesByEnterpriseType(enterpriseTypeList);
                if (CollUtil.isNotEmpty(entTypeList)) {
                    queryWrapper.in("type", entTypeList);
                }
            }
        }
        queryWrapper.orderByAsc("corp_order").orderByDesc("create_time");
        return corpInfoMapper.selectList(queryWrapper);
    }

    @Override
    public Long getCorpCountByCorpName(String corpName) {
        QueryWrapper<CorpInfoDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("corp_name", corpName);
        return corpInfoMapper.selectCount(queryWrapper);
    }

    @Override
    public void saveCorp(CorpInfoDO corpInfoDO) {
        SSOUser ssoUser = AuthContext.getCurrentUser();
        Long tenantId = ssoUser.getTenantId();
        List<String> tenantParentIds = Arrays.asList(ssoUser.getTenantParentIds().split(","));
        MultiResponse<TenantTypeCO> tenantTypeResponse = tenantTypeFacade.listByTenantIdAndNotDefualt(Long.parseLong( tenantParentIds.get(1)));
        Map<String, Long> tenantTypeMap = tenantTypeResponse.getData().stream().collect(Collectors.toMap(TenantTypeCO::getTenantTypeName, TenantTypeCO::getId));
        OpeUnitAddCmd ouac = new OpeUnitAddCmd();
        ouac.setTenantName(corpInfoDO.getCorpName());
        ouac.setTenantTypeId(tenantTypeMap.get(CorpTypeEnum.getNameByCode(corpInfoDO.getType())));
        //企业类型(0-普通企业，1-集团单位，2-股份单位，3-相关方企业，4-货主单位，5-驻港单位)
//        if(corpInfoDO.getType() == 0 || corpInfoDO.getType() == 1 || corpInfoDO.getType() == 2){
//            ouac.setTenantTypeId(1990693345743208448L);
//        } else if (corpInfoDO.getType() == 2){
//            ouac.setTenantTypeId(1990693388072124416L);
//        } else if (corpInfoDO.getType() == 3 || corpInfoDO.getType() == 4 || corpInfoDO.getType() == 5){
//            ouac.setTenantTypeId(1990693388072124416L);
//        }
        // LocalDate
        ouac.setEffectiveDate(LocalDate.of(2099, 12, 31));
        ouac.setAccount(corpInfoDO.getCorpName());
        ouac.setTenantId(tenantId);
        ouac.setPassword(corpInfoDO.getPassword());
        if(corpInfoDO!= null){
            ouac.setId(corpInfoDO.getId());
        }
//        try {
        log.info("创建企业请求底座请求:{}", JSONUtil.toJsonStr(ouac));
        SingleResponse<Long> corpId = unitFacade.add(ouac);
        log.info("创建企业请求底座返回:{}", JSONUtil.toJsonStr(corpId));
        if (corpId.getData() == null) {
            throw new BizException("底座添加失败");
        }
        corpInfoDO.setId(corpId.getData());
//        } catch (Exception e){
//            e.printStackTrace();
//        }

        save(corpInfoDO);

    }

    @Override
    public void updateCorpName(CorpInfoDO corpInfo) {
        UpdateWrapper<CorpInfoDO> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", corpInfo.getId());
        updateWrapper.set("corp_name", corpInfo.getCorpName());
        update(updateWrapper);


        OpeUnitUpdateCmd ouac = new OpeUnitUpdateCmd();
        ouac.setId(corpInfo.getId());
        ouac.setTenantName(corpInfo.getCorpName());
        ouac.setAccount(corpInfo.getCorpName());
        ouac.setTenantTypeId(1989262038388776960L);
        unitFacade.update(ouac);
    }

    @Override
    public Map<Long, String> getCorpinfoNameByCorpinfoId(List<Long> collect) {
        QueryWrapper<CorpInfoDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", collect);
        List<CorpInfoDO> corpInfoDOList = corpInfoMapper.selectList(queryWrapper);
        Map<Long, String> map = corpInfoDOList.stream().collect(
                Collectors.toMap(CorpInfoDO::getId, CorpInfoDO::getCorpName)
        );

        return map;
    }

    @Override
    public List<CorpInfoDO> getCorpinfoByCode(String code) {
        QueryWrapper<CorpInfoDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("code", code);
        return list(queryWrapper);
    }

    @Override
    public List<CorpInfoDO> getCorpinfoByCodeAndId(String code, Long id) {
        QueryWrapper<CorpInfoDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.ne("id", id);
        queryWrapper.eq("code", code);
        return list(queryWrapper);
    }

    @Override
    public Long checkCorpName(Map<String, Object> parmas) {
        QueryWrapper<CorpInfoDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("corp_name", parmas.get("corpName"));
        if (!ObjectUtil.isEmpty(parmas.get("id"))) {
            queryWrapper.ne("id", parmas.get("id"));
        }

        return corpInfoMapper.selectCount(queryWrapper);
    }

    @Override
    public PageResponse<CorpInfoDO> corpUserMiddlePage(Map<String, Object> params) {
        IPage<CorpInfoDO> iPage = new Query<CorpInfoDO>().getPage(params);
        if (ObjectUtil.isNotEmpty(params.get("eqType"))) {
            params.put("type", Arrays.asList(params.get("eqType")));
        } else {
            if (ObjectUtil.isNotEmpty(params.get("enterpriseType"))) {
                List<Integer> enterpriseType = CorpTypeEnum.getCodesByEnterpriseType((Integer) params.get("enterpriseType"));
                if (CollUtil.isNotEmpty(enterpriseType)) {
                    params.put("type", enterpriseType);
                }
            }
        }
        List<Integer> inType = (List<Integer>) params.get("inType");
        if (CollUtil.isNotEmpty(inType)) {
             params.put("type", inType);
        }
        String menuPerms = "";
        if (!ObjectUtils.isEmpty(params.get("menuPath"))) {
            menuPerms = MenuEnum.getMenuKeyByPath(params.get("menuPath").toString());
        }
        IPage<CorpInfoDO> result = corpInfoMapper.corpUserMiddlePage(iPage, params, menuPerms);
        return PageHelper.pageToResponse(result, result.getRecords());
    }

    @Override
    public CorpInfoDO getCorpInfoByCorpName(String corpName) {
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("corp_name", corpName);
        return corpInfoMapper.selectOne(queryWrapper);
    }

    @Override
    public List<CorpInfoDO> getByIdList(List<Long> corpinfoIds) {
        QueryWrapper<CorpInfoDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", corpinfoIds);
//        queryWrapper.eq("use_flag", CorpUseFlagEnum.YES.getCode());
        return corpInfoMapper.selectList(queryWrapper);
    }

    @Override
    public Boolean remove(Long id) {
        unitFacade.delete(id);
        UpdateWrapper updateWrapper = new UpdateWrapper<CorpInfoDO>().eq("id", id);
        updateWrapper.set("delete_enum", "TRUE");
        return update(updateWrapper);

    }

    @Override
    public Boolean isSupper() {
        //判断当前企业是否是监管端
        CorpInfoDO corpInfoDO = corpInfoMapper.selectById(AuthContext.getTenantId());
        if(corpInfoDO == null)
            throw new BizException("当前企业不存在");
        if(CorpTypeEnum.share.getCode().equals(corpInfoDO.getType()))
            return true;
        return false;
    }

    @Override
    public void deleteById(Long id) {
        UpdateWrapper updateWrapper = new UpdateWrapper<CorpInfoDO>();
        updateWrapper.eq("id", id);
        updateWrapper.set("delete_enum", "TRUE");
        update(updateWrapper);
    }
}

