package com.bonus.material.ma.service.impl;

import com.bonus.common.biz.domain.MaTypeProperty;
import com.bonus.common.core.utils.DateUtils;
import com.bonus.common.core.utils.StringUtils;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.material.ma.mapper.MaTypeFileMapper;
import com.bonus.material.ma.mapper.MaTypeMapper;
import com.bonus.material.ma.service.ITypeService;
import com.bonus.material.ma.vo.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 工机具类型管理实现层
 */
@Service
public class MaTypeServiceImpl implements ITypeService {

    @Resource
    private MaTypeMapper maTypeMapper;

    @Resource
    private MaTypeFileMapper typeFileMapper;

    /**
     * 查询机具类型管理ma_type
     *
     * @param typeId 机具类型管理ma_type主键
     * @return 机具类型管理ma_type
     */
    @Override
    public MaType selectMaTypeByTypeId(Long typeId) {
        return maTypeMapper.selectMaTypeByTypeId(typeId);
    }


    /**
     * 新增机具类型管理ma_type
     *
     * @param maType 机具类型管理ma_type
     * @return 结果
     */
    @Override
    @Transactional
    public int insertMaType(MaType maType) {
        Long parentId = maType.getParentId();
        List<MaType> subMas = maTypeMapper.getListByParentId(parentId, null);
        boolean containsSameBrother = subMas.stream().anyMatch(o -> o.getTypeName().equals(maType.getTypeName()));
        if (containsSameBrother) {
            return 0;
        }
        MaType maType1 = maTypeMapper.selectMaTypeByTypeId(parentId);
        String level;
        if (maType1 == null) {
            level = "0";
        } else {
            level = maType1.getLevel();
        }
        maType.setLevel(String.valueOf(Integer.parseInt(level) + 1));
        maType.setCreateTime(DateUtils.getNowDate());
        int i = maTypeMapper.insertType(maType);
        Long typeId = maType.getTypeId();
        // 图片路径保存
        if (StringUtils.isNotEmpty(maType.getPhotoName()) && StringUtils.isNotEmpty(maType.getPhotoUrl())) {
            MaTypeFile typeFile = new MaTypeFile();
            typeFile.setTypeId(typeId);
            typeFile.setFileName(maType.getPhotoName());
            typeFile.setFileUrl(maType.getPhotoUrl());
            typeFile.setFileType("1");
            typeFile.setCreateTime(DateUtils.getNowDate());
            typeFileMapper.insertMaTypeFile(typeFile);
        }
        // 文档路径保存
        if (StringUtils.isNotEmpty(maType.getDocumentName()) && StringUtils.isNotEmpty(maType.getDocumentUrl())) {
            MaTypeFile typeFile1 = new MaTypeFile();
            typeFile1.setTypeId(typeId);
            typeFile1.setFileName(maType.getDocumentName());
            typeFile1.setFileUrl(maType.getDocumentUrl());
            typeFile1.setFileType("2");
            typeFile1.setCreateTime(DateUtils.getNowDate());
            typeFileMapper.insertMaTypeFile(typeFile1);
        }
        // 库管员配置
//        if (Objects.nonNull(maType.getKeeperUserId())) {
//            MaTypeKeeper typeKeeper = new MaTypeKeeper();
//            typeKeeper.setUserId(maType.getKeeperUserId());
//            typeKeeper.setTypeId(typeId);
//            typeKeeper.setCreateTime(DateUtils.getNowDate());
//            maTypeMapper.insertKeeper(typeKeeper);
//        }

        // 维修员配置
//        if (Objects.nonNull(maType.getRepairUserId())) {
//            MaTypeRepair typeRepair = new MaTypeRepair();
//            typeRepair.setUserId(maType.getRepairUserId());
//            typeRepair.setTypeId(typeId);
//            typeRepair.setCreateTime(DateUtils.getNowDate());
//            maTypeMapper.insertRepair(typeRepair);
//        }

        // 资产属性配置
        if (maType.getPropId() > 0) {
            MaPropSet propSet = new MaPropSet();
            propSet.setTypeId(typeId);
            propSet.setPropId(maType.getPropId());
            propSet.setCreateTime(DateUtils.getNowDate());
            maTypeMapper.insertMaPropSet(propSet);
        }

        return i;
    }

