package com.chinaweal.aiccs.aiccs.fraudreg.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.chinaweal.aiccs.aiccs.abnormal.entity.EBaseinfo;
import com.chinaweal.aiccs.aiccs.abnormal.entity.TSAttachment;
import com.chinaweal.aiccs.aiccs.abnormal.service.EBaseinfoService;
import com.chinaweal.aiccs.aiccs.abnormal.service.TSAttachmentService;
import com.chinaweal.aiccs.aiccs.auditing.service.TSOpinionService;
import com.chinaweal.aiccs.aiccs.business.entity.TSTaskList;
import com.chinaweal.aiccs.aiccs.business.service.TSTaskListService;
import com.chinaweal.aiccs.aiccs.business.service.WorkFlowService;
import com.chinaweal.aiccs.aiccs.fraudreg.dto.FraudInfoDto;
import com.chinaweal.aiccs.aiccs.fraudreg.dto.FraudProcessDto;
import com.chinaweal.aiccs.aiccs.fraudreg.entity.TFraudCheck;
import com.chinaweal.aiccs.aiccs.fraudreg.service.*;
import com.chinaweal.aiccs.common.base.controller.BaseController;
import com.chinaweal.aiccs.common.util.valid.ValidGroup;
import com.chinaweal.youfool.framework.springboot.rest.RestResult;
import com.chinaweal.youfool.framework.springboot.rest.ResultCode;
import com.chinaweal.youfool.framework.springboot.util.AssertUtils;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import com.github.xiaoymin.knife4j.annotations.DynamicParameter;
import com.github.xiaoymin.knife4j.annotations.DynamicResponseParameters;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.Valid;
import javax.validation.Validator;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 涉嫌冒用登记流程业务相关接口
 * Code: Yangmc
 * Date: 2021/11/12
 * Time: 13:48
 */

@Api(tags = "1.涉嫌冒用登记业务流程")
@ApiSort(1)
@RestController
@RequestMapping("/fraudReg/process")
@Slf4j
public class FraudProcessController extends BaseController {

    @Resource
    private Validator globalValidator;

    @Resource
    private IFraudProcessService iFraudProcessService;
    @Resource
    private ITBizFraudService itBizFraudService;
    @Resource
    private ITFraudPersonService itFraudPersonService;
    @Resource
    private ITFraudEntService itFraudEntService;
    @Resource
    private ITFraudCheckService itFraudCheckService;
    @Resource
    private TSTaskListService taskListService;
    @Resource
    private TSAttachmentService attachmentService;
    @Resource
    private WorkFlowService workFlowService;
    @Resource
    private TSOpinionService tsOpinionService;
    @Resource
    private EBaseinfoService eBaseInfoService;

