package com.qmth.distributed.print.business.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qmth.distributed.print.business.entity.BasicCardRule;
import com.qmth.distributed.print.business.entity.BasicExamRule;
import com.qmth.distributed.print.business.entity.ExamCard;
import com.qmth.distributed.print.business.entity.ExamTask;
import com.qmth.distributed.print.business.enums.CardRequiredFieldsEnum;
import com.qmth.distributed.print.business.mapper.BasicCardRuleMapper;
import com.qmth.distributed.print.business.service.*;
import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.BasicPrintConfig;
import com.qmth.teachcloud.common.entity.SysUser;
import com.qmth.teachcloud.common.enums.EnumResult;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.service.BasicRoleDataPermissionService;
import com.qmth.teachcloud.common.util.ServletUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * <p>
 * 题卡规则 服务实现类
 * </p>
 *
 * @author xf
 * @since 2021-03-23
 */
@Service
public class BasicCardRuleServiceImpl extends ServiceImpl<BasicCardRuleMapper, BasicCardRule> implements BasicCardRuleService {

    @Resource
    BasicPrintConfigService basicPrintConfigService;

    @Resource
    ExamCardService examCardService;

    @Resource
    ExamTaskService examTaskService;

    @Resource
    BasicRoleDataPermissionService basicRoleDataPermissionService;

    @Resource
    BasicExamRuleService basicExamRuleService;

    @Override
    public IPage<BasicCardRule> list(Boolean enable, String name, Long createStartTime, Long createEndTime, Integer pageNumber, Integer pageSize) {
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(schoolId, requestUser.getId(), ServletUtil.getRequest().getServletPath());
        IPage<BasicCardRule> cardRuleDtoIPage = this.baseMapper.listPage(new Page<>(pageNumber, pageSize), schoolId, enable, SystemConstant.translateSpecificSign(name), createStartTime, createEndTime, dpr);

        BasicExamRule basicExamRule = basicExamRuleService.getBySchoolId();
        List<JSONObject> examRuleRequiredFieldList = JSONObject.parseArray(basicExamRule.getRequiredFields(), JSONObject.class);
        List<JSONObject> examRuleExtendFieldList = JSONObject.parseArray(basicExamRule.getExtendFields(), JSONObject.class);

        List<JSONObject> allExamRuleFieldList = new ArrayList<>();
        allExamRuleFieldList.addAll(examRuleRequiredFieldList);
        if (!CollectionUtils.isEmpty(examRuleExtendFieldList)) {
            for (JSONObject jsonObject : examRuleExtendFieldList) {
                if (jsonObject.getBoolean("enable")) {
                    allExamRuleFieldList.add(jsonObject);
                }
            }
        }
        List<EnumResult> enumResults = CardRequiredFieldsEnum.listTypes();
        List<JSONObject> removeJsonObject = new ArrayList<>();
        for (int i = 0; i < allExamRuleFieldList.size(); i++) {
            JSONObject jsonObject = allExamRuleFieldList.get(i);
            Optional<EnumResult> resultOptional = enumResults.stream().filter(t -> t.getCode().equals(jsonObject.getString("code"))).findFirst();
            if (resultOptional.isPresent()) {
                removeJsonObject.add(jsonObject);
            }
        }

        // 删除必填字段重复的
        if (!CollectionUtils.isEmpty(removeJsonObject)) {
            allExamRuleFieldList.removeAll(removeJsonObject);
        }

        for (BasicCardRule record : cardRuleDtoIPage.getRecords()) {
            List<JSONObject> cardRuleExtendFieldList = JSONObject.parseArray(record.getExtendFields(), JSONObject.class);
            for (JSONObject jsonObject : allExamRuleFieldList) {
                Optional<JSONObject> objectOptional = cardRuleExtendFieldList.stream().filter(m -> m.getString("code").equals(jsonObject.getString("code"))).findFirst();
                if (objectOptional.isPresent()) {
                    jsonObject.put("enable", objectOptional.get().getBoolean("enable"));
                } else {
                    jsonObject.put("enable", false);
                }
            }

            record.setExtendFields(JSONObject.toJSONString(allExamRuleFieldList));
        }
        return cardRuleDtoIPage;
    }

    @Override
    public List<BasicCardRule> list(String param) {
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        return this.baseMapper.list(schoolId, param);
    }

    @Override
    public boolean delete(BasicCardRule cardRule) {
        // 考试绑定的题卡规则数据
        QueryWrapper<BasicPrintConfig> basicPrintConfigQueryWrapper = new QueryWrapper<>();
        basicPrintConfigQueryWrapper.lambda().eq(BasicPrintConfig::getCardRuleId, cardRule.getId());
        int basicPrintConfigCount = basicPrintConfigService.count(basicPrintConfigQueryWrapper);
        if (basicPrintConfigCount > 0) {
            throw ExceptionResultEnum.ERROR.exception("题卡规则已绑定考试，不能删除");
        }

        // 题卡绑定的题卡规则数据
        QueryWrapper<ExamCard> examCardQueryWrapper = new QueryWrapper<>();
        examCardQueryWrapper.lambda().eq(ExamCard::getCardRuleId, cardRule.getId());
        int examCardCount = examCardService.count(examCardQueryWrapper);
        if (examCardCount > 0) {
            throw ExceptionResultEnum.ERROR.exception("题卡规则已绑定题卡，不能删除");
        }

        // 命题任务绑定的题卡规则数据
        QueryWrapper<ExamTask> examTaskQueryWrapper = new QueryWrapper<>();
        examTaskQueryWrapper.lambda().eq(ExamTask::getCardRuleId, cardRule.getId());
        int examTaskCount = examTaskService.count(examTaskQueryWrapper);
        if (examTaskCount > 0) {
            throw ExceptionResultEnum.ERROR.exception("题卡规则已绑定命题任务，不能删除");
        }

        return this.removeById(cardRule.getId());
    }

    @Transactional
    @Override
    public boolean saveCardRule(BasicCardRule cardRule) {
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();

        QueryWrapper<BasicCardRule> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(BasicCardRule::getSchoolId, schoolId)
                .eq(BasicCardRule::getName, cardRule.getName());
        BasicCardRule basicCardRule = this.getOne(queryWrapper);
        // 新增
        if (Objects.isNull(cardRule.getId())) {
            if (basicCardRule != null) {
                throw ExceptionResultEnum.ERROR.exception("题卡规则名称已使用");
            }
            cardRule.setId(SystemConstant.getDbUuid());
            cardRule.setSchoolId(schoolId);
            cardRule.setOrgId(sysUser.getOrgId());
            cardRule.setCreateId(sysUser.getId());
            cardRule.setCreateTime(System.currentTimeMillis());
        }
        // 修改
        else {
            if (basicCardRule != null && basicCardRule.getId().longValue() != cardRule.getId().longValue()) {
                throw ExceptionResultEnum.ERROR.exception("题卡规则名称已使用");
            }
            cardRule.setOrgId(sysUser.getOrgId());
            cardRule.setUpdateId(sysUser.getId());
            cardRule.setUpdateTime(System.currentTimeMillis());
        }
        return this.saveOrUpdate(cardRule);
    }

    @Override
    public boolean enable(Long id, Boolean enable) {
        UpdateWrapper<BasicCardRule> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(BasicCardRule::getEnable, enable)
                .eq(BasicCardRule::getId, id);
        return this.update(updateWrapper);
    }
}
