package digital.laboratory.platform.inspection.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.amazonaws.services.s3.model.AmazonS3Exception;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.annotation.JsonFormat;
import digital.laboratory.platform.common.core.util.R;
import digital.laboratory.platform.common.mybatis.security.service.DLPUser;
import digital.laboratory.platform.common.oss.service.OssFile;
import digital.laboratory.platform.inspection.dto.DeleteTestAtlasDTO;
import digital.laboratory.platform.inspection.dto.TestRecordDto;
import digital.laboratory.platform.inspection.service.InspectRecordService;
import digital.laboratory.platform.inspection.service.TestAtlasService;
import digital.laboratory.platform.inspetion.api.entity.TestRecord;
import digital.laboratory.platform.inspection.service.TestRecordService;
import digital.laboratory.platform.inspection.vo.ProcedureVo;
import digital.laboratory.platform.inspetion.api.vo.TestRecordVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.activation.MimetypesFileTypeMap;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.security.Principal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * @author xy
 * @version 1.0
 * @title TestRecordController
 * @description 检验记录控制器
 * @create 2023/12/19 11:50
 */
@RestController
@RequestMapping("/testRecord")
@Api(tags = "06-检验记录管理", description = "检验记录管理")
public class TestRecordController {

    @Resource
    private TestRecordService testRecordService;

    @Resource
    private InspectRecordService inspectRecordService;

    @Resource
    private TestAtlasService testAtlasService;

    @Resource
    private OssFile ossFile;

    /**
     * 创建实验记录
     */
    @PostMapping("/createTestInstance")
    @ApiOperation(value = "创建实验", notes = "创建实验")
    public R createTestInstance(@RequestBody TestRecordDto testRecord, HttpServletRequest httpServletRequest) throws Exception {
        Principal principal = httpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();
        TestRecord testInstance = testRecordService.createTestInstance(testRecord, dlpUser);
        return testInstance != null ? R.ok(testInstance, "创建成功!") : R.failed("创建失败!");
    }

    @PutMapping("/updateTestInstance")
    @ApiOperation(value = "修改实验", notes = "修改实验")
    public R updateTestInstance(@RequestBody TestRecord testRecord) {
        TestRecord testInstance = testRecordService.updateTestInstance(testRecord);
        return testInstance != null ? R.ok(testInstance, "修改成功!") : R.failed("修改失败!");
    }

    @GetMapping("/getById")
    @ApiOperation(value = "通过实验Id查询实验信息", notes = "通过实验Id查询实验信息")
    public R<TestRecordVo> getTestRecord(String id, HttpServletRequest httpServletRequest) {
        Principal principal = httpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();
        return R.ok(testRecordService.getTestRecord(id, dlpUser), "查询成功!");
    }

    @GetMapping("/getByIdTest")
    @ApiOperation(value = "通过实验Id查询实验信息", notes = "通过实验Id查询实验信息")
    public R getByIdTest(String id, HttpServletRequest httpServletRequest) {
        Principal principal = httpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();
        return R.ok(testRecordService.getById(id), "查询成功!");
    }

    @GetMapping("/getPage")
    @ApiOperation(value = "分页查询实验信息", notes = "分页查询实验信息")
    public R<IPage<TestRecordVo>> getTestRecordPageList(Page page, HttpServletRequest httpServletRequest,
                                                        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") LocalDateTime startTime,
                                                        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") LocalDateTime endTime,
                                                        String businessType) {
        Principal principal = httpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();
        return R.ok(testRecordService.getTestRecordPageList(page, dlpUser, startTime, endTime, businessType), "查询成功!");
    }

    @GetMapping("/getList")
    @ApiOperation(value = "列表查询实验信息", notes = "列表查询实验信息")
    public R<List<TestRecordVo>> getTestRecordList(HttpServletRequest httpServletRequest) {
        Principal principal = httpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();
        return R.ok(testRecordService.getTestRecordList(dlpUser), "查询成功!");
    }

    @PutMapping("/useTemplate")
    @ApiOperation(value = "使用模板", notes = "使用模板")
    public R useTemplate(String testId, String templateId) throws Exception {
        return R.ok(testRecordService.useTemplate(testId, templateId), "使用成功!");
    }

    @GetMapping("/getProcedure")
    @ApiOperation(value = "获取步骤是否完成的参数")
    public R<ProcedureVo> getProcedure(String testId) {
        return R.ok(testRecordService.getProcedure(testId), "数据获取成功!");
    }


