package com.ningdatech.kqapi.admin.manage;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ningdatech.basic.model.IdVo;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.kqapi.admin.model.entity.Window;
import com.ningdatech.kqapi.admin.model.entity.Zone;
import com.ningdatech.kqapi.admin.model.req.ListWindowReq;
import com.ningdatech.kqapi.admin.model.req.WindowSaveReq;
import com.ningdatech.kqapi.admin.model.vo.WindowDetailVO;
import com.ningdatech.kqapi.admin.service.IWindowService;
import com.ningdatech.kqapi.common.constant.BizConst;
import com.ningdatech.kqapi.common.exception.BizException;
import com.ningdatech.kqapi.zzsfw.service.IKqZzsfwMenuService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * WindowManage
 * </p>
 *
 * @author WendyYang
 * @since 12:17 2024/4/20
 */
@Component
@RequiredArgsConstructor
public class WindowManage {

    private final IWindowService windowService;
    private final IKqZzsfwMenuService zzsfwMenuService;

    public synchronized void windowSaveOrUpdate(WindowSaveReq req) {
        Wrapper<Window> nameCheck = Wrappers.lambdaQuery(Window.class)
                .eq(Window::getZoneId, req.getZoneId())
                .eq(Window::getWindowName, req.getWindowName())
                .ne(req.getId() != null, Window::getId, req.getId())
                .last(BizConst.LIMIT_1);
        if (windowService.count(nameCheck) > 0) {
            throw BizException.wrap("您新增的【%s】专区下的【%s】窗口已存在，无须重复添加",
                    req.getZoneName(), req.getWindowName());
        }
        Window win = BeanUtil.copyProperties(req, Window.class);
        windowService.saveOrUpdate(win);
    }

    public void delete(IdVo<Integer> id) {
        windowService.removeById(id.getId());
    }

    public PageVo<WindowDetailVO> pageWindow(ListWindowReq req) {
        Wrapper<Window> query = buildWindowQuery(req);
        Page<Window> page = windowService.page(req.page(), query);
        if (page.getTotal() == 0) {
            return PageVo.empty();
        }
        List<Window> records = page.getRecords();
        List<Integer> windowIds = CollUtils.fieldList(records, Window::getId);
        Map<Integer, Integer> matterCountMap = zzsfwMenuService.matterCountByWindowIds(windowIds);
        List<WindowDetailVO> data = records.stream().map(w -> {
            WindowDetailVO window = BeanUtil.copyProperties(w, WindowDetailVO.class);
            window.setItemCount(matterCountMap.getOrDefault(w.getId(), 0));
            return window;
        }).collect(Collectors.toList());
        return PageVo.of(data, page.getTotal());
    }

    public List<WindowDetailVO> windowOption(ListWindowReq req) {
        Wrapper<Window> query = buildWindowQuery(req);
        Page<Window> page = windowService.page(req.page(), query);
        if (page.getTotal() == 0) {
            return Collections.emptyList();
        }
        return page.getRecords().stream().map(w -> WindowDetailVO.builder()
                .windowName(w.getWindowName())
                .id(w.getId())
                .build()).collect(Collectors.toList());
    }

    private static Wrapper<Window> buildWindowQuery(ListWindowReq req) {
        return Wrappers.lambdaQuery(Window.class)
                .like(StrUtil.isNotBlank(req.getWindowName()), Window::getWindowName, req.getWindowName())
                .eq(req.getZoneId() != null, Window::getZoneId, req.getZoneId())
                .orderByDesc(Window::getUpdateOn);
    }

}
