package com.fs.company.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import com.fs.common.exception.ServiceException;
import com.fs.common.utils.DateUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fs.company.domain.Company;
import com.fs.company.domain.CompanyDomainBind;
import com.fs.company.mapper.CompanyDomainBindMapper;
import com.fs.company.mapper.CompanyMapper;
import com.fs.company.param.CompanyDomainParam;
import com.fs.company.vo.CompanyDomainExportTemplateVo;
import com.fs.company.vo.CompanyDomainVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fs.company.mapper.CompanyDomainMapper;
import com.fs.company.domain.CompanyDomain;
import com.fs.company.service.ICompanyDomainService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 域名管路Service业务层处理
 *
 * @author fs
 * @date 2025-06-16
 */
@Service
public class CompanyDomainServiceImpl extends ServiceImpl<CompanyDomainMapper, CompanyDomain> implements ICompanyDomainService {
    @Autowired
    private CompanyMapper companyMapper;

    @Autowired
    private CompanyDomainMapper baseMapper;

    @Autowired
    private CompanyDomainBindMapper companyDomainBindMapper;

    /**
     * 查询域名管路
     *
     * @param id 域名管路主键
     * @return 域名管路
     */
    @Override
    public CompanyDomain selectCompanyDomainById(Long id) {
        return baseMapper.selectCompanyDomainById(id);
    }

    /**
     * 查询域名管路列表
     *
     * @param companyDomain 域名管路
     * @return 域名管路
     */
    @Override
    public List<CompanyDomainVo> selectCompanyDomainList(CompanyDomainParam companyDomain) {
        return baseMapper.selectCompanyDomainJoinInfo(companyDomain);
    }