    /**
     * 修改机具类型管理ma_type
     *
     * @param maType 机具类型管理ma_type
     * @return 结果
     */
    @Override
    public int updateMaType(MaType maType) {
        Long typeId = maType.getTypeId();
        maType.setUpdateTime(DateUtils.getNowDate());
        int i = maTypeMapper.updateType(maType);
        //保存配置属性
        if (!CollectionUtils.isEmpty(maType.getMaTypeProperties())) {
            maTypeMapper.deleteMaTypePropertyNames(maType.getTypeId());
            List<MaTypeProperty> maTypeProperties = maType.getMaTypeProperties();
            //maTypeProperties.removeIf(MaTypeProperty::isNull);
            maTypeMapper.insertMaTypePropertyNames(maType.getTypeId(), maTypeProperties);
        }
        // 图片路径保存
        if (StringUtils.isNotEmpty(maType.getPhotoName()) && StringUtils.isNotEmpty(maType.getPhotoUrl())) {
            typeFileMapper.deleteMaTypeFileByTypeId(typeId, "1");
            MaTypeFile typeFile = new MaTypeFile();
            typeFile.setTypeId(typeId);
            typeFile.setFileName(maType.getPhotoName());
            typeFile.setFileUrl(maType.getPhotoUrl());
            typeFile.setFileType("1");
            typeFile.setCreateTime(DateUtils.getNowDate());
            typeFile.setUpdateTime(DateUtils.getNowDate());
            typeFileMapper.insertMaTypeFile(typeFile);
        }
        // 文档路径保存
        if (StringUtils.isNotEmpty(maType.getDocumentName()) && StringUtils.isNotEmpty(maType.getDocumentUrl())) {
            typeFileMapper.deleteMaTypeFileByTypeId(typeId, "2");
            MaTypeFile typeFile1 = new MaTypeFile();
            typeFile1.setTypeId(typeId);
            typeFile1.setFileName(maType.getDocumentName());
            typeFile1.setFileUrl(maType.getDocumentUrl());
            typeFile1.setFileType("2");
            typeFile1.setCreateTime(DateUtils.getNowDate());
            typeFile1.setUpdateTime(DateUtils.getNowDate());
            typeFileMapper.insertMaTypeFile(typeFile1);
        }
        // 库管员配置
//        if (maType.getKeeperUserId() != null) {
//            maTypeMapper.deleteKeeperByTypeId(typeId);
//            MaTypeKeeper typeKeeper = new MaTypeKeeper();
//            typeKeeper.setUserId(maType.getKeeperUserId());
//            typeKeeper.setTypeId(typeId);
//            typeKeeper.setCreateTime(DateUtils.getNowDate());
//            typeKeeper.setUpdateTime(DateUtils.getNowDate());
//            maTypeMapper.insertKeeper(typeKeeper);
//        }

        // 维修员配置
//        if (maType.getRepairUserId() != null) {
//            maTypeMapper.deleteTypeByTypeId(typeId);
//            MaTypeRepair typeRepair = new MaTypeRepair();
//            typeRepair.setUserId(maType.getRepairUserId());
//            typeRepair.setTypeId(typeId);
//            maTypeMapper.insertRepair(typeRepair);
//        }
        // 资产属性配置
        if (maType.getPropId() >= 0L) {
            maTypeMapper.deletePropSetByTypeId(typeId);
            MaPropSet propSet = new MaPropSet();
            propSet.setTypeId(typeId);
            propSet.setPropId(maType.getPropId());
            propSet.setCreateTime(DateUtils.getNowDate());
            propSet.setUpdateTime(DateUtils.getNowDate());
            maTypeMapper.insertMaPropSet(propSet);
        }
        return i;
    }

    /**
     * 删除机具类型管理ma_type信息
     *
     * @param typeId 机具类型管理ma_type主键
     * @return 结果
     */
    @Override
    public int deleteMaTypeByTypeId(Long typeId) throws Exception {
        List<MaType> listByParentId = maTypeMapper.getListByParentId(typeId, "");
        if (!listByParentId.isEmpty()) {
            throw new Exception("子级类型不为空!!!");
        }
        return maTypeMapper.deleteTypeById(typeId);
    }

