package com.yeejoin.amos.boot.module.jg.biz.reminder.core;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.module.jg.biz.reminder.biz.factory.GradeStrategyFactory;
import com.yeejoin.amos.boot.module.jg.biz.reminder.dto.MatchItemDto;
import com.yeejoin.amos.boot.module.jg.api.dto.ReminderItemDto;
import org.springframework.context.ApplicationContext;

import java.util.List;
import java.util.Map;

public abstract class DefaultReminder implements IReminderHandler {
    private final ApplicationContext applicationContext;

    public DefaultReminder(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    @Override
    public IPage<ReminderItemDto> remindersPage(Page<ReminderItemDto> page, String bizId, SourceType sourceType, Map<String, Object> formData) {
        IPage<ReminderItemDto> params = parse(page, bizId, sourceType, formData);
        ReminderFieldDiff reminderFieldDiff = applicationContext.getBean(ReminderFieldDiff.class);
        MatchItemDto matchItemDto = setMatchItemBySourceType(sourceType, bizId, formData);
        matchItemDto.setBizType(supportBizType());
        matchItemDto.setPage(page);
        return reminderFieldDiff.getReminderItemsPage(params, matchItemDto);
    }

    private MatchItemDto setMatchItemBySourceType(SourceType sourceType, String bizId, Map<String, Object> formData) {
        switch (sourceType) {
            case realTime:
                return setMatchItem(bizId);
            case json:
                return setMatchItem(bizId, formData);
            default:
                throw new RuntimeException("no support type for " + sourceType);
        }
    }

    @Override
    public Integer getReminderLevel(String bizId, String activeStrategy) {
        GradeStrategyFactory strategyFactory = applicationContext.getBean(GradeStrategyFactory.class);
        MatchItemDto matchItemDto = setMatchItem(bizId) == null ? MatchItemDto.builder().build() : setMatchItem(bizId);
        matchItemDto.setBizType(supportBizType());
        return strategyFactory.getStrategy(activeStrategy).calculateGrade(realtimeParse(bizId), matchItemDto);
    }

    private IPage<ReminderItemDto> parse(Page<ReminderItemDto> page, String bizId, SourceType sourceType, Map<String, Object> formData) {
        switch (sourceType) {
            case realTime:
                return realtimeParse(bizId, page);
            case json:
                return jsonParse(bizId, formData, page);
            default:
                throw new RuntimeException("no support type for " + sourceType);
        }
    }

    /**
     * 获取指定分页的设备、装置、单据下的设备、管道，详情使用
     *
     * @param bizId 唯一标识
     * @return 分页的设备/管道
     */
    protected abstract IPage<ReminderItemDto> realtimeParse(String bizId, Page<ReminderItemDto> page);


    /**
     * 获取指定设备、装置、单据下的设备、管道列表-评分使用;台套-台套设备；气瓶-气瓶；装置-装置
     *
     * @param bizId 唯一标识
     * @return 设备/管道列表
     */
    protected abstract List<ReminderItemDto> realtimeParse(String bizId);


    /**
     * 获取编辑或者新增的设备、装置、单据设备、管道列表
     *
     * @param bizId    唯一标识
     * @param formData 表单数据
     * @param page     分页信息
     * @return 解析后的分页数据
     */
    protected abstract IPage<ReminderItemDto> jsonParse(String bizId, Map<String, Object> formData, Page<ReminderItemDto> page);


    /**
     * 设置匹配项
     *
     * @param bizId    唯一标识
     * @param formData 表单数据
     * @return 构造好的匹配项
     */
    protected abstract MatchItemDto setMatchItem(String bizId, Map<String, Object> formData);


    /**
     * 设置匹配项
     *
     * @param bizId 唯一标识
     * @return 构造好的匹配项
     */
    protected abstract MatchItemDto setMatchItem(String bizId);

}
