package org.jeecg.modules.database.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.database.constant.ExperimentDocType;
import org.jeecg.modules.database.constant.ExperimentReportStatus;
import org.jeecg.modules.database.entity.*;
import org.jeecg.modules.database.service.*;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

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

/**
 * @Description: 试验报告
 * @Author: jeecg-boot
 * @Date: 2024-08-30
 * @Version: V1.0
 */
@Tag(name = "试验报告")
@RestController
@RequestMapping("/database/experimentReport")
@Slf4j
public class ExperimentReportController extends JeecgController<ExperimentReport, IExperimentReportService> {
    @Autowired
    private IExperimentReportService experimentReportService;
    @Autowired
    private IExperimentService       experimentService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private IExperimentDocService experimentDocService;

    /**
     * 分页列表查询
     *
     * @param experimentReport
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    //@AutoLog(value = "试验报告-分页列表查询")
    @Operation(summary = "试验报告-分页列表查询")
    @GetMapping(value = "/list")
    public Result<IPage<ExperimentReport>> queryPageList(ExperimentReport experimentReport,
                                                         @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                         @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                         HttpServletRequest req) {

        // 自定义duoXuan字段的查询规则为：LIKE_WITH_OR
        Date createTime = experimentReport.getCreateTime();
        //experimentReport.setCreateTime(null);
        //experimentReport.setStatus(ExperimentReportStatus.PASSED);
        QueryWrapper<ExperimentReport> queryWrapper = QueryGenerator.initQueryWrapper(experimentReport, req.getParameterMap());
        if (Objects.nonNull(createTime)) {
            queryWrapper.eq("DATE_FORMAT (create_time,'%Y-%m-%d')",
                    DateUtils.formatDate(createTime, "yyyy-MM-dd"));
        }
        Page<ExperimentReport> page = new Page<>(pageNo, pageSize);
        IPage<ExperimentReport> pageList = experimentReportService.join(page, experimentReport, queryWrapper);
        //pageList.getRecords().forEach(v -> {
        //    ExperimentDoc experimentDoc = experimentDocService.getByExperimentId(v.getExperimentId(), ExperimentDocType.sybg.getType());
        //    v.setFileUrl(Optional.ofNullable(experimentDoc).map(ExperimentDoc::getFilePath).orElse(null));
        //});
        return Result.OK(pageList);
    }

    /**
     * 添加
     *
     * @param experimentReport
     * @return
     */
    @AutoLog(value = "试验报告-添加")
    @Operation(summary = "试验报告-添加")
    @RequiresPermissions("database:experiment_report:add")
    @PostMapping(value = "/add")
    public Result<String> add(@RequestBody ExperimentReport experimentReport) {
        String experimentId = experimentReport.getExperimentId();
        if (StringUtils.isBlank(experimentId)) {
            return Result.error("试验数据不存在！");
        }
        Experiment experiment = experimentService.getById(experimentId);
        if (ObjUtil.isNull(experiment)) {
            return Result.error("试验数据不存在！");
        }
        //if (!StringUtils.equals(experiment.getStatus(), ExperimentStatus.COMPLETED)) {
        //    return Result.error("试验状态不正确,请先完成试验！");
        //}
        //ExperimentReport report = experimentReportService.getByExperimentId(experimentId);
        //if (ObjUtil.isNotNull(report)) {
        //    return Result.error("试验报告已存在！");
        //}
        String sampleInfo = experimentReport.getSampleInfo();
        String fileName = experiment.getName();
        if (StringUtils.isNotBlank(sampleInfo)) {
            List<Map> sampleList = JSON.parseArray(sampleInfo, Map.class);
            String modelBatch = sampleList.stream().map(v -> String.valueOf(v.getOrDefault("modelBatch", ""))).collect(
                    Collectors.joining("-"));
            String sampleName = sampleList.stream().map(v -> String.valueOf(v.getOrDefault("sampleName", ""))).collect(
                    Collectors.joining("-"));
            fileName = sampleName + "-" + modelBatch;
        }
        experimentReport.setReportName("试验报告-" + fileName);
        experimentReportService.save(experimentReport);
        return Result.OK("添加成功！");
    }

