package com.njcn.gather.icd.mapping.controller;

import com.njcn.common.pojo.annotation.OperateInfo;
import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.LogUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.njcn.gather.icd.mapping.pojo.param.CsIcdPathParam;
import com.njcn.gather.icd.mapping.pojo.param.IcdCheckResultSaveParam;
import com.njcn.gather.icd.mapping.pojo.vo.CsIcdPathDetailVO;
import com.njcn.gather.icd.mapping.pojo.vo.CsIcdPathVO;
import com.njcn.gather.icd.mapping.service.CsIcdPathService;
import com.njcn.web.controller.BaseController;
import com.njcn.web.utils.HttpResultUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;

/**
 * ICD 存储记录维护入口。
 */
@Slf4j
@Api(tags = "ICD存储记录管理")
@RestController
@RequestMapping("/api/mms-mapping/icd-paths")
@RequiredArgsConstructor
public class CsIcdPathController extends BaseController {

    private final CsIcdPathService csIcdPathService;

    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @ApiOperation("查询ICD存储记录列表")
    @PostMapping("/list")
    public HttpResult<List<CsIcdPathVO>> list(@RequestBody(required = false) CsIcdPathParam.ListParam param) {
        String methodDescribe = getMethodDescribe("list");
        LogUtil.njcnDebug(log, "{}，开始查询ICD存储记录列表", methodDescribe);
        List<CsIcdPathVO> result = csIcdPathService.listIcdPaths(param);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }

    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @ApiOperation("查询参照ICD列表")
    @PostMapping("/reference-list")
    public HttpResult<List<CsIcdPathVO>> referenceList() {
        String methodDescribe = getMethodDescribe("referenceList");
        LogUtil.njcnDebug(log, "{}，开始查询参照ICD列表", methodDescribe);
        List<CsIcdPathVO> result = csIcdPathService.listReferenceIcdPaths();
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }

    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @ApiOperation("新增ICD存储记录")
    @PostMapping(value = "/add", consumes = {"application/json"})
    public HttpResult<Boolean> add(@RequestBody @Validated CsIcdPathParam param) {
        String methodDescribe = getMethodDescribe("add");
        LogUtil.njcnDebug(log, "{}，开始新增ICD存储记录", methodDescribe);
        boolean result = csIcdPathService.addIcdPath(param);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }

    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @ApiOperation("上传并新增ICD存储记录")
    @PostMapping(value = "/add", consumes = {"multipart/form-data"})
    public HttpResult<Boolean> addWithFile(@RequestPart("icdFile") MultipartFile icdFile,
                                           @RequestPart("request") @Validated CsIcdPathParam param) {
        String methodDescribe = getMethodDescribe("addWithFile");
        LogUtil.njcnDebug(log, "{}，开始上传并新增ICD存储记录，fileName={}", methodDescribe, resolveFileName(icdFile));
        fillIcdFile(param, icdFile);
        boolean result = csIcdPathService.addIcdPath(param);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }

    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @ApiOperation("编辑ICD存储记录")
    @PostMapping(value = "/update", consumes = {"application/json"})
    public HttpResult<Boolean> update(@RequestBody @Validated CsIcdPathParam.UpdateParam param) {
        String methodDescribe = getMethodDescribe("update");
        LogUtil.njcnDebug(log, "{}，开始编辑ICD存储记录，icdId={}", methodDescribe, param.getId());
        boolean result = csIcdPathService.updateIcdPath(param);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }

    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @ApiOperation("上传并编辑ICD存储记录")
    @PostMapping(value = "/update", consumes = {"multipart/form-data"})
    public HttpResult<Boolean> updateWithFile(@RequestPart("icdFile") MultipartFile icdFile,
                                              @RequestPart("request") @Validated CsIcdPathParam.UpdateParam param) {
        String methodDescribe = getMethodDescribe("updateWithFile");
        LogUtil.njcnDebug(log, "{}，开始上传并编辑ICD存储记录，icdId={}，fileName={}", methodDescribe, param.getId(), resolveFileName(icdFile));
        fillIcdFile(param, icdFile);
        boolean result = csIcdPathService.updateIcdPath(param);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }

    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @ApiOperation("激活ICD存储记录")
    @ApiImplicitParam(name = "id", value = "ICD记录ID", required = true)
    @PostMapping("/{id}/activate")
    public HttpResult<Boolean> activate(@PathVariable("id") String id) {
        String methodDescribe = getMethodDescribe("activate");
        LogUtil.njcnDebug(log, "{}，开始激活ICD存储记录，icdId={}", methodDescribe, id);
        boolean result = csIcdPathService.activateIcdPath(id);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }

    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @ApiOperation("删除ICD存储记录")
    @PostMapping("/delete")
    public HttpResult<Boolean> delete(@RequestBody List<String> ids) {
        String methodDescribe = getMethodDescribe("delete");
        LogUtil.njcnDebug(log, "{}，开始删除ICD存储记录，ids={}", methodDescribe, ids);
        boolean result = csIcdPathService.deleteIcdPath(ids);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }

    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @ApiOperation("查询ICD校验结果详情")
    @ApiImplicitParam(name = "id", value = "ICD记录ID", required = true)
    @PostMapping("/{id}/icd-check-msg")
    public HttpResult<JsonNode> getIcdCheckMsg(@PathVariable("id") String id) {
        String methodDescribe = getMethodDescribe("getIcdCheckMsg");
        LogUtil.njcnDebug(log, "{}，开始查询ICD校验结果详情，icdId={}", methodDescribe, id);
        JsonNode result = csIcdPathService.getIcdCheckMsg(id);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }

    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @ApiOperation("查询ICD映射文件详情")
    @ApiImplicitParam(name = "id", value = "ICD记录ID", required = true)
    @PostMapping("/{id}/mapping-detail")
    public HttpResult<CsIcdPathDetailVO> getMappingDetail(@PathVariable("id") String id) {
        String methodDescribe = getMethodDescribe("getMappingDetail");
        LogUtil.njcnDebug(log, "{}，开始查询ICD映射文件详情，icdId={}", methodDescribe, id);
        CsIcdPathDetailVO result = csIcdPathService.getMappingDetail(id);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }

    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @ApiOperation("保存ICD唯一性校验结果")
    @ApiImplicitParam(name = "id", value = "ICD记录ID", required = true)
    @PostMapping(value = "/{id}/icd-check-result", consumes = {"application/json"})
    public HttpResult<Boolean> saveIcdCheckResult(@PathVariable("id") String id,
                                                  @RequestBody IcdCheckResultSaveParam param) {
        String methodDescribe = getMethodDescribe("saveIcdCheckResult");
        LogUtil.njcnDebug(log, "{}，开始保存ICD校验结果，icdId={}", methodDescribe, id);
        boolean result = csIcdPathService.saveIcdCheckResult(id, param);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }

