package com.xjrsoft.module.ledger.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.xjrsoft.common.enums.DeleteMark;
import com.xjrsoft.common.enums.EnabledMark;
import com.xjrsoft.common.enums.MenuType;
import com.xjrsoft.common.enums.YesOrNoEnum;
import com.xjrsoft.common.exception.MyException;
import com.xjrsoft.module.form.entity.MenuConfig;
import com.xjrsoft.module.ledger.dto.AddLedgerConfigReleaseDto;
import com.xjrsoft.module.ledger.dto.LedgerConfigReleasePageDto;
import com.xjrsoft.module.ledger.dto.UpdateLedgerConfigReleaseDto;
import com.xjrsoft.module.ledger.entity.LedgerConfig;
import com.xjrsoft.module.ledger.entity.LedgerConfigRelease;
import com.xjrsoft.module.ledger.mapper.LedgerConfigMapper;
import com.xjrsoft.module.ledger.mapper.LedgerConfigReleaseMapper;
import com.xjrsoft.module.ledger.service.ILedgerConfigReleaseService;
import com.xjrsoft.module.ledger.vo.LedgerConfigPageVo;
import com.xjrsoft.module.ledger.vo.LedgerConfigReleaseInfoVo;
import com.xjrsoft.module.ledger.vo.LedgerConfigReleaseVo;
import com.xjrsoft.module.system.entity.Menu;
import com.xjrsoft.module.system.service.IMenuService;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
* @title: 台账发布表
* @Author dzx
* @Date: 2024-03-07
* @Version 1.0
*/
@Service
@AllArgsConstructor
public class LedgerConfigReleaseServiceImpl extends MPJBaseServiceImpl<LedgerConfigReleaseMapper, LedgerConfigRelease> implements ILedgerConfigReleaseService {

    private final LedgerConfigReleaseMapper ledgerConfigReleaseMapper;
    private final LedgerConfigMapper ledgerConfigMapper;
    private final IMenuService menuService;

    @Override
    public Page<LedgerConfigPageVo> getPage(Page<LedgerConfigPageVo> page, LedgerConfigReleasePageDto dto) {
        return ledgerConfigReleaseMapper.getPage(page, dto);
    }

    @Override
    public Boolean addRelease(AddLedgerConfigReleaseDto dto) {
        boolean exists = menuService.count(Wrappers.<Menu>lambdaQuery().eq(Menu::getCode, dto.getMenuConfig().getCode())) > 0;
        if (exists) {
            throw new MyException("菜单编码已存在");
        }

        long releaseId = IdUtil.getSnowflakeNextId();

        Long menuId = IdUtil.getSnowflakeNextId();
        insertMenuConfig(dto.getMenuConfig(), releaseId, menuId);

        LedgerConfig ledgerConfig = ledgerConfigMapper.selectById(dto.getLedgerConfigId());
        LedgerConfigRelease configRelease = new LedgerConfigRelease();
        configRelease.setId(releaseId);
        configRelease.setConfigJson(ledgerConfig.getConfigJson());
        configRelease.setMenuId(menuId);
        configRelease.setLedgerConfigId(dto.getLedgerConfigId());
        configRelease.setDeleteMark(DeleteMark.NODELETE.getCode());
        configRelease.setEnabledMark(EnabledMark.ENABLED.getCode());
        configRelease.setCreateUserId(StpUtil.getLoginIdAsLong());
        configRelease.setCreateDate(new Date());
        configRelease.setRemark(dto.getRemark());
        configRelease.setSortCode(dto.getMenuConfig().getSortCode());
        return ledgerConfigReleaseMapper.insert(configRelease) > 0;
    }

    @Override
    public Boolean updateRelease(UpdateLedgerConfigReleaseDto dto) {
        LedgerConfigRelease configRelease = ledgerConfigReleaseMapper.selectById(dto.getId());
        boolean exists = menuService.count(
                Wrappers.<Menu>lambdaQuery()
                        .eq(Menu::getCode, dto.getMenuConfig().getCode())
                        .ne(Menu::getId, configRelease.getMenuId())
        ) > 0;
        if (exists) {
            throw new MyException("菜单编码已存在");
        }
        Menu menu = menuService.getById(configRelease.getMenuId());

        insertMenuConfig(dto.getMenuConfig(), dto.getId(), menu.getId());
        LedgerConfig ledgerConfig = ledgerConfigMapper.selectById(dto.getLedgerConfigId());
        LedgerConfigRelease configReleaseUpd = new LedgerConfigRelease();
        configReleaseUpd.setId(dto.getId());
        configReleaseUpd.setConfigJson(ledgerConfig.getConfigJson());
        configReleaseUpd.setMenuId(menu.getId());
        configReleaseUpd.setLedgerConfigId(dto.getLedgerConfigId());
        configReleaseUpd.setDeleteMark(DeleteMark.NODELETE.getCode());
        configReleaseUpd.setEnabledMark(EnabledMark.ENABLED.getCode());
        configReleaseUpd.setCreateUserId(StpUtil.getLoginIdAsLong());
        configReleaseUpd.setCreateDate(new Date());
        configReleaseUpd.setModifyDate(new Date());
        configReleaseUpd.setModifyUserId(StpUtil.getLoginIdAsLong());
        configReleaseUpd.setRemark(dto.getRemark());
        configReleaseUpd.setSortCode(dto.getMenuConfig().getSortCode());
        return ledgerConfigReleaseMapper.updateById(configReleaseUpd) > 0;
    }

