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

import cn.hutool.core.util.IdUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.business.entity.TSTaskList;
import com.chinaweal.aiccs.aiccs.business.service.TSTaskListService;
import com.chinaweal.aiccs.aiccs.market.entity.TSUsualInspect;
import com.chinaweal.aiccs.aiccs.market.service.ITSUsualInspectService;
import com.chinaweal.aiccs.aiccs.market.service.impl.BizOwnerAssignServiceImpl;
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.exception.custom.BusinessException;
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.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.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * <p>
 * 日常检查信息 控制器
 * </p>
 *
 * @author chinaweal
 * @since 2021-10-18
 */
@Api(tags = "日常检查相关接口")
@ApiSort(1)
@RestController
@RequestMapping("/market/tSUsualInspect")
@Slf4j
public class TSUsualInspectController extends BaseController {

    @Resource
    private FileStorageService fileStorageService;
    @Resource
    private BizOwnerAssignServiceImpl bizOwnerAssignService;
    @Resource
    private ITSUsualInspectService iTSUsualInspectService;
    @Resource
    private TSAttachmentService attachmentService;
    @Resource
    private EBaseinfoService eBaseinfoService;
    @Resource
    private TUsersService tUsersService;
    @Resource
    private TSTaskListService taskListService;

    @ApiOperation(value = "0.分页查询企业主体信息", position = 1)
    @PostMapping("/listEntInfo")
    public RestResult<IPage<EBaseinfo>> listEntInfo(HttpServletRequest request, @RequestBody PageRequestDto pageRequestDto) {

        IPage<EBaseinfo> data = eBaseinfoService.defaultPaging(pageRequestDto, queryWrapper -> {
            queryWrapper.lambda().eq(EBaseinfo::getRegstate, "1");
            /**
             * 需要限制区域
             * 1、市局用户可以监管所有企业；
             *
             * 2、区所局用户可以监管所属区划下的所有企业；
             *
             */
            AICUser aicUser = getLoginUser(request);
            if (!"440101".equals(aicUser.getRegionID())) { // 区所局
                queryWrapper.lambda().likeRight(EBaseinfo::getSuporg, aicUser.getRegionID().substring(0, 6));
            }

            Map<String, Object> customParamMap = pageRequestDto.getCustomParamMap();
            if (customParamMap == null || customParamMap.isEmpty()) return;
            String entType = customParamMap.get("entType") != null ? customParamMap.get("entType").toString() : null;
            if ("individual".equals(entType)) {
                queryWrapper.lambda().eq(EBaseinfo::getEnttype, "9910");
            } else if ("farmer".equals(entType)) {
                queryWrapper.lambda().in(EBaseinfo::getEnttype, "9100", "9200");
            } else if ("company".equals(entType)) {
                queryWrapper.lambda().notIn(EBaseinfo::getEnttype, "9910", "9100", "9200");
            }
            String regno = customParamMap.get("regno") != null ? customParamMap.get("regno").toString() : null;
            if (StringUtils.isNotBlank(regno)) {
                queryWrapper.lambda().and(fq -> fq.or(eq -> eq.eq(EBaseinfo::getUniscid, regno)).or(eq -> eq.eq(EBaseinfo::getRegno, regno)));
            }

            if (customParamMap.get("entname")!= null && StringUtils.isNotBlank(customParamMap.get("entname").toString())) {
                queryWrapper.lambda().eq(EBaseinfo::getEntname, customParamMap.get("entname").toString());
            }

            if (customParamMap.get("sliceId") != null && StringUtils.isNotBlank(customParamMap.get("sliceId").toString())) {
                List<String> pripIds = new ArrayList<>();
                String sliceId = customParamMap.get("sliceId").toString();
                bizOwnerAssignService.listBySliceId(sliceId).forEach(item -> { pripIds.add(item.getPripid()); });
                queryWrapper.lambda().in(EBaseinfo::getPripid, pripIds);
            }
        }, null);
        return RestResult.ok(data);
    }

