package com.seer.teach.admin.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.seer.teach.admin.convert.GradeSubjectConvert;
import com.seer.teach.admin.request.GradeSubjectReq;
import com.seer.teach.admin.response.GradeSubjectResp;
import com.seer.teach.common.enums.ResultCodeEnum;
import com.seer.teach.common.utils.AssertUtils;
import com.seer.teach.teacher.module.entity.GradeSubjectEntity;
import com.seer.teach.teacher.module.entity.SubjectsEntity;
import com.seer.teach.teacher.service.GradeSubjectService;
import com.seer.teach.teacher.service.SubjectsService;
import com.seer.teach.user.api.GradeServiceApi;
import com.seer.teach.user.api.dto.GradeDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class GradeSubjectAdminService {

    private final SubjectsService subjectsService;

    private final GradeSubjectService gradeSubjectService;

    private final GradeServiceApi gradeServiceApi;


    /**
     * 获取年级-科目
     */
    public List<GradeSubjectResp> listSubjectsGrade() {
        List<GradeSubjectEntity> result = gradeSubjectService.list(new LambdaQueryWrapper<GradeSubjectEntity>()
                .orderByAsc(GradeSubjectEntity::getGradeId)
                .orderByAsc(GradeSubjectEntity::getSort)
                .orderByAsc(GradeSubjectEntity::getId));
        if (result.isEmpty()) {
            return Collections.emptyList();
        }
        Set<Integer> subjectIds = result.stream()
                .map(GradeSubjectEntity::getSubjectId)
                .collect(Collectors.toSet());
        Map<Integer, String> subjectNameMap = subjectsService.list(new LambdaQueryWrapper<SubjectsEntity>()
                        .in(SubjectsEntity::getId, subjectIds)
                        .select(SubjectsEntity::getId, SubjectsEntity::getSubject)).stream()
                .collect(Collectors.toMap(s -> s.getId().intValue(), SubjectsEntity::getSubject));
        Set<Integer> gradeIds = result.stream().map(GradeSubjectEntity::getGradeId).collect(Collectors.toSet());
        Map<Integer, GradeDTO> gradeNameMap = Optional.ofNullable(
                        gradeServiceApi.findGradesByIds(new ArrayList<>(gradeIds))
                ).orElse(Collections.emptyList())
                .stream().collect(Collectors.toMap(GradeDTO::getId, Function.identity()));
        LinkedHashMap<Integer, GradeSubjectResp> map = new LinkedHashMap<>();
        for (GradeSubjectEntity r : result) {
            String subjectName = subjectNameMap.get(r.getSubjectId());
            if (subjectName == null || subjectName.isEmpty()) {
                continue;
            }
            GradeSubjectResp group = map.computeIfAbsent(r.getGradeId(), gid -> {
                GradeDTO gradeInfo = gradeNameMap.get(gid);
                GradeSubjectResp g = new GradeSubjectResp();
                g.setId(r.getId());
                g.setGradeId(gid);
                g.setStatus(gradeInfo != null ? gradeInfo.getStatus() : 0);
                g.setGrade(gradeInfo != null ? gradeInfo.getGrade() : String.valueOf(gid));
                g.setChildren(new ArrayList<>());
                return g;
            });
            GradeSubjectResp.SubjectItem item = new GradeSubjectResp.SubjectItem();
            item.setSubject(subjectName);
            item.setRelationId(r.getId());
            item.setSubjectId(r.getSubjectId());
            item.setStatus(r.getStatus());
            item.setSort(r.getSort());
            group.getChildren().add(item);
        }
        return new ArrayList<>(map.values());
    }

    /**
     * 新增科目
     */
    public void addGradeSubject(GradeSubjectReq params) {
        GradeSubjectEntity one = gradeSubjectService.getOne(new LambdaQueryWrapper<GradeSubjectEntity>()
                .eq(GradeSubjectEntity::getGradeId, params.getGradeId())
                .eq(GradeSubjectEntity::getSubjectId, params.getSubjectId()));
        AssertUtils.isNull(one, ResultCodeEnum.THE_SUBJECT_IS_EXISTS);
        SubjectsEntity byId = subjectsService.getById(params.getSubjectId());
        AssertUtils.notNull(byId, ResultCodeEnum.THE_SUBJECT_IS_NOT_LISTED);
        GradeSubjectEntity gradeSubjectEntity = GradeSubjectConvert.INSTANCE.convertOne(params);
        gradeSubjectEntity.setCreateTime(LocalDateTime.now());
        gradeSubjectService.save(gradeSubjectEntity);
        log.info("科目添加成功{}", gradeSubjectEntity);
    }

    /**
     * 修改科目状态
     */
    public void updateGradeSubject(GradeSubjectReq params) {
        GradeSubjectEntity entity = gradeSubjectService.getById(params.getRelationId());
        AssertUtils.notNull(entity, ResultCodeEnum.SUBJECT_IS_NOT_EXIST);
        entity.setStatus(params.getStatus());
        entity.setSort(params.getSort());
        gradeSubjectService.updateById(entity);
        log.info("年级-科目更新成功{}", entity);
    }

    /**
     * 删除科目
     */
    public void deleteGradeSubject(Integer relationId) {
        GradeSubjectEntity one = gradeSubjectService.getById(relationId);
        AssertUtils.notNull(one, ResultCodeEnum.THE_SUBJECT_IS_NOT_EXISTS);
        AssertUtils.isTrue(one.getStatus()==0,ResultCodeEnum.SUBJECT_HAVE_BEEN_LISTED_NOT_ALLOWED_TO_BE_DELETED);
        boolean result = gradeSubjectService.removeById(relationId);
        log.info("删除科目{}成功:{}", relationId, result);
    }
}