    @Override
    public Boolean deleteRelease(List<Long> ids) {
        for (Long id : ids) {
            LedgerConfigRelease release = ledgerConfigReleaseMapper.selectById(id);
            ledgerConfigReleaseMapper.deleteById(id);

            menuService.removeById(release.getMenuId());
        }
        return true;
    }

    @Override
    public LedgerConfigReleaseVo getRelease(Long id) {
        LedgerConfigRelease release = ledgerConfigReleaseMapper.selectById(id);
        if (release == null) {
            throw new MyException("未能找到发布信息");
        }
        Menu menu = menuService.getById(release.getMenuId());
        LedgerConfigReleaseVo vo = new LedgerConfigReleaseVo();
        vo.setId(id);
        vo.setLedgerConfigId(release.getLedgerConfigId());
        vo.setRemark(release.getRemark());
        vo.setSortCode(release.getSortCode());
        MenuConfig menuConfig = new MenuConfig();
        menuConfig.setIcon(menu.getIcon());
        menuConfig.setCode(menu.getCode());
        menuConfig.setName(menu.getTitle());
        menuConfig.setParentId(menu.getParentId().toString());
        menuConfig.setRemark(menu.getRemark());
        menuConfig.setSortCode(menu.getSortCode());
        vo.setMenuConfig(menuConfig);
        return vo;
    }

    @Override
    public LedgerConfigReleaseInfoVo getConfigInfo(Long id) {
        LedgerConfigRelease release = ledgerConfigReleaseMapper.selectById(id);
        Menu menu = menuService.getById(release.getMenuId());
        LedgerConfig ledgerConfig = ledgerConfigMapper.selectById(release.getLedgerConfigId());
        LedgerConfigReleaseInfoVo vo = new LedgerConfigReleaseInfoVo();
        vo.setConfigJson(release.getConfigJson());
        vo.setLedgerName(ledgerConfig.getName());
        vo.setMenuName(menu.getTitle());
        vo.setId(release.getId());
        return vo;
    }

    /**
     * 初始化菜单数据
     * @param menuConfig 菜单配置信息
     * @param releaseId 发布id
     * @param menuId 菜单id
     * @return 菜单id
     */
    @SneakyThrows
    private Long insertMenuConfig(MenuConfig menuConfig, Long releaseId, Long menuId) {
        Menu menu = BeanUtil.toBean(menuConfig, Menu.class);
        Menu parentMenu = menuService.getById(menuConfig.getParentId());
        menu.setId(menuId);
        menu.setName(menuConfig.getName() + RandomUtil.randomNumbers(4));
        menu.setTitle(menuConfig.getName());
        menu.setMenuType(MenuType.FUNCTION.getCode());
        menu.setDisplay(YesOrNoEnum.YES.getCode());
        menu.setAllowDelete(YesOrNoEnum.YES.getCode());
        menu.setSystemId(parentMenu.getSystemId());
        menu.setSystemType(parentMenu.getSystemType());
        menu.setAllowModify(YesOrNoEnum.YES.getCode());
        menu.setOutLink(YesOrNoEnum.NO.getCode());
        menu.setKeepAlive(YesOrNoEnum.NO.getCode());
        menu.setSortCode(menuConfig.getSortCode());
        menu.setParentId(StrUtil.isBlank(menuConfig.getParentId()) ? 0L : Long.parseLong(menuConfig.getParentId()));

        menu.setComponentType(YesOrNoEnum.YES.getCode());
        //固定路径  与前端必须匹配
        menu.setPath("/ledger/template/" + Convert.toStr(releaseId));
        menu.setComponent("/ledger/template/index");

        //新增菜单
        menuService.saveOrUpdate(menu);

        return menu.getId();
    }
}
