package com.ruoyi.project.business.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.ruoyi.common.enums.ValueType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.project.business.domain.*;
import com.ruoyi.project.business.dto.TpAreaOptionalDTO;
import com.ruoyi.project.business.enums.JEPFuncEnum;
import com.ruoyi.project.business.enums.JEPLogicEnum;
import com.ruoyi.project.business.mapper.TpAreaOptionalParaPriceMapper;
import com.ruoyi.project.business.service.ITpAreaElevatorModelParaService;
import com.ruoyi.project.business.service.ITpAreaOptionalParaPriceService;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.stream.Collectors;

import com.ruoyi.project.business.service.ITpAreaOptionalParaService;
import com.ruoyi.project.business.service.ITpParaLibraryService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * 【请填写功能名称】Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-05-28
 */
@Service
public class TpAreaOptionalParaPriceServiceImpl extends ServiceImpl<TpAreaOptionalParaPriceMapper, TpAreaOptionalParaPrice> implements ITpAreaOptionalParaPriceService
{
    @Autowired
    private TpAreaOptionalParaPriceMapper tpAreaOptionalParaPriceMapper;
    @Resource
    private ITpAreaOptionalParaService tpAreaOptionalParaService;
    @Resource
    private ITpAreaElevatorModelParaService tpAreaElevatorModelParaService;
    @Resource
    private ITpParaLibraryService tpParaLibraryService;

    /**
     * 查询【请填写功能名称】
     * 
     * @param id 【请填写功能名称】主键
     * @return 【请填写功能名称】
     */
    @Override
    public TpAreaOptionalParaPrice selectTpAreaOptionalParaPriceById(Long id)
    {
        return tpAreaOptionalParaPriceMapper.selectTpAreaOptionalParaPriceById(id);
    }

    /**
     * 查询【请填写功能名称】列表
     * 
     * @param tpAreaOptionalParaPrice 【请填写功能名称】
     * @return 【请填写功能名称】
     */
    @Override
    public List<TpAreaOptionalParaPrice> selectTpAreaOptionalParaPriceList(TpAreaOptionalParaPrice tpAreaOptionalParaPrice)
    {
        return tpAreaOptionalParaPriceMapper.selectTpAreaOptionalParaPriceList(tpAreaOptionalParaPrice);
    }

    /**
     * 新增【请填写功能名称】
     * 
     * @param tpAreaOptionalParaPrice 【请填写功能名称】
     * @return 结果
     */
    @Override
    public int insertTpAreaOptionalParaPrice(TpAreaOptionalParaPrice tpAreaOptionalParaPrice)
    {
        tpAreaOptionalParaPrice.setId(null);
        tpAreaOptionalParaPrice.setStatus("0");
        tpAreaOptionalParaPrice.setCreateBy(SecurityUtils.getUserId().toString());
        tpAreaOptionalParaPrice.setCreateTime(DateUtils.getNowDate());
        getFormula(Lists.newArrayList(tpAreaOptionalParaPrice));
        return tpAreaOptionalParaPriceMapper.insertTpAreaOptionalParaPrice(tpAreaOptionalParaPrice);
    }

    public void getFormula(List<TpAreaOptionalParaPrice> list) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        // 1. 取得梯型相关的参数
        TpAreaElevatorModelPara param = new TpAreaElevatorModelPara();
        param.setElevatorModelId(list.get(0).getElevatorModelId());
        List<TpAreaElevatorModelPara> paramList = tpAreaElevatorModelParaService.selectTpAreaElevatorModelParaList(param);

        List<TpParaLibrary> libraryList;
        if (CollectionUtils.isNotEmpty(paramList)) {
            TpParaLibrary library = new TpParaLibrary();
            library.setIds(paramList.stream().map(TpAreaElevatorModelPara::getParaId).collect(Collectors.toList()));
            libraryList = tpParaLibraryService.selectTpParaLibraryList(library).stream()
                    .sorted(Comparator.comparing(item -> -item.getParaName().length())).collect(Collectors.toList());
        } else {
            libraryList = Lists.newArrayList();
        }

        TpAreaOptionalPara current = tpAreaOptionalParaService.selectTpAreaOptionalParaById(list.get(0).getMarkupId());
        // 当前所有加价项
        TpAreaOptionalPara tpAreaOptionalPara = new TpAreaOptionalPara();
        tpAreaOptionalPara.setElevatorModelId(list.get(0).getElevatorModelId());
        List<TpAreaOptionalPara> paraList = tpAreaOptionalParaService.selectTpAreaOptionalParaList(tpAreaOptionalPara)
                .stream().filter(item -> !item.getId().equals(current.getId())).collect(Collectors.toList());;