    @ApiOperation(value = "1.新增日常检查信息(启动流程-单独检查)", position = 1)
    @PostMapping("/save")
    public RestResult<TSUsualInspect> saveTSUsualInspect(@RequestBody @Valid TSUsualInspect tSUsualInspect, BindingResult bindingResult) {
        AssertUtils.isBndingValidit(bindingResult);
        tSUsualInspect = iTSUsualInspectService.saveTSUsualInspect(tSUsualInspect);
        return RestResult.ok(tSUsualInspect);
    }

    @ApiOperation(value = "2.删除日常检查信息", position = 2)
    @PostMapping("/delete")
    public RestResult<String> removeTSUsualInspect(@RequestParam @ApiParam("bizSeq") String id) {
        if(StringUtils.isBlank(id)){
            return RestResult.error(ResultCode.PARAM_IS_BLANK);
        }
        TSUsualInspect tsUsualInspect = null;
        tsUsualInspect = iTSUsualInspectService.getById(id);
        if(tsUsualInspect != null){
            tsUsualInspect.setStatus("4");
            iTSUsualInspectService.updateById(tsUsualInspect);
        }

        LambdaQueryWrapper<TSTaskList> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TSTaskList::getBizseqid, tsUsualInspect.getBizSeq());
        TSTaskList task = taskListService.getOne(wrapper);
        if(task != null){
            task.setBusstatus(BaseDataConstant.BUSINESS_STATUS_XYXF_END);
            taskListService.updateById(task);
        }

