package com.chinaweal.aiccs.aiccs.market.controller;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.chinaweal.aiccs.aiccs.abnormal.entity.Gzaiccode;
import com.chinaweal.aiccs.aiccs.abnormal.entity.TSAttachment;
import com.chinaweal.aiccs.aiccs.abnormal.service.TSAttachmentService;
import com.chinaweal.aiccs.aiccs.business.entity.TSTaskList;
import com.chinaweal.aiccs.aiccs.market.entity.TSSueInspect;
import com.chinaweal.aiccs.aiccs.market.entity.TSUsualInspect;
import com.chinaweal.aiccs.aiccs.market.service.ITSSueInspectService;
import com.chinaweal.aiccs.common.base.controller.BaseController;
import com.chinaweal.aiccs.common.constant.BaseDataConstant;
import com.chinaweal.aiccs.common.constant.Constant;
import com.chinaweal.aiccs.common.util.ConstantsUtil;
import com.chinaweal.aiccs.common.util.StringUtils;
import com.chinaweal.aiccs.common.util.filestorage.FileStorageService;
import com.chinaweal.aiccs.config.CommonConfig;
import com.chinaweal.aiccs.org.service.TUsersService;
import com.chinaweal.aicorg.model.AICUser;
import com.chinaweal.youfool.framework.springboot.mybatis.plus.page.PageRequestDto;
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.chinaweal.youfool.framework.sso.util.SSOUtil;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ConfigureBuilder;
import com.deepoove.poi.util.PoitlIOUtils;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 应诉检查信息  控制器
 * </p>
 *
 * @author chinaweal
 * @since 2021-10-13
 */
@Api(tags = "应诉检查相关接口")
@ApiSort(2)
@RestController
@RequestMapping("/market/sueInspect")
@Slf4j
public class TSSueInspectController extends BaseController {

    @Resource
    private FileStorageService fileStorageService;
    @Resource
    private ITSSueInspectService iTSSueInspectService;
    @Resource
    private TSAttachmentService attachmentService;
    @Resource
    private TUsersService tUsersService;

    @ApiOperation(value = "1.新增应诉检查信息 ", position = 1)
    @ApiOperationSupport(order = 1)
    @PostMapping("/save")
    public RestResult<TSSueInspect> saveTSSueInspect(@RequestBody @Valid TSSueInspect tssueinspect, BindingResult bindingResult) {
        AssertUtils.isBndingValidit(bindingResult);
        tssueinspect = iTSSueInspectService.saveTSSueInspect(tssueinspect);
        return RestResult.ok(tssueinspect);
    }

    @ApiOperation(value = "2.删除应诉检查信息 ", position = 2)
    @PostMapping("/delete")
    public RestResult<String> removeTSSueInspect(@RequestParam @ApiParam("bizseq") String id) {
        if(StringUtils.isBlank(id)){
            return RestResult.error(ResultCode.PARAM_IS_BLANK);
        }
        TSSueInspect tsSueInspect = null;
        tsSueInspect = iTSSueInspectService.getById(id);
        if(tsSueInspect != null){
            tsSueInspect.setStatus("4");
            iTSSueInspectService.updateById(tsSueInspect);
        }

        return RestResult.ok();
    }

    @ApiOperation(value = "3.修改应诉检查信息 ", position = 3)
    @PostMapping("/update")
    public RestResult<String> updateTSSueInspect(@RequestBody @Valid TSSueInspect tssueinspect, BindingResult bindingResult) {
        AssertUtils.isBndingValidit(bindingResult);
        iTSSueInspectService.updateTSSueInspect(tssueinspect);
        return RestResult.ok();
    }

    @ApiOperation(value = "4.查询应诉检查信息 ", position = 4)
    @GetMapping("/get")
    public RestResult<TSSueInspect> getTSSueInspect(@RequestParam @ApiParam("id") Serializable id) {
        TSSueInspect tssueinspect = iTSSueInspectService.getById(id);
        return RestResult.ok(tssueinspect);
    }

    @ApiOperation(value = "5.分页查询应诉检查信息 ", position = 5)
    @PostMapping("/list")
    public RestResult<IPage<TSSueInspect>> listTSSueInspect(@RequestBody PageRequestDto pageRequestDto) {
        IPage<TSSueInspect> data = iTSSueInspectService.defaultPaging(pageRequestDto, queryWrapper -> {
            queryWrapper.lambda().ne(TSSueInspect::getStatus, "4");
            Map<String, Object> customParamMap = pageRequestDto.getCustomParamMap();
            if (customParamMap == null) return;
            // type 0-待检查 1-已检查
            if ("1".equals(customParamMap.get("type"))) {
                queryWrapper.lambda().eq(TSSueInspect::getStatus, "1");
            } else {
                queryWrapper.lambda().ne(TSSueInspect::getStatus, "1");
            }
            // 根据机关查询
            AICUser aicUser = SSOUtil.getUser();
            Gzaiccode gzaiccode = tUsersService.findOrganization(aicUser.getPrimaryKey());
            queryWrapper.lambda().eq(TSSueInspect::getInspectOrg, gzaiccode.getScountrycode());
        }, null);
        return RestResult.ok(data);
    }

