package com.fs.company.service.impl;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fs.common.core.domain.R;
import com.fs.common.utils.DateUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fs.company.domain.CompanyDomain;
import com.fs.company.domain.CompanyDomainBindUser;
import com.fs.company.domain.CompanyUser;
import com.fs.company.mapper.CompanyDomainBindUserMapper;
import com.fs.company.mapper.CompanyDomainMapper;
import com.fs.company.mapper.CompanyUserMapper;
import com.fs.company.param.CompanyDomainBindParam;
import com.fs.company.vo.CompanyDomainBindVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fs.company.mapper.CompanyDomainBindMapper;
import com.fs.company.domain.CompanyDomainBind;
import com.fs.company.service.ICompanyDomainBindService;

/**
 * 域名绑定销售公司Service业务层处理
 *
 * @author fs
 * @date 2025-06-17
 */
@Service
public class CompanyDomainBindServiceImpl extends ServiceImpl<CompanyDomainBindMapper, CompanyDomainBind> implements ICompanyDomainBindService {
    @Autowired
    private CompanyDomainBindMapper baseMapper;
    @Autowired
    private CompanyUserMapper companyUserMapper;

    @Autowired
    private CompanyDomainMapper companyDomainMapper;

    @Autowired
    private CompanyDomainBindUserMapper companyDomainBindUserMapper;

    @Autowired
    private CompanyDomainBindUserServiceImpl companyDomainBindUserService;

    /**
     * 查询域名绑定销售公司
     *
     * @param id 域名绑定销售公司主键
     * @return 域名绑定销售公司
     */
    @Override
    public CompanyDomainBind selectCompanyDomainBindById(Long id) {

        return baseMapper.selectCompanyDomainBindById(id);
    }

    /**
     * 查询域名绑定销售公司列表
     *
     * @param companyDomainBind 域名绑定销售公司
     * @return 域名绑定销售公司
     */
    @Override
    public List<CompanyDomainBindVo> selectCompanyDomainBindList(CompanyDomainBindParam companyDomainBind) {
        return baseMapper.selectJoinBindInfo(companyDomainBind);
    }

    /**
     * 新增域名绑定销售公司
     *
     * @param companyDomainBind 域名绑定销售公司
     * @return 结果
     */
    @Override
    public int insertCompanyDomainBind(CompanyDomainBind companyDomainBind) {
        companyDomainBind.setCreateTime(DateUtils.getNowDate());
        return baseMapper.insertCompanyDomainBind(companyDomainBind);
    }

    /**
     * 修改域名绑定销售公司
     *
     * @param companyDomainBind 域名绑定销售公司
     * @return 结果
     */
    @Override
    public int updateCompanyDomainBind(CompanyDomainBind companyDomainBind) {
        companyDomainBind.setUpdateTime(DateUtils.getNowDate());
        return baseMapper.updateCompanyDomainBind(companyDomainBind);
    }

    /**
     * 批量删除域名绑定销售公司
     *
     * @param ids 需要删除的域名绑定销售公司主键
     * @return 结果
     */
    @Override
    public int deleteCompanyDomainBindByIds(Long[] ids) {
        //获取中间关联表
        List<CompanyDomainBindUser> companyDomainBindUserList = companyDomainBindUserMapper.selectList(new LambdaQueryWrapper<CompanyDomainBindUser>().in(CompanyDomainBindUser::getBindId, ids));
        if (ObjectUtil.isNotNull(companyDomainBindUserList) && !companyDomainBindUserList.isEmpty()) {
            Long[] idArray = companyDomainBindUserList.stream()
                    .map(CompanyDomainBindUser::getId)
                    .toArray(Long[]::new);
            //删除关联表
            companyDomainBindUserService.deleteCompanyDomainBindUserByIds(idArray);
        }

        return baseMapper.deleteCompanyDomainBindByIds(ids);
    }

    /**
     * 删除域名绑定销售公司信息
     *
     * @param id 域名绑定销售公司主键
     * @return 结果
     */
    @Override
    public int deleteCompanyDomainBindById(Long id) {
        return baseMapper.deleteCompanyDomainBindById(id);
    }

    @Override
    public R domainBatchBinding(CompanyDomainBindParam param) {
        //验证分配企业信息是否存在
        List<CompanyDomainBind> companyDomainBindList = baseMapper.selectList(new LambdaQueryWrapper<CompanyDomainBind>().in(CompanyDomainBind::getId, param.getCompanyIds()));

        if (companyDomainBindList.isEmpty()) {
            return R.error("分配域名企业数据不存在！");
        }
        if (companyDomainBindList.size() != param.getCompanyIds().size()) {
            return R.error("分配域名中存在不存在的记录！");
        }

        CompanyDomain domain = companyDomainMapper.selectById(companyDomainBindList.get(0).getDomainId());

        if (ObjectUtil.isEmpty(domain)) {
            return R.error("操作失败，域名不存在！");
        }

        //验证分配人员是否存在
        List<CompanyUser> companyUserList = companyUserMapper.getUserInfoByUserIds(param.getCompanyUserIds());
        if (companyUserList.isEmpty()) {
            return R.error("分配人员数据不存在！");
        }

        if (companyUserList.size() != param.getCompanyUserIds().size()) {
            return R.error("分配人员中存在不存在的记录！");
        }

        //获取分配关系
        Set<String> existingBinds = companyDomainBindUserMapper.selectList(new LambdaQueryWrapper<CompanyDomainBindUser>().in(CompanyDomainBindUser::getBindId, param.getCompanyIds()).in(CompanyDomainBindUser::getCompanyUserId, param.getCompanyUserIds())).stream()
                .map(bind -> bind.getBindId() + "key" + bind.getCompanyUserId())
                .collect(Collectors.toSet());

        List<CompanyDomainBindUser> insertUserList = new LinkedList<>();
        String userId = param.getUserId();
        for (Long bind : param.getCompanyIds()) {
            for (Long bindUser : param.getCompanyUserIds()) {
                String key = bind + "key" + bindUser;
                if (!existingBinds.contains(key)) {
                    CompanyDomainBindUser user = new CompanyDomainBindUser();
                    user.setBindId(bind);
                    user.setCompanyUserId(bindUser);
                    user.setCreateTime(new Date());
                    user.setCreateBy(userId);
                    insertUserList.add(user);
                }
            }
        }

        //批量插入数据
        if (!insertUserList.isEmpty()) {
            batchBindInsert(insertUserList, 1000);
        }

        //批量更新用户域名字段
        companyUserMapper.batchUpdateUserDomain(companyUserList.stream().map(CompanyUser::getUserId).collect(Collectors.toList()), domain.getDomain());
        return R.ok("操作成功！");
    }

    // 分批插入方法
    private void batchBindInsert(List<CompanyDomainBindUser> list, int batchSize) {
        for (int i = 0; i < list.size(); i += batchSize) {
            int end = Math.min(i + batchSize, list.size());
            companyDomainBindUserMapper.batchInsertBindUserInfo(list.subList(i, end));
        }
    }
}
