package com.chinaweal.aiccs.aiccs.revoke.service.impl;

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.service.EBaseinfoService;
import com.chinaweal.aiccs.aiccs.abnormal.service.TSWritService;
import com.chinaweal.aiccs.aiccs.inspect.service.TSWorkNoService;
import com.chinaweal.aiccs.aiccs.revoke.entity.*;
import com.chinaweal.aiccs.aiccs.revoke.entity.dto.DirectRevokeDto;
import com.chinaweal.aiccs.aiccs.revoke.entity.dto.DirectRevokeResultDto;
import com.chinaweal.aiccs.aiccs.revoke.mapper.TsbizrevlistMapper;
import com.chinaweal.aiccs.aiccs.revoke.service.*;
import com.chinaweal.aiccs.aiccs.security.entity.PenaltyEntInfo;
import com.chinaweal.aiccs.aiccs.security.service.IPenaltyEntInfoService;
import com.chinaweal.aiccs.aiccs.system.service.TRBaseCodeService;
import com.chinaweal.aiccs.aiccs.writs.entity.Tswrittemplate;
import com.chinaweal.aiccs.aiccs.writs.service.TswrittemplateService;
import com.chinaweal.aiccs.common.util.*;
import com.chinaweal.aiccs.org.service.AicorgService;
import com.chinaweal.aiccs.outside.service.TfRevokeServicelmpl;
import com.chinaweal.aicorg.model.AICUser;
import com.chinaweal.youfool.framework.springboot.exception.custom.BusinessException;
import com.chinaweal.youfool.framework.springboot.mybatis.plus.BaseServiceImpl;
import com.chinaweal.youfool.framework.sso.util.SSOUtil;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import java.io.File;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Lee
 * @since 2021-03-26
 */
@Service
public class TsbizrevlistServiceImpl extends BaseServiceImpl<TsbizrevlistMapper, Tsbizrevlist> implements TsbizrevlistService {
    @Autowired
    private TsrevtasklistService tsrevtasklistService;
    @Autowired
    private CaseService caseService;
    @Autowired
    private CreateFileService createFileService;
    @Autowired
    private TSWritService tsWritService;
    @Autowired
    private EBaseinfoService eBaseinfoService;
    @Lazy
    @Autowired
    private TswritscontentService tswritscontentService;
    @Autowired
    private TSWorkNoService tsWorkNoService;
    @Autowired
    private CaseReportService caseReportService;
    @Autowired
    private AicorgService aicorgService;
    @Autowired
    private HearingNoticeService hearingNoticeService;
    @Autowired
    private PunishDecisionService punishDecisionService;
    @Autowired
    private TRBaseCodeService baseCodeService;
    @Autowired
    private TfRevokeServicelmpl tfRevokeServicelmpl;
    @Autowired
    private RevokelistService revokelistService;
    @Autowired
    private TswrittemplateService tswrittemplateService;
    @Autowired
    private BizRevEntService bizRevEntService;
    @Autowired
    private com.chinaweal.aiccs.aiccs.abnormal.service.IGzaiccodeService gzaiccodeService;
    @Autowired
    private BatchRevokePushRecordService batchRevokePushRecordService;
    @Autowired
    private IPenaltyEntInfoService iPenaltyEntInfoService;

    private final Logger logger = LoggerFactory.getLogger(TsbizrevlistServiceImpl.class);

    /**
     * 异常名录待办启动
     *
     * @param user             当前登录用户
     * @param revtaskListModel 待办信息
     * @param bizrevlists      拟吊销主体列表
     * @return 创建结果
     * @author lroyia
     * @since 2021年1月22日 13:36:00
     */
    @Override
    public Tsrevtasklist saveRevListAccept(AICUser user, Tsrevtasklist revtaskListModel, List<Tsbizrevlist> bizrevlists) {
        if (StringUtils.isBlank(revtaskListModel.getTasklistid())) {
            for (Tsbizrevlist bizRevListModel : bizrevlists) {
                bizRevListModel.setIntosponsor(user.getName());//设置主办人
                bizRevListModel.setIntosponsorId(user.getPrimaryKey());//主办人id
                bizRevListModel.setStatus("1"); // 流程启动把状态设置为 "立案经办中"
                saveOrUpdate(bizRevListModel);
            }
            String definedname = FlowUtil.REVOKEWORKFLOW;////吊销登记批量吊销流程模板

            //新待办 设置待办信息
            revtaskListModel = HandleWorkFlowUtil.createRevTaskList(revtaskListModel, user);
            //开始工作流
            tsrevtasklistService.startWorkFlow(revtaskListModel, user, definedname);
        }
        return revtaskListModel;
    }