    @OperateInfo(info = LogEnum.BUSINESS_COMMON)
    @ApiOperation("上传并保存ICD唯一性校验结果")
    @ApiImplicitParam(name = "id", value = "ICD记录ID", required = true)
    @PostMapping(value = "/{id}/icd-check-result", consumes = {"multipart/form-data"})
    public HttpResult<Boolean> saveIcdCheckResultWithFile(@PathVariable("id") String id,
                                                          @RequestPart("icdFile") MultipartFile icdFile,
                                                          @RequestPart("request") IcdCheckResultSaveParam param) {
        String methodDescribe = getMethodDescribe("saveIcdCheckResultWithFile");
        LogUtil.njcnDebug(log, "{}，开始上传并保存ICD校验结果，icdId={}，fileName={}", methodDescribe, id, resolveFileName(icdFile));
        fillIcdFile(param, icdFile);
        boolean result = csIcdPathService.saveIcdCheckResult(id, param);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }

    private void fillIcdFile(CsIcdPathParam param, MultipartFile icdFile) {
        if (icdFile == null || icdFile.isEmpty()) {
            throw new IllegalArgumentException("ICD文件不能为空");
        }
        try {
            param.setIcdContent(icdFile.getBytes());
        } catch (IOException ex) {
            throw new IllegalArgumentException("读取ICD文件失败：" + ex.getMessage(), ex);
        }
    }

    private void fillIcdFile(IcdCheckResultSaveParam param, MultipartFile icdFile) {
        if (param == null) {
            throw new IllegalArgumentException("ICD校验结果不能为空");
        }
        if (icdFile == null || icdFile.isEmpty()) {
            throw new IllegalArgumentException("ICD文件不能为空");
        }
        try {
            param.setIcdContent(icdFile.getBytes());
        } catch (IOException ex) {
            throw new IllegalArgumentException("读取ICD文件失败：" + ex.getMessage(), ex);
        }
    }

    private String resolveFileName(MultipartFile icdFile) {
        if (icdFile == null || icdFile.getOriginalFilename() == null) {
            return null;
        }
        String fileName = icdFile.getOriginalFilename().trim();
        return fileName.isEmpty() ? null : fileName;
    }
}
