package com.shzg.project.worn.service.impl;

import java.util.ArrayList;
import java.util.List;

import com.shzg.common.exception.ServiceException;
import com.shzg.common.utils.DateUtils;
import com.shzg.project.worn.unit.PinyinUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.shzg.project.worn.mapper.WornMaterialTypeMapper;
import com.shzg.project.worn.domain.WornMaterialType;
import com.shzg.project.worn.service.IWornMaterialTypeService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 物料类型Service业务层处理
 * 
 * @author shzg
 * @date 2026-03-11
 */
@Service
public class WornMaterialTypeServiceImpl implements IWornMaterialTypeService
{
    @Autowired
    private WornMaterialTypeMapper wornMaterialTypeMapper;

    /**
     * 查询物料类型
     * 
     * @param id 物料类型主键
     * @return 物料类型
     */
    @Override
    public WornMaterialType selectWornMaterialTypeById(Long id)
    {
        return wornMaterialTypeMapper.selectWornMaterialTypeById(id);
    }

    /**
     * 查询物料类型列表
     * 
     * @param wornMaterialType 物料类型
     * @return 物料类型
     */
    @Override
    public List<WornMaterialType> selectWornMaterialTypeList(WornMaterialType wornMaterialType)
    {
        return wornMaterialTypeMapper.selectWornMaterialTypeList(wornMaterialType);
    }


    /**
     * 新增物料类型
     * 
     * @return 结果
     */
    @Override
    public int insertWornMaterialType(WornMaterialType type)
    {
        Long parentId = type.getParentId();

        /** ==============================
         * 1 处理 parent_id / ancestors / level
         * ============================== */

        // 一级类型
        if (parentId == null || parentId == 0)
        {
            type.setParentId(0L);
            type.setAncestors("0");
            type.setLevel(1L);
        }
        // 子级类型
        else
        {
            WornMaterialType parent = wornMaterialTypeMapper.selectWornMaterialTypeById(parentId);

            if (parent == null)
            {
                throw new RuntimeException("父级类型不存在");
            }

            type.setParentId(parentId);

            // ancestors = 父级 ancestors + 父级id
            type.setAncestors(parent.getAncestors() + "," + parentId);

            // level = 父级level + 1
            type.setLevel(parent.getLevel() + 1);
        }


        /** ==============================
         * 2 自动生成类型编码 type_code
         * ============================== */

        String maxCode = wornMaterialTypeMapper.selectMaxTypeCode();

        int nextNum = 1;

        if (maxCode != null)
        {
            nextNum = Integer.parseInt(maxCode.substring(2)) + 1;
        }

        String newCode = "MT" + String.format("%04d", nextNum);

        type.setTypeCode(newCode);


        /** ==============================
         * 3 自动生成首字母
         * ============================== */

        String firstLetter = PinyinUtils.getFirstLetter(type.getTypeName());

        type.setFirstLetter(firstLetter);


        /** ==============================
         * 4 默认字段
         * ============================== */

        type.setIsDelete("0");
        type.setStatus("0");
        type.setCreateTime(DateUtils.getNowDate());


        /** ==============================
         * 5 插入数据库
         * ============================== */

        return wornMaterialTypeMapper.insertWornMaterialType(type);
    }
    /**
     * 修改物料类型
     * 
     * @param wornMaterialType 物料类型
     * @return 结果
     */
    @Override
    @Transactional
    public int updateWornMaterialType(WornMaterialType wornMaterialType)
    {
        Long id = wornMaterialType.getId();
        Long newParentId = wornMaterialType.getParentId();

        // 查询当前节点原始数据
        WornMaterialType old = wornMaterialTypeMapper.selectWornMaterialTypeById(id);

        // 查询新的父节点
        WornMaterialType parent = null;
        if (newParentId != null && newParentId != 0)
        {
            parent = wornMaterialTypeMapper.selectWornMaterialTypeById(newParentId);
        }

        String newAncestors;
        Long newLevel;

        if (parent != null)
        {
            newAncestors = parent.getAncestors() + "," + parent.getId();
            newLevel = parent.getLevel() + 1;
        }
        else
        {
            newAncestors = "0";
            newLevel = 1L;
        }

        wornMaterialType.setAncestors(newAncestors);
        wornMaterialType.setLevel(newLevel);

        // 更新当前节点
        int rows = wornMaterialTypeMapper.updateWornMaterialType(wornMaterialType);

        // 如果父节点发生变化，需要更新所有子节点 ancestors
        if (!old.getParentId().equals(newParentId))
        {
            List<WornMaterialType> children = wornMaterialTypeMapper.selectChildrenById(id);

            for (WornMaterialType child : children)
            {
                String childAncestors = child.getAncestors().replace(old.getAncestors(), newAncestors);
                child.setAncestors(childAncestors);
                wornMaterialTypeMapper.updateChildrenAncestors(child);
            }
        }

        return rows;
    }

    /**
     * 批量删除物料类型
     * 
     * @param ids 需要删除的物料类型主键
     * @return 结果
     */
    @Override
    public int deleteWornMaterialTypeByIds(Long[] ids)
    {
        for (Long id : ids)
        {
            // 查询是否存在子节点
            int count = wornMaterialTypeMapper.selectChildCountByParentId(id);

            if (count > 0)
            {
                throw new ServiceException("该物料类型存在子类型，不能删除");
            }
        }

        return wornMaterialTypeMapper.deleteWornMaterialTypeByIds(ids);
    }

    @Override
    public List<WornMaterialType> selectWornMaterialTypeTree()
    {
        List<WornMaterialType> list = wornMaterialTypeMapper.selectWornMaterialTypeList(new WornMaterialType());
        return buildTree(list);
    }

    /**
     * 构建树结构
     */
    private List<WornMaterialType> buildTree(List<WornMaterialType> list)
    {
        List<WornMaterialType> roots = new ArrayList<>();

        for (WornMaterialType node : list)
        {
            if (node.getParentId() != null && node.getParentId() == 0)
            {
                recursionFn(list, node);
                roots.add(node);
            }
        }

        return roots;
    }

    /**
     * 递归子节点
     */
    private void recursionFn(List<WornMaterialType> list, WornMaterialType node)
    {
        List<WornMaterialType> children = new ArrayList<>();

        for (WornMaterialType t : list)
        {
            if (node.getId().equals(t.getParentId()))
            {
                recursionFn(list, t);
                children.add(t);
            }
        }

        node.setChildren(children);
    }
}