    @ApiOperation(value = "1.启动待办,保存投诉人、被投诉主体信息等相关信息", position = 1)
    @DynamicResponseParameters(name = "涉嫌冒用登记启动待办返回结果集", properties = {
            @DynamicParameter(name = "taskId", value = "待办id"),
            @DynamicParameter(name = "bizSeq", value = "业务id"),
            @DynamicParameter(name = "workflowId", value = "工作流id"),
    })
    @PostMapping("/startTask")
    public RestResult<?> startTask(@RequestBody FraudInfoDto fraudInfoDto, HttpServletRequest request) {

        // 根据投诉人类型手动执行校验规则
        List list = globalValidator.validate(fraudInfoDto, "0".equals(fraudInfoDto.getComplainerType()) ? ValidGroup.Fraud.Person.class :"2".equals(fraudInfoDto.getComplainerType())? ValidGroup.Fraud.Other.class : ValidGroup.Fraud.Ent.class)
                .stream()
                .map(ConstraintViolation::getMessage)
                .collect(Collectors.toList());
        AssertUtils.isTrue(list.isEmpty(), ResultCode.PARAM_IS_INVALID, list);
        // 封装参数
        LambdaQueryWrapper<EBaseinfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EBaseinfo::getUniscid,fraudInfoDto.getUniScId());
        // 查询基本信息
        EBaseinfo eBaseinfo = eBaseInfoService.getOne(wrapper);
        fraudInfoDto.setBusinessType("1");
        if ("2".equals(fraudInfoDto.getBusinessType())){

            if (!"1".equals(eBaseinfo.getRegstate())){
                return RestResult.error(ResultCode.SPECIFIED_QUESTIONED_USER_NOT_EXIST,"该企业状态不允许撤销变更");
            }
        }else if ("3".equals(fraudInfoDto.getBusinessType())){
            if (!"3".equals(eBaseinfo.getRegstate()) && !"4".equals(eBaseinfo.getRegstate())){
                return RestResult.error(ResultCode.SPECIFIED_QUESTIONED_USER_NOT_EXIST,"该企业状态不允许撤销注销");
            }
        }
        return RestResult.ok(iFraudProcessService.startTask(fraudInfoDto, getLoginUser(request)));
    }

    @ApiOperation(value = "2.获取业务相关业务信息", position = 2)
    @GetMapping("/getBusFraudInfo")
    public RestResult<Map<String, Object>> getBusFraudInfo(@RequestParam @ApiParam("业务主键") String bizSeq,
                                                           @RequestParam @ApiParam("工作流id") String workflowId,
                                                           @RequestParam @ApiParam("是否只读 0-否 1-是") String readOnly) {
        AssertUtils.isNotBlank(bizSeq, workflowId);
        Map<String, Object> result = new HashMap<>();
        result.put("bizFraudInfo", itBizFraudService.getTBizFraudByBizSeq(bizSeq));
        result.put("fraudEntInfo", itFraudEntService.getByBizSeq(bizSeq));
        result.put("fraudPersonInfo", itFraudPersonService.getByBizSeq(bizSeq));
        result.put("opinions", tsOpinionService.getOpinionsWithOrg(workflowId));
        result.put("fraudCheckInfo", itFraudCheckService.lambdaQuery().eq(TFraudCheck::getBizSeq, bizSeq).one());
        if ("0".equals(readOnly)) result.put("nextSequenceFlowList", workFlowService.findNextSequenceFlowList(workflowId));
        return RestResult.ok(result);
    }

    @ApiOperation(value = "3.上传线索来源和附件(attachType 0-投诉人身份信息 1-线索来源 2-案件信息材料 " +
            "3-撤销设立通知书、撤销变更通知书、不予受理通知书) 4-现场核查通知书扫描件 ", position = 3)
    @PostMapping("upload")
    public RestResult<List<TSAttachment>> upload(@RequestParam MultipartFile[] files, @RequestParam String attachType, @RequestParam String id, HttpServletRequest request) throws IOException {
        AssertUtils.isNotBlank(attachType, id);
        if (files.length == 0) throw new RuntimeException("附件内容为空");
        return RestResult.ok(iFraudProcessService.upload(files, id, attachType, getLoginUser(request)));
    }

    @ApiOperation(value = "4.上传线索附件、案件材料回显 ", position = 4)
    @GetMapping(value = "/listFile")
    public RestResult<List<TSAttachment>> listFile(@RequestParam String id, @RequestParam String attachType) {
        AssertUtils.isNotBlank(id);
        return RestResult.ok(attachmentService.lambdaQuery().eq(TSAttachment::getBizseq, id).eq(TSAttachment::getAttachtype, attachType).list());
    }

    @ApiOperation(value = "5.流程控制", position = 5)
    @PostMapping("/processControl")
    public RestResult<?> processControl(@RequestBody @Validated FraudProcessDto fraudProcessDto, BindingResult bindingResult, HttpServletRequest request) {
        AssertUtils.isBndingValidit(bindingResult);

        List<TSTaskList> listTask = taskListService.selectByBizSeqID(fraudProcessDto.getBizSeq());
        AssertUtils.isTrue(!listTask.isEmpty(), ResultCode.DATA_NONE);

        String msg=iFraudProcessService.processControl(fraudProcessDto, listTask.get(0), getLoginUser(request));
        if(!msg.equals("success")) return RestResult.error(ResultCode.INTERFACE_OUTER_INVOKE_ERROR,msg);
        return RestResult.ok();
    }


}
