package org.dromara.ygpassport.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.toolkit.MPJWrappers;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.excel.core.ExcelResult;
import org.dromara.ygpassport.domain.CombatProject;
import org.dromara.ygpassport.domain.StudentList;
import org.dromara.ygpassport.domain.Tutor;
import org.dromara.ygpassport.domain.dto.ProjectDto;
import org.dromara.ygpassport.domain.dto.StuCombatProjectDto;
import org.dromara.ygpassport.domain.dto.StuTutorDto;
import org.dromara.ygpassport.listener.CombatProjectImportListener;
import org.dromara.ygpassport.service.ITutorService;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.ygpassport.domain.vo.CombatProjectVo;
import org.dromara.ygpassport.domain.bo.CombatProjectBo;
import org.dromara.ygpassport.service.ICombatProjectService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;

/**
 * 实战项目经历
 *
 * @author Lion Li
 * @date 2024-01-11
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/ygpassport/combatProject")
public class CombatProjectController extends BaseController {

    private final ICombatProjectService combatProjectService;

    private final ITutorService tutorService;

    /**
     * 查询实战项目经历列表 old
     */
    @SaCheckPermission("ygpassport:combatProject:list")
    @GetMapping("/list")
    public TableDataInfo<CombatProjectVo> list(CombatProjectBo bo, PageQuery pageQuery) {
        return combatProjectService.queryPageList(bo, pageQuery);
    }

    /**
     * 查询实战项目经历列表 new
     */
    @SaCheckPermission("ygpassport:combatProject:list")
    @PostMapping("/listNew")
    public IPage<ProjectDto> listNew(@RequestBody JSONObject jsonObject) {
        JSONObject query = jsonObject.getJSONObject("query");
        String projectName = query.getStr("projectName");
        String tutorName = query.getStr("tutorName");
        String stuName = query.getStr("stuName");

        List<StuCombatProjectDto> stuCombatProjectDtoList = combatProjectService.selectJoinList(StuCombatProjectDto.class,
            MPJWrappers.<CombatProject>lambdaJoin()
                .selectAll(CombatProject.class)
                .like(StringUtils.isNotBlank(projectName),CombatProject::getProjectName, projectName)
                .like(StringUtils.isNotBlank(tutorName),CombatProject::getTutorName, tutorName)
                .select(StudentList::getStuName)
                .like(StringUtils.isNotBlank(stuName),StudentList::getStuName, stuName)
                .leftJoin(StudentList.class, StudentList::getStuNo, CombatProject::getStuNo));

        List<StuTutorDto> stuTutorList = tutorService.selectJoinList(StuTutorDto.class,
            MPJWrappers.<Tutor>lambdaJoin()
                .selectAll(Tutor.class)
                .like(StringUtils.isNotBlank(projectName),Tutor::getProjectName, projectName)
                .like(StringUtils.isNotBlank(tutorName),Tutor::getTutorName, tutorName)
                .select(StudentList::getStuName)
                .like(StringUtils.isNotBlank(stuName),StudentList::getStuName, stuName)
                .leftJoin(StudentList.class, StudentList::getStuNo, Tutor::getStuNo));

        List<ProjectDto> projectDtoList = new ArrayList<>();
        HashMap<String, List<ProjectDto>> hashMap = new HashMap<>();
        for (StuCombatProjectDto project : stuCombatProjectDtoList) {
            ProjectDto projectDto = new ProjectDto(project);
            projectDtoList.add(projectDto);
            List<ProjectDto> list = new ArrayList<>();
            if (hashMap.containsKey(projectDto.getProjectName())) {
                list = hashMap.get(projectDto.getProjectName());
            }
            list.add(projectDto);
            hashMap.put(projectDto.getProjectName(), list);
        }
        for (StuTutorDto project : stuTutorList) {
            ProjectDto projectDto = new ProjectDto(project);
            if (!hashMap.containsKey(projectDto.getProjectName())) {
                projectDtoList.add(projectDto);
            } else {
                List<ProjectDto> list = hashMap.get(project.getProjectName());
                int flag = 0;
                for (ProjectDto p : list) {
                    if (
                        p.getSemester().equals(projectDto.getSemester())
                            && p.getStuName().equals(projectDto.getStuName())
                            && p.getTutorName().equals(projectDto.getTutorName())) {
                        flag = 1;
                    }
                }
                if (flag == 0) {
                    projectDtoList.add(projectDto);
                    list.add(projectDto);
                    hashMap.put(projectDto.getProjectName(), list);
                }
            }
        }

        IPage<ProjectDto> projectDtoIPage = new Page<>(query.getInt("pageNum"), query.getInt("pageSize"));
        projectDtoIPage.setRecords(projectDtoList);

        return projectDtoIPage;
    }

    /**
     * 导出实战项目经历列表
     */
    @SaCheckPermission("ygpassport:combatProject:export")
    @Log(title = "实战项目经历", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(CombatProjectBo bo, HttpServletResponse response) {
        List<CombatProjectVo> list = combatProjectService.queryList(bo);
        ExcelUtil.exportExcel(list, "实战项目经历", CombatProjectVo.class, response);
    }

    /**
     * 导入实战项目经历数据
     *
     * @param file          导入文件
     * @param updateSupport 是否更新已存在数据
     */
    @Log(title = "实战项目经历信息", businessType = BusinessType.IMPORT)
    @SaCheckPermission("ygpassport:combatProject:import")
    @PostMapping(value = "/importCombatProjectData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public R<Void> importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception {
        CombatProjectImportListener listener = new CombatProjectImportListener(updateSupport);

        ExcelResult<CombatProjectVo> result = ExcelUtil.importExcel(file.getInputStream(), CombatProjectVo.class, listener);
        return R.ok(result.getAnalysis());
    }

    /**
     * 获取导入模板
     */
    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response) {
        ExcelUtil.exportExcel(new ArrayList<>(), "实战项目经历信息", CombatProjectVo.class, response);
    }


    /**
     * 获取实战项目经历详细信息
     *
     * @param id 主键
     */
    @SaCheckPermission("ygpassport:combatProject:query")
    @GetMapping("/{id}")
    public R<CombatProjectVo> getInfo(@NotNull(message = "主键不能为空")
                                      @PathVariable Long id) {
        return R.ok(combatProjectService.queryById(id));
    }

    /**
     * 新增实战项目经历
     */
    @SaCheckPermission("ygpassport:combatProject:add")
    @Log(title = "实战项目经历", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody CombatProjectBo bo) {
        return toAjax(combatProjectService.insertByBo(bo));
    }

    /**
     * 修改实战项目经历
     */
    @SaCheckPermission("ygpassport:combatProject:edit")
    @Log(title = "实战项目经历", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody CombatProjectBo bo) {
        return toAjax(combatProjectService.updateByBo(bo));
    }

    /**
     * 删除实战项目经历
     *
     * @param ids 主键串
     */
    @SaCheckPermission("ygpassport:combatProject:remove")
    @Log(title = "实战项目经历", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] ids) {
        return toAjax(combatProjectService.deleteWithValidByIds(List.of(ids), true));
    }
}