    @ApiOperation(value = "6.上传线索来源和附件(attachType 0-责令书 1-线索来源 2-附件) ", position = 6)
    @PostMapping("upload")
    public RestResult<?> upload(MultipartFile[] file, String attachType, String id, HttpServletRequest request) throws IOException {
        // 获得上传目录
        AICUser curUser = getLoginUser(request);
        // 获得上传目录
        String realPath = CommonConfig.getFraudRegPath();
        realPath += File.separator + curUser.getPrimaryKey() + File.separator + id;

        for (MultipartFile multipartFile : file) {
            String fileName = multipartFile.getOriginalFilename();
            String ext = StringUtils.isNotBlank(fileName) && fileName.lastIndexOf(Constant.DOT) > -1 ? fileName.substring(fileName.lastIndexOf(Constant.DOT)) : StringUtils.EMPTY;
            String virtualFileName = IdUtil.simpleUUID() + ext;
            fileStorageService.writeFromStream(realPath, virtualFileName, multipartFile.getInputStream());

            TSAttachment tsAttachment = new TSAttachment();
            tsAttachment.setBizseq(id);
            tsAttachment.setPripid(StringUtils.EMPTY);
            tsAttachment.setFileext(ext);
            tsAttachment.setFilename(fileName);
            tsAttachment.setFileurl(realPath + File.separator + virtualFileName);
            tsAttachment.setUploaddate(LocalDate.now());
            tsAttachment.setUserid(curUser.getPrimaryKey());
            tsAttachment.setUsername(curUser.getName());
            tsAttachment.setAttachtype(attachType); // 1-线索来源 2-上传附件
            attachmentService.save(tsAttachment);
        }

        return RestResult.ok();
    }

    @ApiOperation(value = "7.上传线索来源和附件回显 ", position = 7)
    @GetMapping(value = "/listFile")
    public RestResult<List<TSAttachment>> listFile(@RequestParam String id) {
        AssertUtils.isNotBlank(id);
        return RestResult.ok(attachmentService.lambdaQuery().eq(TSAttachment::getBizseq, id).list());
    }

    @ApiOperation(value = "8.材料文件下载", position = 8)
    @GetMapping("/downloadFile")
    public void uploadFile(@RequestParam String fileId, HttpServletResponse response) throws IOException {
        TSAttachment tsAttachment = attachmentService.getById(fileId);
        //拼接绝对路径，获取流
        String realPath = CommonConfig.getUploadPath();
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(realPath + File.separator + tsAttachment.getTemppath()));
        BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
        String fileName = new String(tsAttachment.getFilename().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        //设置：当浏览器收到这份资源的时候，以下载的方式提醒用户，而不是直接显示
        response.setHeader("Content-Disposition", "attachment;  filename=\"" + fileName + "\"");
        byte[] buffer = new byte[4096];
        int len;
        while ((len = bis.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bis.close();
        bos.close();
    }

    @ApiOperation(value = "9.线索来源和附件删除", position = 9)
    @PostMapping("/delFile")
    public RestResult<?> delFile(@RequestParam String id) {
        TSAttachment tsAttachmentModel = attachmentService.getById(id);
        if (tsAttachmentModel == null) return RestResult.error(ResultCode.DATA_NONE);
        String realPath = CommonConfig.getUploadPath() + File.separator + tsAttachmentModel.getTemppath();
        try {
            Files.delete(Paths.get(realPath));
        } catch (IOException e) {
            log.error("删除文件异常", e);
        }
        attachmentService.removeById(id);
        return RestResult.ok();
    }


    @ApiOperation(value = "10.生成检查表", position = 10)
    @GetMapping("/createInspectDoc")
    public void createInspectDoc(@RequestParam String id, HttpServletResponse response) throws IOException {
        TSSueInspect tssueinspect = iTSSueInspectService.getById(id);
        String realPath = this.getClass().getClassLoader().getResource("static/template/sueInspect.docx").getPath();
        ConfigureBuilder builder = Configure.newBuilder();
        builder.setElMode(Configure.ELMode.SPEL_MODE);
        XWPFTemplate template = XWPFTemplate.compile(realPath, builder.build()).render(tssueinspect);
        response.setContentType("application/octet-stream");
        response.setHeader("Content-disposition","attachment;filename="+ new String("检查表".getBytes("UTF-8"),"ISO-8859-1") +".docx");

        try (OutputStream out = response.getOutputStream();
                BufferedOutputStream bos = new BufferedOutputStream(out)) {
            template.write(bos);
            bos.flush();
            out.flush();
            PoitlIOUtils.closeQuietlyMulti(template, bos, out);
        }
    }

    @ApiOperation(value = "11.获取检查记录信息", position = 11)
    @GetMapping("getList")
    public RestResult<List<TSSueInspect>> getTSSueInspectList(String pripid){
        AssertUtils.isNotEmpty(pripid);
        List<TSSueInspect> list = iTSSueInspectService.getListByPripid(pripid);
        if(CollectionUtils.isNotEmpty(list)){
            for (TSSueInspect tsSueInspect : list) {
                // 封装检查方式中文
                String inspectTypeStr = ConstantsUtil.getInspectTypeMap().get(tsSueInspect.getInspectType());
                if(inspectTypeStr != null){
                    tsSueInspect.setInspectTypeStr(inspectTypeStr);
                }
                // 封装检查结果中文
                String inspectResultStr = ConstantsUtil.getInspectResultMap().get(tsSueInspect.getInspectResult());
                if(inspectResultStr != null){
                    tsSueInspect.setInspectResultStr(inspectResultStr);
                }
            }
        }
        return RestResult.ok(list);
    }

}