    @GetMapping("/solutionPage")
    @ApiOperation(value = "分页查询实验中所有溶液编号")
    public R getResultSolutionPage(Page page, String testId) {
        return R.ok(testRecordService.getResultSolutionPage(page, testId), "数据获取成功!");
    }

    @DeleteMapping
    @ApiOperation(value = "通过实验ID删除这个实验")
    public R delTestRecord(String testId) {
        return testRecordService.delTestRecord(testId) ? R.ok("删除成功!") : R.failed(" 删除失败!");
    }

    @PostMapping("/uploadTestAtlas")
    @ApiOperation(value = "上传该实验的实验图谱")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "testId", value = "实验id", required = true)
    })
    public R uploadTestAtlas(@RequestParam("testId") String testId, @RequestPart("file") MultipartFile file) {
        //  ? R.ok("上传实验图谱成功!") : R.failed("上传实验图谱删除失败!")
        try {
            return testAtlasService.uploadTestAtlas(testId, file);
        } catch (Exception e) {
            e.printStackTrace();
            return R.failed("系统出错，请联系管理员！");
        }
    }

    @GetMapping("/getTestAtlasList")
    @ApiOperation(value = "获取图谱列表")
    @ApiImplicitParam(name = "testId", value = "该实验图谱关联的实验id")
    public R getTestAtlasList(@RequestParam("testId") String testId) {
        return testAtlasService.getTestAtlasList(testId);
    }

    @GetMapping("/getTestAtlasListByBusinessId")
    @ApiOperation(value = "根据业务id获取图谱列表")
    @ApiImplicitParam(name = "businessId", value = "该实验图谱关联的实验id")
    public R getTestAtlasListByBusinessId(@RequestParam("businessId") String businessId) {
        try {
            return testAtlasService.getTestAtlasListByBusinessId(businessId);
        } catch (Exception e) {
            e.printStackTrace();
            return R.failed("系统出错，请联系管理员！");
        }
    }

    @DeleteMapping("/deleteTestAtlas")
    @ApiOperation(value = "删除图谱，支持批量删除")
    public R deleteTestAtlas(@RequestBody @Valid DeleteTestAtlasDTO dto) {
        try {
            return testAtlasService.deleteTestAtlas(dto);
        } catch (Exception e) {
            e.printStackTrace();
            return R.failed(e.getMessage());
        }
    }

    @GetMapping("/getTestAtlasByFileId")
    @ApiOperation(value = "根据实验id和文件id获取图片")
    @ApiImplicitParam(name = "testId", value = "该实验图谱关联的实验id")
    public void getTestAtlasByFileId(@RequestParam("testId") String testId,
                                     @RequestParam("fileId") String fileId,
                                     HttpServletResponse httpServletResponse) throws IOException {
        try {
            TestRecord testRecord = testRecordService.getById(testId);
            JSONArray jsonArray = JSONArray.parseArray(testRecord.getTestAtlas());
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject object = jsonArray.getJSONObject(i);
                if (object.getString("fileId").equals(fileId)) {
                    ossFile.fileGet(object.getString("path"), httpServletResponse.getOutputStream());
                    httpServletResponse.setContentType(new MimetypesFileTypeMap().getContentType(object.getString("fileName")));
                    break;
                }
            }
        } catch (AmazonS3Exception s3e) {
            httpServletResponse.sendError(s3e.getStatusCode(), s3e.toString());
        } catch (Exception e) {
            httpServletResponse.sendError(501, e.toString());
        }
//        return R.ok(ossFile.fileList(TestRecordFileUrl.TEST_ATLAS_PATH.getFileUrl()+testId));
    }

    @PostMapping("/queryTestRecordInfoByBusinessId")
    @ApiOperation("根据业务id获取实验信息")
    public R<Map<String, TestRecordVo>> queryTestRecordInfoByBusinessId(@RequestBody List<String> businessIds) {
        try {
            return testRecordService.queryTestRecordInfoByBusinessId(businessIds);
        } catch (Exception e) {
            e.printStackTrace();
            return R.failed(e.getMessage());
        }
    }

    @ApiOperation("生成检验记录-贵阳禁毒")
    @GetMapping("/inspectionRecord")
    public R inspectionRecord(String businessId, String materialType) throws Exception {
        return inspectRecordService.buildInspectionRecord(businessId, materialType, false);
    }

    @ApiOperation("预览检验记录-贵阳禁毒")
    @GetMapping("/previewRecord")
    public void previewRecord(String businessId, String materialType, HttpServletResponse response) throws Exception {
        inspectRecordService.previewInspectionRecord(businessId, materialType, response);
    }
}