        return RestResult.ok();
    }

    @ApiOperation(value = "3.修改日常检查信息", position = 3)
    @PostMapping("/update")
    public RestResult<?> updateTSUsualInspect(@RequestBody @Valid TSUsualInspect tSUsualInspect, BindingResult bindingResult) {
        AssertUtils.isBndingValidit(bindingResult);
        AICUser aicUser = SSOUtil.getUser();
        tSUsualInspect.setInspectorId(aicUser.getPrimaryKey());
        return RestResult.ok(iTSUsualInspectService.updateTSUsualInspect(tSUsualInspect));
    }

    @ApiOperation(value = "4.查询日常检查信息", position = 4)
    @GetMapping("/get")
    public RestResult<TSUsualInspect> getTSUsualInspect(@RequestParam @ApiParam("id") Serializable id) {
        AICUser aicUser = SSOUtil.getUser();
        TSUsualInspect tSUsualInspect = iTSUsualInspectService.getById(id);
        if (tSUsualInspect.getInspector() == null || "".equals(tSUsualInspect.getInspector())) {
            tSUsualInspect.setInspector(aicUser.getName());
        }
        return RestResult.ok(tSUsualInspect);
    }

    @ApiOperation(value = "5.分页查询日常检查信息", position = 5)
    @PostMapping("/list")
    public RestResult<IPage<TSUsualInspect>> listTSUsualInspect(@RequestBody PageRequestDto pageRequestDto) {

        AICUser aicUser = SSOUtil.getUser();
        Map<String, Object> customParamMap = pageRequestDto.getCustomParamMap();
        Map<String, Object> paramMap = pageRequestDto.getParamMap();
        Map<String, String> likeParamMap = pageRequestDto.getLikeParamMap();
        if (customParamMap != null && !customParamMap.containsKey("type")) {
            throw new BusinessException(ResultCode.PARAM_NOT_COMPLETE);
        }

        IPage<TSUsualInspect> data = null;
        if ("0".equals(customParamMap.get("type"))) { // 查待办
            // 搜索统一码和注册号
            String regno = StringUtils.tranObject(paramMap.get("regno"));
            String uscc = StringUtils.tranObject(paramMap.get("uscc"));
            String searchName = likeParamMap.get("entName");
            //判断入参为统一码还是注册号
            if (StringUtils.isNotBlank(uscc)) {
                customParamMap.put("uscc",uscc);
            }
            if (StringUtils.isNotBlank(regno)){
                customParamMap.put("regno",regno);
            }
            if (StringUtils.isNotBlank(searchName)){
                customParamMap.put("entName", searchName);
            }
            Boolean orderingRuleBoolean = pageRequestDto.getOrderingRuleBoolean();
            String orderField = pageRequestDto.getOrderField();
            customParamMap.put("signuserid", aicUser.getPrimaryKey());
            customParamMap.put("pageIndex", (pageRequestDto.getCurPage() - 1) * pageRequestDto.getPageSize());
            customParamMap.put("pageSize",  pageRequestDto.getPageSize());
            customParamMap.put("orderField", orderField);
            customParamMap.put("orderingRuleBoolean", orderingRuleBoolean);
            List<TSUsualInspect> pageByTask = iTSUsualInspectService.getPageByTask(customParamMap);
            Integer count = iTSUsualInspectService.countByTask(customParamMap);
//            IPage<TSTaskList> listIPage = taskListService.lambdaQuery().eq(TSTaskList::getBustype, BaseDataConstant.MARKET_INSPECT)
//                    .in(TSTaskList::getBusstatus, "0", "-1")
//                    .and(i -> i.eq(TSTaskList::getSignuserid, aicUser.getPrimaryKey())
//                            .or().exists(String.format("select 1 from tsrefgroupanduser tg where tg.GROUPID = tstasklist.ACCEPTGROUPID and tg.USERID = '%s'", aicUser.getPrimaryKey()))).page(new Page<>(pageRequestDto.getCurPage(), pageRequestDto.getPageSize()));

            data = new Page<>(pageRequestDto.getCurPage(), pageRequestDto.getPageSize());
            data.setTotal(count);
            data.setRecords(pageByTask);
//            if (listIPage.getRecords().size() > 0) {
//                data.setRecords(iTSUsualInspectService.lambdaQuery().in(TSUsualInspect::getBizSeq, listIPage.getRecords().stream().map(TSTaskList::getBizseqid).collect(Collectors.toList())).list());
//            } else {
//                data.setRecords(null);
//            }
        } else {
            data = iTSUsualInspectService.defaultPaging(pageRequestDto, queryWrapper -> {
                queryWrapper.lambda().eq(TSUsualInspect::getStatus, "1");
                queryWrapper.lambda().eq(TSUsualInspect::getInspectOrg, aicUser.getRegionID());
            }, null);
        }

        return RestResult.ok(data);
    }

    @ApiOperation(value = "6.上传附件 ", position = 6)
    @PostMapping("upload")
    public RestResult<?> upload(MultipartFile[] file, String attachType, String id, HttpServletRequest request) throws IOException {
        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;
            if (!Constant.EXT_MAP.containsKey(ext)) {
                return RestResult.error(ResultCode.PARAM_IS_INVALID, "上传文件格式不正确");
            }
        }
        // 获得上传目录
        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);
        if (tsAttachment == null) {
            throw new BusinessException("文件无法找到" + fileId);
        }
        response.setHeader("Content-Disposition", "attachment;  filename=\"" + new String(tsAttachment.getFilename().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1) + "\"");
        fileStorageService.writeToStream(tsAttachment.getFileurl(), response.getOutputStream());
    }

    @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)
    @PostMapping(value = "/batchSave")
    public RestResult<?> batchSave(MultipartFile file, String inspectExpireDate, String source) {
        AssertUtils.isNotBlank(inspectExpireDate, source);
        return RestResult.ok(iTSUsualInspectService.batchSave(file, inspectExpireDate, source));
    }

    @ApiOperation(value = "10.批量地址新增待检查业户 （发起一条任务）", position = 10)
    @PostMapping(value = "/batchAddressSave", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public RestResult<?> batchAddressSave(String ids, String inspectExpireDate, String source, String checkAddress) {
        AssertUtils.isNotBlank(inspectExpireDate, source);
        return RestResult.ok(iTSUsualInspectService.batchAddressSave(ids, inspectExpireDate, source, checkAddress));
    }

    /**
     * 导出excel批量未查询出的数据
     */
    @ApiOperation(value = "11.导出excel批量未查询出的数据", position = 11)
    @GetMapping("/exportNoSearchData")
    public void exportNoSearchData(@RequestParam @ApiParam("id") String id, HttpServletResponse response) {
        AssertUtils.isNotBlank(id);
        iTSUsualInspectService.exportNoSearchData(id, response);
    }

    @ApiOperation(value = "12.企业主体详细-检查记录信息", position = 12)
    @GetMapping("getList")
    public RestResult<List<TSUsualInspect>> getTSUsualInspectList(String pripid){
        AssertUtils.isNotEmpty(pripid);
        List<TSUsualInspect> list = iTSUsualInspectService.getListByPripid(pripid);
        if (CollectionUtils.isNotEmpty(list)) {
            for (TSUsualInspect tsUsualInspect : list) {
                // 封装检查结果中文
                AtomicReference<String> inspectResultStr = new AtomicReference<>("");
                Arrays.stream(tsUsualInspect.getInspectResult().split(",")).forEach(key -> {
                    inspectResultStr.set(inspectResultStr.get() + ConstantsUtil.getInspectResultMap().get(key) + ";");
                });
                if (inspectResultStr != null) {
                    tsUsualInspect.setInspectResultStr(inspectResultStr.get());
                }
            }
        }
        List<TSUsualInspect> historyList = iTSUsualInspectService.queryHistroyListByPripid(pripid);
        if (historyList.size()>0) list.addAll(historyList);
        return RestResult.ok(list);
    }

    @ApiOperation(value = "13.市场所协同综合统计", position = 13)
    @GetMapping("/statistics")
    public RestResult<Map<String, List<Map<String, String>>>> statistics() {
        return RestResult.ok(iTSUsualInspectService.statistics());
    }


    @ApiOperation(value = "14.修复上线前在办数据", position = 14)
    @GetMapping("/repairData")
    public RestResult<?> repairData() {
        iTSUsualInspectService.repairData();
        return RestResult.ok();
    }

    @ApiOperation(value = "15.发起多条任务", position = 15)
    @PostMapping("/startManyTask")
    public RestResult<?> startManyTask(String ids, String inspectExpireDate, String source) {
        AssertUtils.isNotBlank(inspectExpireDate, source);
        return RestResult.ok(iTSUsualInspectService.startManyTask(ids, inspectExpireDate, source));
    }

    @ApiOperation(value = "16.导出不可发起的企业名单", position = 16)
    @PostMapping("exportNoCanExcel")
    public void exportNoCanExcel(String ids, HttpServletRequest request, HttpServletResponse response) throws IOException {
        AssertUtils.isNotBlank(ids);
        AICUser aicUser = getLoginUser(request);
        if(aicUser==null){
            throw new BusinessException("登录超时，请重新登录");
        }
        List<String> pripids = Arrays.asList(ids.split(";"));
        List<String> filedList = new ArrayList<>();
        filedList.add("统一社会信用代码");
        filedList.add("主体名称");
        filedList.add("地址");

        ServletOutputStream outputStream=null;
        try {
            response.setHeader("Pragma", "No-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setHeader("Content-Disposition",
                    "attachment;filename=" + new String("不可发起名单.xlsx".getBytes(), "UTF-8"));
            response.setContentType("application/msexcel;charset=UTF-8");
            outputStream = response.getOutputStream();
            ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
            WriteSheet writeSheet1 = EasyExcel.writerSheet(0, "sheet1").build();

            List<List<Object>> rs = eBaseinfoService.exportInfo2(pripids, filedList, true);
            excelWriter.write(rs, writeSheet1);
            excelWriter.finish();
        }catch (Exception e) {
            outputStream.close();
            e.printStackTrace();
        } finally {
            outputStream.close();
        }
    }


    /**
     * 记录查看联系人操作
     *
     * @param pripid 主体pripid
     * @author lwd
     * @since 2025年6月25日 16:11:09
     */
    @ApiOperation("记录查看联系人操作")
    @RequestMapping("addContactLogByEntNo")
    public RestResult<?> addContactLogByEntNo(String pripid,String originalValue, HttpServletResponse response, HttpServletRequest request) {
        AICUser aicUser = getLoginUser(request);
        return RestResult.ok(iTSUsualInspectService.addContactLogByEntNo(pripid,originalValue, aicUser));
    }
}
