package cn.nianxx.thhotel.platform.navigation.repository;

import cn.nianxx.thhotel.platform.common.dto.PlatformPageSnapshot;
import cn.nianxx.thhotel.platform.navigation.common.enums.PlatformMenuStatus;
import cn.nianxx.thhotel.platform.navigation.domain.PlatformMenuEntity;
import cn.nianxx.thhotel.platform.navigation.mapper.PlatformMenuMapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.List;
import java.util.Optional;
import org.springframework.stereotype.Repository;

/**
 * 基于 MyBatis-Plus 的平台菜单仓储实现。
 */
@Repository
public class MybatisPlatformNavigationRepository implements PlatformNavigationRepository {

    private final PlatformMenuMapper menuMapper;

    public MybatisPlatformNavigationRepository(PlatformMenuMapper menuMapper) {
        this.menuMapper = menuMapper;
    }

    @Override
    public Optional<PlatformMenuEntity> findMenuByCode(String menuCode) {
        return Optional.ofNullable(menuMapper.selectOne(Wrappers.<PlatformMenuEntity>lambdaQuery()
                .eq(PlatformMenuEntity::getMenuCode, menuCode)
                .last("LIMIT 1")));
    }

    @Override
    public Optional<PlatformMenuEntity> findMenuById(Long menuId) {
        if (menuId == null) {
            return Optional.empty();
        }
        return Optional.ofNullable(menuMapper.selectById(menuId));
    }

    @Override
    public List<PlatformMenuEntity> listAllMenus() {
        return menuMapper.selectList(Wrappers.<PlatformMenuEntity>lambdaQuery()
                .orderByAsc(PlatformMenuEntity::getSortOrder)
                .orderByAsc(PlatformMenuEntity::getMenuCode));
    }

    @Override
    public PlatformPageSnapshot<PlatformMenuEntity> queryMenus(String keyword, String menuStatus, int pageNum, int pageSize) {
        Page<PlatformMenuEntity> page = menuMapper.selectPage(Page.of(pageNum, pageSize),
                Wrappers.<PlatformMenuEntity>lambdaQuery()
                        .eq(menuStatus != null && !menuStatus.isBlank(), PlatformMenuEntity::getMenuStatus, menuStatus)
                        .and(keyword != null && !keyword.isBlank(), wrapper -> wrapper
                                .like(PlatformMenuEntity::getMenuCode, keyword)
                                .or()
                                .like(PlatformMenuEntity::getMenuName, keyword)
                                .or()
                                .like(PlatformMenuEntity::getRoutePath, keyword))
                        .orderByAsc(PlatformMenuEntity::getSortOrder)
                        .orderByAsc(PlatformMenuEntity::getMenuCode));
        return new PlatformPageSnapshot<>(page.getRecords(), page.getTotal(), pageNum, pageSize);
    }

    @Override
    public void insertMenu(PlatformMenuEntity menu) {
        menuMapper.insert(menu);
    }

    @Override
    public void updateMenu(PlatformMenuEntity menu) {
        menuMapper.updateById(menu);
    }

    @Override
    public List<PlatformMenuEntity> listVisibleMenus(List<String> permissionCodes) {
        if (permissionCodes == null || permissionCodes.isEmpty()) {
            return menuMapper.selectList(Wrappers.<PlatformMenuEntity>lambdaQuery()
                    .eq(PlatformMenuEntity::getMenuStatus, PlatformMenuStatus.ACTIVE.name())
                    .eq(PlatformMenuEntity::getVisible, true)
                    .isNull(PlatformMenuEntity::getPermissionCode)
                    .orderByAsc(PlatformMenuEntity::getSortOrder)
                    .orderByAsc(PlatformMenuEntity::getMenuCode));
        }
        return menuMapper.selectList(Wrappers.<PlatformMenuEntity>lambdaQuery()
                .eq(PlatformMenuEntity::getMenuStatus, PlatformMenuStatus.ACTIVE.name())
                .eq(PlatformMenuEntity::getVisible, true)
                .and(wrapper -> wrapper.isNull(PlatformMenuEntity::getPermissionCode)
                        .or()
                        .in(!permissionCodes.isEmpty(), PlatformMenuEntity::getPermissionCode, permissionCodes))
                .orderByAsc(PlatformMenuEntity::getSortOrder)
                .orderByAsc(PlatformMenuEntity::getMenuCode));
    }
}