    @Override
    public List<TreeSelect> getMaTypeList(String typeName, String parentId) {
        List<MaType> maTypes = maTypeMapper.selectMaTypeTree(parentId);
        //填充自定义属性
        //如果没有查询到那么返回空
        return buildDeptTreeSelect(fillProperties(maTypes));
    }

    private List<MaType> fillProperties(List<MaType> maTypes) {
        List<MaTypeProperty> maTypeProperties = maTypeMapper.selectMaTypePropertyNames();
        Map<Long, List<MaTypeProperty>> maTypePropertiesMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(maTypeProperties)) {
            maTypePropertiesMap = maTypeProperties.stream().collect(Collectors.groupingBy(MaTypeProperty::getTypeId));
        }
        for (MaType maType : maTypes) {
            maType.setMaTypeProperties(maTypePropertiesMap.get(maType.getTypeId()));
        }
        return maTypes;
    }

    @Override
    public List<TreeSelect> getMaTypeSelect(String typeName, String parentId) {
        List<MaType> maTypes = maTypeMapper.getMaTypeSelect(parentId);
        //如果没有查询到那么返回空
        return buildDeptTreeSelect(maTypes);
    }


    /**
     * 根据左列表类型id查询右表格
     *
     * @param typeId
     * @return
     */
    @Override
    public List<MaType> getListByMaType(Long typeId, String typeName) {
        List<MaType> maTypes = maTypeMapper.selectMaTypeList("");
        MaType maType = new MaType();
        maType.setTypeId(typeId);

        List<MaType> typeListByMaType = getTypeListByMaType(Collections.singletonList(maType), maTypes, new ArrayList<>());

        if (StringUtils.isNotNull(typeName)) {
            //根据类型名称过滤集合
            List<MaType> types = typeListByMaType
                    .stream()
                    .filter(ma -> ma.getTypeName().contains(typeName))
                    .collect(Collectors.toList());
            //如果没有查询到那么返回空
            return types;
        }
        return typeListByMaType;
    }

    /**
     * 根据父级类型递归获取树结构
     *
     * @param
     * @return
     */
    private List<MaType> getTypeListByMaType(List<MaType> parentTypes, List<MaType> oldMaTypes, List<MaType> newMaTypes) {
        //初始化新容器
        if (newMaTypes == null) {
            newMaTypes = new ArrayList<>();
            //添加父级对象 左边需要添加因为需要显示  右边不需要添加因为不需要显示
            newMaTypes.addAll(parentTypes);
        }
        //递归父级容器
        List<MaType> parentList = new ArrayList<>();
        //过滤相同数据,减少循环,性能优化
        oldMaTypes = oldMaTypes.stream().filter(oldMaType -> !parentTypes.contains(oldMaType)).collect(Collectors.toList());
        for (MaType maType : oldMaTypes) {
            for (MaType parentType : parentTypes) {
                if (maType.getParentId().equals(parentType.getTypeId())) {

                    newMaTypes.add(maType);
                    parentList.add(maType);
                }
            }
        }
        //如果还有父级递归查询
        if (!parentList.isEmpty()) {
            return getTypeListByMaType(parentList, oldMaTypes, newMaTypes);
        } else {
            List<MaType> result = new ArrayList<>();
            for (MaType type : newMaTypes) {
                boolean a = true;
                Long typeId1 = type.getTypeId();
                for (MaType type1 : newMaTypes) {
                    Long pid = type1.getParentId();
                    if (typeId1.equals(pid)) {
                        a = false;
                    }
                }
                if (a) {
                    result.add(type);
                }
            }
            //返回
            return result;
        }
    }


    /**
     * 构建前端所需要下拉树结构
     *
     * @param depts 部门列表
     * @return 下拉树结构列表
     */
    @Override
    public List<TreeSelect> buildDeptTreeSelect(List<MaType> depts) {
        List<MaType> deptTrees = buildDeptTree(depts);
        return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    /**
     * 构建前端所需要树结构
     *
     * @param maTypeList 部门列表
     * @return 树结构列表
     */
    @Override
    public List<MaType> buildDeptTree(List<MaType> maTypeList) {
        List<MaType> returnList = new ArrayList<>();
        List<Long> tempList = maTypeList.stream().map(MaType::getTypeId).collect(Collectors.toList());
        for (MaType maType : maTypeList) {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(maType.getParentId())) {
                recursionFn(maTypeList, maType);
                returnList.add(maType);
            }
        }
        if (returnList.isEmpty()) {
            returnList = maTypeList;
        }
        return returnList;
    }

    /**
     * 根据组织树parent_id查询结果
     *
     * @param typeId   父级id
     * @param typeName 名称筛选
     * @return
     */
    @Override
    public List<MaType> getListByParentId(Long typeId, String typeName) {
        return maTypeMapper.getListByParentId(typeId, typeName);
    }

    @Override
    public List<Integer> selectParentId(Long typeId, Integer level) {
        return maTypeMapper.selectParentId(typeId, level);
    }

    /**
     * 查询工器具类型四级组织树
     *
     * @param typeId
     * @param typeName
     * @return
     */
    @Override
    public List<MaType> getEquipmentType(Long typeId, String typeName) {
        List<MaType> maTypes = maTypeMapper.selectMaTypeList("");
        List<MaType> list = new ArrayList<>();
        for (MaType maType : maTypes) {
            if (maType.getParentId() == 0) {
                list.add(maType);
            }
        }
        List<MaType> tree = new ArrayList<>();
        //根据父节点获取对应的儿子节点
        for (MaType maType : list) {
            List<MaType> child = getChild(maTypes, maType.getTypeId());
            maType.setChildren(child);
            tree.add(maType);
        }

        return list;
    }

    @Override
    public Integer updateLeasePrice(MaType maType) {
        return maTypeMapper.updateLeasePrice(maType.getTypeIds(), maType.getLeasePrice());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult addProperties(MaType maType) {
        // 1. 参数校验
        if (maType == null || StringUtils.isEmpty(maType.getTypeName())) {
            return AjaxResult.error("参数不合法");
        }

        // 2. 检查同级节点是否有同名类型
        if (hasDuplicateTypeName(maType)) {
            return AjaxResult.error("未新增成功，请查看同一层级是否有重名的类型！");
        }

        try {
            // 3. 设置类型基本信息
            setupMaTypeBasicInfo(maType);

            // 4. 插入类型记录
            int insertCount = maTypeMapper.insertType(maType);
            if (insertCount <= 0) {
                return AjaxResult.error("新增类型失败");
            }

            // 5. 处理并插入属性
            Long typeId = maType.getTypeId();
            List<MaTypeProperty> properties = buildMaTypeProperties(typeId, maType.getFormFeature());

            if (!properties.isEmpty()) {
                int propertyInsertCount = maTypeMapper.insertMaTypePropertyNames(typeId, properties);
                if (propertyInsertCount <= 0) {
                    throw new RuntimeException("新增属性失败");
                }
            }

            return AjaxResult.success("新增成功");
        } catch (Exception e) {
            return AjaxResult.error("新增失败：" + e.getMessage());
        }
    }

    @Override
    public AjaxResult updateProperties(MaType maType) {
        // 1. 参数校验
        if (maType == null || StringUtils.isEmpty(maType.getTypeName())) {
            return AjaxResult.error("参数不合法");
        }

        // 2. 检查同级节点是否有同名类型
        if (hasDuplicateTypeName(maType)) {
            return AjaxResult.error("未修改成功，请查看同一层级是否有重名的类型！");
        }

        try {
            // 3. 设置类型基本信息
            setupMaTypeBasicInfo(maType);

            // 4. 插入类型记录
            int insertCount = maTypeMapper.updateType(maType);
            if (insertCount <= 0) {
                return AjaxResult.error("修改类型失败");
            }

            // 5. 处理并插入属性
            Long typeId = maType.getTypeId();
            List<MaTypeProperty> properties = buildMaTypeProperties(typeId, maType.getFormFeature());
            maTypeMapper.deleteMaTypePropertyNames(typeId);
            if (!properties.isEmpty()) {
                int propertyInsertCount = maTypeMapper.insertMaTypePropertyNames(typeId, properties);
                if (propertyInsertCount <= 0) {
                    throw new RuntimeException("修改属性失败");
                }
            }

            return AjaxResult.success("修改成功");
        } catch (Exception e) {
            return AjaxResult.error("修改失败：" + e.getMessage());
        }
    }

    @Override
    public List<MaType> getList(String typeName, Integer level, Integer parentId, String keyWord) {
        List<MaType> list = maTypeMapper.getList(typeName, level, parentId, keyWord);
        return fillProperties(list);
    }

    // 检查是否有重复类型名
    private boolean hasDuplicateTypeName(MaType maType) {
        Long parentId = maType.getParentId();
        Long currentId = maType.getTypeId(); // 可能为null（新增场景）
        String typeName = maType.getTypeName();

        List<MaType> siblings = maTypeMapper.getListByParentId(parentId, null);

        return siblings.stream()
                // 过滤逻辑：若currentId为null（新增），则不过滤任何节点；若不为null（编辑），则排除自身
                .filter(sibling -> currentId == null ? true : !sibling.getTypeId().equals(currentId))
                // 判断是否存在同名节点
                .anyMatch(sibling -> typeName.equals(sibling.getTypeName()));
    }

    // 设置类型基本信息
    private void setupMaTypeBasicInfo(MaType maType) {
        Long parentId = maType.getParentId();
        MaType parent = parentId == 0 ? null : maTypeMapper.selectMaTypeByTypeId(parentId);

        // 设置层级
        String level = parent == null ? "0" : parent.getLevel();
        maType.setLevel(String.valueOf(Integer.parseInt(level) + 1));

        // 设置其他信息
        maType.setCreateTime(DateUtils.getNowDate());
        maType.setCompanyId(parentId == 0 ? "101" : parent.getCompanyId());
    }

    // 构建类型属性列表
    private List<MaTypeProperty> buildMaTypeProperties(Long typeId, List<FormFeature> formFeatures) {
        if (CollectionUtils.isEmpty(formFeatures)) {
            return Collections.emptyList();
        }

        return formFeatures.stream()
                .flatMap(formFeature -> {
                    String propertyName = formFeature.getFeatureName();
                    String mustHave = formFeature.isRequired() ? "1" : "0";

                    if ("input".equals(formFeature.getInputType())) {
                        return Stream.of(createMaTypeProperty(typeId, propertyName, formFeature.getValue(), mustHave));
                    } else if ("select".equals(formFeature.getInputType())) {
                        return formFeature.getOptions().stream()
                                .map(value -> createMaTypeProperty(typeId, propertyName, value, mustHave));
                    }
                    return Stream.empty();
                })
                .collect(Collectors.toList());
    }

    // 创建类型属性对象
    private MaTypeProperty createMaTypeProperty(Long typeId, String propertyName, String propertyValue, String mustHave) {
        MaTypeProperty property = new MaTypeProperty();
        property.setTypeId(typeId);
        property.setPropertyName(propertyName);
        property.setPropertyValue(propertyValue);
        property.setMustHave(mustHave);
        return property;
    }

    /**
     * @Author dingjie
     * @Date 2023/12/14
     * @Description 递归调用获取儿子
     */
    public List<MaType> getChild(List<MaType> list, Long parentId) {
        List<MaType> childList = new ArrayList<MaType>();
        for (MaType maType : list) {
            Long typeId = maType.getTypeId();
            Long pid = maType.getParentId();
            if (parentId.equals(pid)) {
                List<MaType> childLists = getChild(list, typeId);

                maType.setChildren(childLists);
                childList.add(maType);
            }
        }
        return childList;
    }


    /**
     * 递归列表
     */
    private void recursionFn(List<MaType> list, MaType t) {
        // 得到子节点列表
        List<MaType> childList = getChildList(list, t);
        t.setChildren(childList);
        for (MaType tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }


    /**
     * 得到子节点列表
     */
    private List<MaType> getChildList(List<MaType> list, MaType t) {
        List<MaType> tlist = new ArrayList<MaType>();
        Iterator<MaType> it = list.iterator();
        while (it.hasNext()) {
            MaType n = (MaType) it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getTypeId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }


    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<MaType> list, MaType t) {
        return getChildList(list, t).size() > 0 ? true : false;
    }
}