    /**
     * 编辑
     *
     * @param experimentReport
     * @return
     */
    @AutoLog(value = "试验报告-编辑")
    @Operation(summary = "试验报告-编辑")
    @RequiresPermissions("database:experiment_report:edit")
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> edit(@RequestBody ExperimentReport experimentReport, HttpServletRequest request) {
        //String username = JwtUtil.getUserNameByToken(request);
        ExperimentReport report = experimentReportService.getById(experimentReport.getId());
        //if (!StringUtils.equals(report.getCreateBy(), username)) {
        //    return Result.error("您无权进行编辑!");
        //}
        //待校对
        if (!(StringUtils.equals(report.getStatus(), "INIT") || StringUtils.equals(report.getStatus(), "REJECT"))) {
            return Result.error("该报告状态无法进行编辑!");
        }
        if (StringUtils.equals(report.getStatus(), "REJECT") && StringUtils.isNotBlank(experimentReport.getLastStatus())) {
            experimentReport.setStatus(experimentReport.getLastStatus());
        }
        experimentReportService.updateById(experimentReport);
        experimentDocService.generate(report.getExperimentId(), ExperimentDocType.sybg.getType());
        return Result.OK("编辑成功!");
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "试验报告-通过id删除")
    @Operation(summary = "试验报告-通过id删除")
    @RequiresPermissions("database:experiment_report:delete")
    @DeleteMapping(value = "/delete")
    public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
        experimentReportService.removeById(id);
        return Result.OK("删除成功!");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "试验报告-批量删除")
    @Operation(summary = "试验报告-批量删除")
    @RequiresPermissions("database:experiment_report:delete")
    @DeleteMapping(value = "/deleteBatch")
    public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        this.experimentReportService.removeByIds(Arrays.asList(ids.split(",")));
        return Result.OK("批量删除成功!");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    //@AutoLog(value = "试验报告-通过id查询")
    @Operation(summary = "试验报告-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<ExperimentReport> queryById(@RequestParam(name = "id", required = true) String id) {
        ExperimentReport experimentReport = experimentReportService.getById(id);
        if (experimentReport == null) {
            return Result.error("未找到对应数据");
        }

        //ExperimentDoc experimentDoc = experimentDocService.getByExperimentId(experimentReport.getExperimentId(),
        //        ExperimentDocType.sybg.getType());
        //experimentReport.setFileUrl(Optional.ofNullable(experimentDoc).map(ExperimentDoc::getFilePath).orElse(null));
        return Result.OK(experimentReport);
    }

    /**
     * 通过实验id查询
     *
     * @param experimentId
     * @return
     */
    //@AutoLog(value = "试验评定-通过id查询")
    @Operation(summary = "试验报告-通过实验ID查询")
    @GetMapping(value = "/queryByExperimentId")
    public Result<List<ExperimentReport>> getByExperimentId(
            @RequestParam(name = "experimentId", required = true) String experimentId) {
        List<ExperimentReport> experimentReport = experimentReportService.getByExperimentId(experimentId);
        if (CollUtil.isEmpty(experimentReport)) {
            return Result.ok();
        }
        //experimentReport.forEach(v -> {
        //    ExperimentDoc experimentDoc = experimentDocService.getByExperimentId(experimentId, ExperimentDocType.sybg.getType());
        //    v.setFileUrl(Optional.ofNullable(experimentDoc).map(ExperimentDoc::getFilePath).orElse(null));
        //});

        return Result.OK(experimentReport);
    }

    /**
     * 导出excel
     *
     * @param request
     * @param experimentReport
     */

    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, ExperimentReport experimentReport) {
        return super.exportXls(request, experimentReport, ExperimentReport.class, "试验报告");
    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @RequiresPermissions("database:experiment_report:add")
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, ExperimentReport.class);
    }

    /**
     * 审核
     *
     * @param experimentReport
     * @return
     */
    @AutoLog(value = "试验报告-审核")
    @Operation(summary = "试验报告-审核")
    @RequiresPermissions("database:experiment_report:audit")
    @RequestMapping(value = "/audit", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> audit(@RequestBody ExperimentReport experimentReport, HttpServletRequest request) {
        String username = JwtUtil.getUserNameByToken(request);
        if (oConvertUtils.isEmpty(username)) {
            return Result.error("用户未登录!");
        }
        // 根据用户名查询用户信息
        SysUser sysUser = sysUserService.getUserByName(username);
        ExperimentReport report = experimentReportService.getById(experimentReport.getId());
        //校对员
        String requestStatus = experimentReport.getStatus();
        //待校对
        if (StringUtils.equals(report.getStatus(), ExperimentReportStatus.INIT)) {
            if (!StringUtils.equals(report.getProofreader(), sysUser.getId())) {
                return Result.error("您无权进行校对!");
            }
            if (!StringUtils.equals(requestStatus, ExperimentReportStatus.PROOFREAD_PASS)) {
                report.setStatus(ExperimentReportStatus.REJECT);
                report.setLastStatus(ExperimentReportStatus.INIT);
            }
            report.setProofreaderMemo(experimentReport.getMemo());
            report.setProofreaderTime(DateUtils.formatDate(new Date(), "yyyy-MM-dd HH:mm"));
            report.setStatus(requestStatus);
        }
        //待审核
        else if (StringUtils.equals(report.getStatus(), ExperimentReportStatus.PROOFREAD_PASS)) {
            if (!StringUtils.equals(report.getAuditor(), sysUser.getId())) {
                return Result.error("您无权进行审核!");
            }
            if (!StringUtils.equals(requestStatus, ExperimentReportStatus.AUDIT_PASS)) {
                report.setStatus(ExperimentReportStatus.REJECT);
                report.setLastStatus(ExperimentReportStatus.PROOFREAD_PASS);

            }
            report.setAuditorMemo(experimentReport.getMemo());
            report.setAuditorTime(DateUtils.formatDate(new Date(), "yyyy-MM-dd HH:mm"));
            report.setStatus(requestStatus);
        }

        //待批准
        else if (StringUtils.equals(report.getStatus(), ExperimentReportStatus.AUDIT_PASS)) {
            if (!StringUtils.equals(report.getConfirmer(), sysUser.getId())) {
                return Result.error("您无权进行批准!");
            }
            if (!StringUtils.equals(requestStatus, ExperimentReportStatus.PASSED)) {
                report.setStatus(ExperimentReportStatus.REJECT);
                report.setLastStatus(ExperimentReportStatus.AUDIT_PASS);
            }
            report.setConfirmerMemo(experimentReport.getMemo());
            report.setConfirmerTime(DateUtils.formatDate(new Date(), "yyyy-MM-dd HH:mm"));
            report.setStatus(requestStatus);
        } else {
            return Result.error("实验报告状态异常!");
        }
        if (StringUtils.equals(report.getStatus(), ExperimentReportStatus.PASSED)) {
            ExperimentDoc generate = experimentDocService.generate(report.getExperimentId(), ExperimentDocType.sybg.getType());
            String filePath = generate.getFilePath();
            report.setFileUrl(filePath);
        }
        experimentReportService.updateById(report);

        return Result.OK("审核成功!");
    }

    @AutoLog(value = "试验报告-撤回")
    @Operation(summary = "试验报告-撤回")
    @RequestMapping(value = "/cancel", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> cancel(@RequestBody ExperimentReport experimentReport, HttpServletRequest request) {
        String username = JwtUtil.getUserNameByToken(request);
        if (oConvertUtils.isEmpty(username)) {
            return Result.error("用户未登录!");
        }
        String reportId = experimentReport.getId();
        ExperimentReport report = experimentReportService.getById(reportId);
        Experiment experiment = experimentService.getById(report.getExperimentId());
        if (!(StringUtils.equals(experimentReport.getCreateBy(), username) || StringUtils.equals(experiment.getCreateBy(), username))) {
            return Result.error("您无权进行撤回!");
        }
        report.setStatus(ExperimentReportStatus.INIT);
        experimentReportService.updateById(report);
        return Result.OK("撤回成功!");
    }
}