    /**
     * 新增域名管路
     *
     * @param companyDomain 域名管路
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertCompanyDomain(CompanyDomain companyDomain) {
        //验证是否域名重复
        if (baseMapper.selectCount(new LambdaQueryWrapper<CompanyDomain>().eq(CompanyDomain::getDomain, companyDomain.getDomain()).eq(CompanyDomain::getStatus, 1)) > 0) {
            throw new ServiceException("更新失败，当前域名" + companyDomain.getDomain() + "已存在！");
        }

        companyDomain.setCreateTime(DateUtils.getNowDate());
        return baseMapper.insertCompanyDomain(companyDomain);
    }

    /**
     * 修改域名管路
     *
     * @param companyDomain 域名管路
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateCompanyDomain(CompanyDomain companyDomain) {
        //验证数据是否存在
        CompanyDomain domain = baseMapper.selectById(companyDomain.getId());
        if (ObjectUtil.isEmpty(domain)) {
            throw new ServiceException("操作失败，更新数据不存在！");
        }

        //验证是否域名重复
        if (baseMapper.selectCount(new LambdaQueryWrapper<CompanyDomain>().eq(CompanyDomain::getDomain, companyDomain.getDomain()).eq(CompanyDomain::getStatus, 1).ne(CompanyDomain::getId, companyDomain.getId())) > 0) {
            throw new ServiceException("更新失败，当前域名" + companyDomain.getDomain() + "已存在！");
        }

        companyDomain.setUpdateTime(DateUtils.getNowDate());
        return baseMapper.updateCompanyDomain(companyDomain);
    }

    /**
     * 批量删除域名管路
     *
     * @param ids 需要删除的域名管路主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteCompanyDomainByIds(Long[] ids) {
        //查询域名
        CompanyDomainParam companyDomain = new CompanyDomainParam();
        companyDomain.setIds(ids);
        List<CompanyDomainVo> domainList = baseMapper.selectCompanyDomainJoinInfo(companyDomain);
        if (domainList.isEmpty() || domainList.size() != ids.length) {
            throw new ServiceException("域名数量不一致，请核对后再试！");
        }

//        Map<Long, CompanyDomainVo> checkMap = domainList.stream().collect(Collectors.toMap(CompanyDomainVo::getId, d -> d));
//        //查询是否有分配
//        CompanyDomainVo checkVo;
//        for (Long id : ids) {
//            checkVo = checkMap.get(id);
//            if (ObjectUtil.isNotNull(checkVo)) {
//                if (ObjectUtil.isNotNull(checkVo.getBindNum()) && checkVo.getBindNum() > 0) {
//                    throw new ServiceException("删除失败，当前域名" + checkVo.getDomain() + "已绑定" + checkVo.getBindNum() + "家销售公司，请解绑后操作！");
//                } else if (checkVo.getStatus() == 1) {
//                    throw new ServiceException("删除失败，当前域名" + checkVo.getDomain() + "状态正常启用中，请关闭后操作！");
//                }
//            }
//        }
        //删除域名企业中间表数据
        companyDomainBindMapper.deleteCompanyDomainBindBydomainIds(ids);
        //删除企业销售中间表数据

        return baseMapper.deleteCompanyDomainByIds(ids);
    }

    /**
     * 删除域名管路信息
     *
     * @param id 域名管路主键
     * @return 结果
     */
    @Override
    public int deleteCompanyDomainById(Long id) {
        return baseMapper.deleteCompanyDomainById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R domainBatchBinding(CompanyDomainParam param) {
        // 验证绑定域名是否存在（批量查询）
        List<CompanyDomain> domainList = baseMapper.selectList(
                new LambdaQueryWrapper<CompanyDomain>()
                        .select(CompanyDomain::getId)
                        .in(CompanyDomain::getId, param.getDomainIds())
                        .eq(CompanyDomain::getStatus, 1)
        );

        if (domainList.isEmpty()) {
            return R.failed("绑定域名数据不存在！");
        }

        if (domainList.size() != param.getDomainIds().size()) {
            return R.failed("绑定域名中存在状态非激活或不存在的记录！");
        }

        // 验证绑定企业是否存在
        List<Company> companyList = companyMapper.selectCompanyByIds(param.getCompanyIds());
        if (companyList.isEmpty()) {
            return R.failed("绑定企业数据不存在！");
        }

        if (companyList.size() != param.getCompanyIds().size()) {
            return R.failed("绑定企业中存在不存在的记录！");
        }

        // 获取已存在的绑定关系
        Set<String> existingBinds = companyDomainBindMapper.selectList(
                        new LambdaQueryWrapper<CompanyDomainBind>()
                                .select(CompanyDomainBind::getDomainId, CompanyDomainBind::getCompanyId)
                                .in(CompanyDomainBind::getDomainId, param.getDomainIds())
                                .in(CompanyDomainBind::getCompanyId, param.getCompanyIds())
                )
                .stream()
                .map(bind -> bind.getDomainId() + "key" + bind.getCompanyId())
                .collect(Collectors.toSet());

        // 生成待插入的绑定关系（优化集合操作）
        List<CompanyDomainBind> insertList = new ArrayList<>();
        String userId = param.getUserId();  // 假设此处为userId

        for (Long domainId : param.getDomainIds()) {
            for (Company company : companyList) {
                String key = domainId + "key" + company.getCompanyId();
                if (!existingBinds.contains(key)) {
                    insertList.add(createBind(domainId, company, userId));
                }
            }
        }

        // 批量插入数据（修正条件判断）
        if (!insertList.isEmpty()) {
            // 分批处理，每批1000条
            batchBindInsert(insertList, 1000);
        }

        return R.ok("操作成功！");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R importDomainData(CompanyDomainParam param, List<CompanyDomainExportTemplateVo> domainList) {
        if (!domainList.isEmpty()) {
            //查询域名列表数据
            List<String> domains = domainList.stream().map(CompanyDomainExportTemplateVo::getDomain).collect(Collectors.toList());
            List<CompanyDomain> companyDomainList = baseMapper.selectList(new LambdaQueryWrapper<CompanyDomain>().select(CompanyDomain::getDomain).eq(CompanyDomain::getStatus, 1).in(CompanyDomain::getDomain, domains));
            Map<String, Long> checkMap = companyDomainList.stream().collect(Collectors.toMap(CompanyDomain::getDomain, s -> 0L));
            //便利数据
            List<CompanyDomain> insertList = new LinkedList<>();
            String userId = param.getUserId();
            domainList.stream().filter(d -> ObjectUtil.isNotNull(d.getDomain())).forEach(f -> {
                if (!checkMap.containsKey(f.getDomain())) {
                    CompanyDomain domain = new CompanyDomain();
                    domain.setStatus(1L);//默认启用
                    domain.setCreateBy(userId);
                    domain.setDomain(f.getDomain());
                    domain.setRemark(f.getRemark());
                    domain.setCreateTime(new Date());
                    insertList.add(domain);
                    checkMap.put(f.getDomain(), 0L);
                }
            });

            //批量插入
            if (!insertList.isEmpty()) {
                batchDomainInsert(insertList, 1000);
            }
        }
        return R.ok(null);
    }

    // 辅助方法：创建绑定对象
    private CompanyDomainBind createBind(Long domainId, Company company, String userId) {
        CompanyDomainBind bind = new CompanyDomainBind();
        bind.setDomainId(domainId);
        bind.setCompanyId(company.getCompanyId());
        bind.setCreateBy(userId);
        bind.setCreateTime(new Date());  // 补充创建时间
        return bind;
    }

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

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