        Function<String, String> replaceNames = formula -> {
            if (StringUtils.isBlank(formula)){
                return "";
            }

            // 1. 替换逻辑操作符
            for (JEPLogicEnum item : JEPLogicEnum.values()) {
                formula = formula.replaceAll(StringUtils.initLogicRegpx(item.getLogicKey()), item.getLogicValue());
            }

            // 2. 替换函数操作符
            for (JEPFuncEnum item : JEPFuncEnum.values()) {
                formula = formula.replaceAll(StringUtils.initFuncRegpx(item.getFuncValue()), Matcher.quoteReplacement("$@$" + item.getFuncKey() + "$@$"));
            }

            // 3. 替换变量名
            for (TpParaLibrary item: libraryList){
                formula = formula.replaceAll(StringUtils.initRegpx(item.getParaName()), Matcher.quoteReplacement("$_$" + item.getParaCode() + "$_$"));
            }

            // 4. 替换其他加价项
            for (TpAreaOptionalPara item: paraList){
                if (formula.indexOf(item.getMarkupName()) == -1) {
                    continue;
                }
                if(item.getId().equals(current.getId())){
                    continue;
                }
                if (item.getSortIndex() >= current.getSortIndex()) {
                    throw new ServiceException("公式中选择的其他加价项必须排在当前加价项之前");
                }
                formula = formula.replaceAll(StringUtils.initWordRegpx(item.getMarkupName()), Matcher.quoteReplacement("$_$" + item.getMarkupName() + "$_$"));
            }

            return formula;
        };

        list.forEach(item -> {
            if (ValueType.FORMULA.getCode().equals(item.getQuantityType())) {
                item.setQuantity(null);
                item.setQuantityFormula(replaceNames.apply(item.getQuantityFormulaTxt()));
            } else {
                item.setQuantityFormula("");
                item.setQuantityFormulaTxt("");
            }

            if (ValueType.FORMULA.getCode().equals(item.getPriceType())) {
                item.setPrice(null);
                item.setPriceFormula(replaceNames.apply(item.getPriceFormulaTxt()));
            } else {
                item.setPriceFormula("");
                item.setPriceFormulaTxt("");
            }
        });

    }

    /**
     * 修改【请填写功能名称】
     * 
     * @param tpAreaOptionalParaPrice 【请填写功能名称】
     * @return 结果
     */
    @Override
    public int updateTpAreaOptionalParaPrice(TpAreaOptionalParaPrice tpAreaOptionalParaPrice)
    {
        tpAreaOptionalParaPrice.setUpdateBy(SecurityUtils.getUserId().toString());
        tpAreaOptionalParaPrice.setUpdateTime(DateUtils.getNowDate());
        if (Objects.nonNull(tpAreaOptionalParaPrice.getPriceFormulaTxt())){
            getFormula(Lists.newArrayList(tpAreaOptionalParaPrice));
        }

        // 清空price字段
        tpAreaOptionalParaPriceMapper.clearPrice(tpAreaOptionalParaPrice.getId());
        return tpAreaOptionalParaPriceMapper.updateTpAreaOptionalParaPrice(tpAreaOptionalParaPrice);
    }

    /**
     * 批量删除【请填写功能名称】
     * 
     * @param ids 需要删除的【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteTpAreaOptionalParaPriceByIds(Long[] ids)
    {
        if (CollectionUtils.isEmpty(listByIds(Arrays.asList(ids)))) {
            throw new ServiceException("数据不存在或已被删除，请刷新后重试");
        }
        return tpAreaOptionalParaPriceMapper.deleteTpAreaOptionalParaPriceByIds(ids);
    }

    /**
     * 删除【请填写功能名称】信息
     *
     * @param id 【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteTpAreaOptionalParaPriceById(Long id) {
        if (Objects.isNull(getById(id))) {
            throw new ServiceException("数据不存在或已被删除，请刷新后重试");
        }
        return tpAreaOptionalParaPriceMapper.deleteTpAreaOptionalParaPriceById(id);
    }

    @Override
    public List<TpAreaOptionalDTO> listAllOptionParamInfoByElevatorModelId(Long elevatorModelId) {
        return tpAreaOptionalParaPriceMapper.listAllOptionParamInfoByElevatorModelId(elevatorModelId);
    }

    @Override
    public void deleteTpAreaOptionalParaPriceByElevatorModelId(Long id) {
        tpAreaOptionalParaPriceMapper.deleteTpAreaOptionalParaPriceByElevatorModelId(id);
    }
}