    private String pushRevocationData(RevocationSubject revocation) {
        String result = "";
        JSONObject jobparasjson = new JSONObject();
        JSONObject jobjparas = new JSONObject();

        jobjparas.put("PRIPID", revocation.getPripid());//主体身份编码
        jobjparas.put("UNISCID", revocation.getUniscid());//统一社会信用代码
        jobjparas.put("ENTNAME", revocation.getEntname());//企业名称
        jobjparas.put("REVOKEREA", revocation.getRevokerea());//吊销批准文号
        jobjparas.put("REVOKEDATE", revocation.getRevokedate());//吊销批准部门
        jobjparas.put("AFFWRITENO", revocation.getAffwriteno());//完税情况
        jobjparas.put("PUBNEWSNAME", revocation.getPubnewsname());//清算组织
        jobjparas.put("USERID", revocation.getUserid());//吊销人员ID
        jobjparas.put("USERNAME", revocation.getUsername());//吊销人员姓名
        jobparasjson.put("params", jobjparas);

        String url = "";//推送地址

        result = getHttpClientRevocation(jobparasjson.toString(), url);

        return result;
    }

    private String getHttpClientRevocation(String param, String url) {
        String result = null;
//        HttpClientUtil httpclient = new HttpClientUtil();
//        PostMethod post = new PostMethod(url);
//        post.setRequestHeader("Content-Type", "application/json; charset=utf-8");
//        post.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "utf-8");

//        try {
//            HttpClient httpClient = new HttpClient();
//            PostMethod post = new PostMethod(url);
//            HttpMethod method = post;
//            logger.info("开始推送市场主体吊销服务数据");
//            if (param != null) {
//                RequestEntity se = new StringRequestEntity(param, "application/json", "UTF-8");
//                post.setRequestEntity(se);
//            }
//            try {
//                httpClient.executeMethod(method);
//                String restresponse = method.getResponseBodyAsString();
//                System.out.println("===================restresponse:" + restresponse);
//                result=restresponse;
//            } catch (Exception e) {
//                e.printStackTrace();
//
//            } finally {
//                post.releaseConnection();
//
//            }
//            logger.info("推送市场主体吊销服务数据成功");
//            return result;
//        }catch (Exception e){
//            e.printStackTrace();
//            logger.error("推送市场主体吊销服务数据失败"+e);
//            return "error";
//        }
        return null;
    }

    @Override
    public IPage<Tsbizrevlist> queryRevocationTzsList(IPage<Tsbizrevlist> page) {
        return baseMapper.queryRevocationTzsList(page);
    }

    @Override
    public IPage<Tsbizrevlist> queryRevocationJdsList(IPage<Tsbizrevlist> page) {
        return baseMapper.queryRevocationJdsList(page);
    }

    @Override
    public IPage<Tsbizrevlist> queryRevocationTzsByNameList(IPage<Tsbizrevlist> page, Map<String, Object> pram) {
        return baseMapper.queryRevocationTzsByNameList(page, pram);
    }

    @Override
    public IPage<Tsbizrevlist> queryRevocationJdsByNameList(IPage<Tsbizrevlist> page, Map<String, Object> pram) {
        return baseMapper.queryRevocationJdsByNameList(page, pram);
    }

    @Override
    public BizRevEnt getByPripidandBizseq(String pripid, String bizseq) {
        LambdaQueryWrapper<BizRevEnt> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BizRevEnt::getBizseq, bizseq)
                .eq(BizRevEnt::getPripid, pripid)
                .eq(BizRevEnt::getIsremove, "0");
        BizRevEnt bizRevEnt = bizRevEntService.getOne(wrapper, false);
//        LambdaQueryWrapper<Tsbizrevlist> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(Tsbizrevlist::getBizseq,bizseq)
//                .eq(Tsbizrevlist::getPripid,pripid)
//                .eq(Tsbizrevlist::getIsRemove,"0");
//        Tsbizrevlist tsbizrevlist = getOne(wrapper, false);
        return bizRevEnt;
    }

    @Override
    public IPage<Tsbizrevlist> getNoOpenRevListPage(IPage<Tsbizrevlist> page, Map<String, Object> paramMap) {
        return baseMapper.selectNoOpenRevListPage(page, paramMap);
    }

    @Override
    public List<Tsbizrevlist> getBizRevEntList(Tsbizrevlist bizrevlistParam) {
        if (bizrevlistParam == null) return null;
        return baseMapper.selectBizRevEntList(bizrevlistParam);
    }

    @Override
    public IPage<Tsbizrevlist> getRevEntPage(IPage<Tsbizrevlist> page, Map<String, Object> param) {
        return baseMapper.selectRevEntPage(page, param);
    }

    @Override
    public List<Tsbizrevlist> selectInBiz(String pripid) {
        return baseMapper.selectInBiz(pripid);
    }

    @Override
    public Tsbizrevlist getOneBybizseq(String bizseq) {
        LambdaQueryWrapper<Tsbizrevlist> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Tsbizrevlist::getBizseq, bizseq);
        return getOne(wrapper);
    }

    @Override
    public void createHearingPdf(String bizseq, String pripid, String fileName, ServletOutputStream os) throws Exception {

        Tsbizrevlist tsbizrevlist = getOneBybizseq(bizseq);
        if (tsbizrevlist == null) throw new BusinessException("下载文件错误");
        LambdaQueryWrapper<BizRevEnt> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BizRevEnt::getPripid, pripid).eq(BizRevEnt::getBizseq, bizseq).eq(BizRevEnt::getIsremove, "0");
        BizRevEnt bizRevEnt = bizRevEntService.getOne(queryWrapper);
        TsCase aCase = caseService.getByBizseq(bizseq);

        // 生成听证告知书
        Map<String, Object> map = new HashMap<>();
        // 文书内容
        LambdaQueryWrapper<Tswrittemplate> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Tswrittemplate::getBizseq, bizseq)
                .eq(Tswrittemplate::getIsTemplate, "0")
                .eq(Tswrittemplate::getWritsType, WorkNoUtil.WORKNOTYPE_32);
        Tswrittemplate tswrittemplate = tswrittemplateService.getOne(wrapper);
        if (tswrittemplate == null) {
            throw new BusinessException("下载文件错误");
        }
        map.put("htmlContent", tswrittemplate.getContent());
        map.put("writsno", bizRevEnt.getPreHearNotWritsno());
        map.put("areaName", ConstantsUtil.getAreaName(tsbizrevlist.getHandleOrg()));
        map.put("entname", bizRevEnt.getEntname());
        map.put("name", aCase.getHandlerName() + "、" + aCase.getAssistantName());
        map.put("addr", tsbizrevlist.getHandleOrgCn());
        map.put("pripid", bizRevEnt.getPripid());

        AICUser user = SSOUtil.getUser();
        if (user == null) {
            throw new BusinessException("下载文件错误,登录异常。");
        }
        String path;
        String userOrg = StringUtils.substring(user.getRegionID(), 0, 6);
        if (!userOrg.equals("440115") && !userOrg.equals("440110")) {
            path = "static" + File.separator + "template" + File.separator + "hearingNotice.docx";
        } else {
            path = "static" + File.separator + "template" + File.separator + "hearingNoticeNS.docx";
        }
        //String path = "static" + File.separator + "template" + File.separator + "hearingNotice.docx";
        ServletOutputStream pdfStream = createFileService.createPdfStream(bizseq, fileName, "13", path, map, os);
        if (pdfStream == null) {
            throw new BusinessException("下载文件错误");
        }
    }

    @Override
    public void createPunishDecPdf(String bizseq, String pripid, String fileName, ServletOutputStream os) throws Exception {
        Tsbizrevlist tsbizrevlist = getOneBybizseq(bizseq);
        if (tsbizrevlist == null) throw new BusinessException("下载文件错误");
        LambdaQueryWrapper<BizRevEnt> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BizRevEnt::getPripid, pripid).eq(BizRevEnt::getBizseq, bizseq).eq(BizRevEnt::getIsremove, "0");
        BizRevEnt bizRevEnt = bizRevEntService.getOne(queryWrapper);

        // 生成听证告知书
        Map<String, Object> map = new HashMap<>();
        // 文书内容
        LambdaQueryWrapper<Tswrittemplate> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Tswrittemplate::getBizseq, bizseq)
                .eq(Tswrittemplate::getIsTemplate, "0")
                .eq(Tswrittemplate::getWritsType, WorkNoUtil.WORKNOTYPE_33);
        Tswrittemplate tswrittemplate = tswrittemplateService.getOne(wrapper);
        if (tswrittemplate == null) {
            throw new BusinessException("下载文件错误");
        }
        EBaseinfo eBaseinfo = eBaseinfoService.getOne(new LambdaQueryWrapper<EBaseinfo>().eq(EBaseinfo::getPripid, bizRevEnt.getPripid()), false);
        map.put("htmlContent", tswrittemplate.getContent());
        map.put("entName", bizRevEnt.getEntname());
        map.put("entCerName", bizRevEnt.getEntname());
        map.put("uniscid", bizRevEnt.getUniscid());
        map.put("lerep", eBaseinfo.getLerep());
        map.put("dom", eBaseinfo.getDom());
        map.put("writsno", bizRevEnt.getPrePunDecWritsno());
        map.put("areaName", ConstantsUtil.getAreaName(tsbizrevlist.getHandleOrg()));


        AICUser user = SSOUtil.getUser();
        if (user == null) {
            throw new BusinessException("下载文件错误,登录异常。");
        }
        String path;
        String userOrg = StringUtils.substring(user.getRegionID(), 0, 6);
        if (!userOrg.equals("440115") && !userOrg.equals("440110")) {
            path = "static" + File.separator + "template" + File.separator + "punishDecision.docx";
        } else {
            path = "static" + File.separator + "template" + File.separator + "punishDecisionNS.docx";
        }
        //String path = "static" + File.separator + "template" + File.separator + "punishDecision.docx";
        ServletOutputStream pdfStream = createFileService.createPdfStream(bizseq, fileName, "14", path, map, os);
        if (pdfStream == null) {
            throw new BusinessException("下载文件错误");
        }
    }

    @Override
    public IPage<Tsbizrevlist> getForceLogoutNoticetPage(Page<Tsbizrevlist> page, Map<String, Object> param) {
        return baseMapper.getForceLogoutNoticetPage(page, param);
    }

    @Override
    public List<Tsbizrevlist> selectInZxBiz(String pripid) {
        return baseMapper.selectInZxBiz(pripid);
    }

    /**
     * 批量直接吊销市场主体（无需审批）
     * 直接将市场主体吊销状态写入吊销结果表，并推送至外部系统
     */
    @Override
    @Transactional
    public DirectRevokeResultDto directRevoke(DirectRevokeDto dto, AICUser user) {
        List<String> pripids = dto.getPripids();

        int successCount = 0;
        int failCount = 0;
        List<String> successList = new ArrayList<>();
        List<DirectRevokeResultDto.FailItem> failList = new ArrayList<>();

        LocalDateTime now = LocalDateTime.now();

        // 获取用户所属机关代码
        String orgCode = aicorgService.getRegionCodeByUser(user);
        String orgName = "";
        if (StringUtils.isNotBlank(orgCode)) {
            orgName = gzaiccodeService.getNameByCode(orgCode);
        }

        for (String pripid : pripids) {
            try {
                // 查询企业基本信息
                PenaltyEntInfo penaltyEntInfo = iPenaltyEntInfoService.getOne(new LambdaQueryWrapper<PenaltyEntInfo>()
                        .eq(PenaltyEntInfo::getPripid, pripid));

                if (penaltyEntInfo == null) {
                    failCount++;
                    failList.add(new DirectRevokeResultDto.FailItem()
                            .setPripid(pripid)
                            .setReason("执法企业信息不存在"));
                    continue;
                }

                EBaseinfo eBaseinfo = eBaseinfoService.getById(pripid);

                if (eBaseinfo == null) {
                    failCount++;
                    failList.add(new DirectRevokeResultDto.FailItem()
                            .setPripid(pripid)
                            .setReason("企业信息不存在"));
                    continue;
                }

                // 检查是否已在吊销结果表中
                Revokelist existRevoke = revokelistService.getOne(new LambdaQueryWrapper<Revokelist>()
                        .eq(Revokelist::getPripid, pripid)
                        .eq(Revokelist::getState, "1"));
                if (existRevoke != null) {
                    failCount++;
                    failList.add(new DirectRevokeResultDto.FailItem()
                            .setPripid(pripid)
                            .setEntname(eBaseinfo.getEntname())
                            .setReason("该企业已被吊销"));
                    continue;
                }

                // 检查是否在办理中的批量吊销业务
                List<Tsbizrevlist> inBizList = selectInBiz(pripid);
                if (inBizList != null && !inBizList.isEmpty()) {
                    logger.info("企业{}正在批量吊销业务中，将直接吊销", eBaseinfo.getUniscid());
                }

                // 创建吊销记录
                Revokelist revokelist = new Revokelist();
                revokelist.setPripid(pripid);
                revokelist.setUniscid(eBaseinfo.getUniscid());
                revokelist.setRegno(eBaseinfo.getRegno());
                revokelist.setEntname(eBaseinfo.getEntname());
                revokelist.setIntosponsorid(user.getPrimaryKey());
                revokelist.setIntosponsorname(user.getName());
                revokelist.setRevokeRea(dto.getRevokeReasonCode());
                revokelist.setRevokedate(now);
                revokelist.setState("1"); // 1表示吊销状态
                revokelist.setPunishOrg(orgCode);
                revokelist.setPunishOrgCn(orgName);
                revokelist.setLauptime(now);

                // 保存吊销记录
                boolean saved = revokelistService.save(revokelist);

                if (saved) {
                    // 写入推送记录存储表，后续定时任务统一推送
                    BatchRevokePushRecord pushRecord = new BatchRevokePushRecord();
                    pushRecord.setRevlistid(revokelist.getRevlistid());
                    pushRecord.setPripid(pripid);
                    pushRecord.setUniscid(eBaseinfo.getUniscid());
                    pushRecord.setEntname(eBaseinfo.getEntname());
                    pushRecord.setRevokeRea(dto.getRevokeReasonCode());
                    pushRecord.setRevokedate(now);
                    pushRecord.setPunishOrg(orgCode);
                    pushRecord.setPunishOrgCn(orgName);
                    pushRecord.setHandlerid(user.getPrimaryKey());
                    pushRecord.setHandlername(user.getName());
                    pushRecord.setPushStatus("0"); // 0-待推送
                    pushRecord.setPushCount(0);
                    pushRecord.setChangeregstate("2");
                    pushRecord.setCreateTime(now);
                    pushRecord.setUpdateTime(now);
                    pushRecord.setBiztype("0");
                    pushRecord.setRemark(dto.getRemark());

                    batchRevokePushRecordService.save(pushRecord);

                    successCount++;
                    successList.add(eBaseinfo.getEntname());
                } else {
                    failCount++;
                    failList.add(new DirectRevokeResultDto.FailItem()
                            .setPripid(pripid)
                            .setEntname(eBaseinfo.getEntname())
                            .setReason("保存吊销记录失败"));
                }

            } catch (Exception e) {
                failCount++;
                failList.add(new DirectRevokeResultDto.FailItem()
                        .setPripid(pripid)
                        .setReason("处理异常：" + e.getMessage()));
                logger.error("直接吊销处理异常，pripid：{}", pripid, e);
            }
        }

        return new DirectRevokeResultDto()
                .setTotal(pripids.size())
                .setSuccessCount(successCount)
                .setFailCount(failCount)
                .setSuccessList(successList)
                .setFailList(failList);
    }
}
