package com.zksy.report.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.xiaoymin.knife4j.core.util.StrUtil;
import com.zksy.basicData.domain.*;
import com.zksy.basicData.mapper.*;
import com.zksy.common.core.domain.AjaxResult;
import com.zksy.report.domain.CreditReportVo;
import com.zksy.report.service.CreditReportService;
import lombok.SneakyThrows;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;

@Service
public class CreditReportServiceImpl implements CreditReportService {

    private final String DEFAULT_VALUE = "-";
    private String uniCode;

    @Override
    public AjaxResult queryByUniCode(String uniCode) {
        this.uniCode = uniCode;
        CreditReportVo creditReportVo = new CreditReportVo();
        List<Consumer<CreditReportVo>> list = new ArrayList<>();
        list.add(this::processCreditReportVoA);
        list.add(this::processCreditReportVoB);
        list.add(this::processCreditReportVoC);
        list.add(this::processCreditReportVoD);
        list.add(this::processCreditReportVoE);
        list.add(this::processCreditReportVoF);
        list.add(this::processCreditReportVoG);
        list.add(this::processCreditReportVoH);
        list.parallelStream().forEach(q -> {
            q.accept(creditReportVo);
        });
        return AjaxResult.success(creditReportVo);
    }

    @Override
    @SneakyThrows
    public void downloadReport(String unicode, HttpServletResponse response) {
        try (XWPFDocument document = new XWPFDocument()) {
            // 添加标题段落
            XWPFParagraph titleParagraph = document.createParagraph();
            titleParagraph.setAlignment(ParagraphAlignment.CENTER);
            XWPFRun titleRun = titleParagraph.createRun();
            titleRun.setFontSize(24);
            titleRun.setColor("000000");
            titleRun.setText("性与暴力企业综合信用报告");

            // 添加公司名称段落
            XWPFParagraph companyParagraph = document.createParagraph();
            companyParagraph.setAlignment(ParagraphAlignment.CENTER);
            XWPFRun companyRun = companyParagraph.createRun();
            companyRun.setFontSize(18);
            companyRun.setColor("000000");
            companyRun.setText("湖南性与暴力有限公司");

            // 添加信用等级和评分情况段落
            XWPFParagraph creditParagraph = document.createParagraph();
            creditParagraph.setAlignment(ParagraphAlignment.CENTER);
            XWPFRun creditRun = creditParagraph.createRun();
            creditRun.setFontSize(16);
            creditRun.setColor("000000");
            creditRun.setText("企业信用等级：ZZZ级\n信用评分情况：0分");

            ByteArrayOutputStream out = new ByteArrayOutputStream();
            document.write(out);
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=credit_report.docx");
            response.getOutputStream().write(out.toByteArray());
            response.getOutputStream().flush();
        } catch (IOException e) {
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "下载失败");
        }
    }






    @Autowired
    private XcrEBaseinfoMapper xcrEBaseinfoMapper;
    @Autowired
    private XcrMajorMembersMapper xcrMajorMembersMapper;
    @Autowired
    private XcrAnnualReportBaseInfoMapper xcrAnnualReportBaseInfoMapper;
    @Autowired
    private XcrEnterpriseAnnualReportWebsiteMapper xcrEnterpriseAnnualReportWebsiteMapper;
    @Autowired
    private XcrEnterpriseAnnualReportShareholderMapper xcrEnterpriseAnnualReportShareholderMapper;
    @Autowired
    private XcrChangeFilingMapper xcrChangeFilingMapper;
    @Autowired
    private XcrBranchOfficesInfoMapper xcrBranchOfficesInfoMapper;
    @Autowired
    private XcrAnnualReportExternalInvestmentMapper xcrAnnualReportExternalInvestmentMapper;
    @Autowired
    private XcrAdministrativeLicensingMapper xcrAdministrativeLicensingMapper;

    private void processCreditReportVoA(CreditReportVo vo) {
        LambdaQueryWrapper<XcrEBaseinfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(XcrEBaseinfo::getUniCode, uniCode);
        XcrEBaseinfo one = xcrEBaseinfoMapper.selectOne(wrapper);
        CreditReportVo.A a1 = new CreditReportVo.A("法定代表人", DEFAULT_VALUE, DEFAULT_VALUE);
        a1 = Optional.ofNullable(one)
                .map(q -> new CreditReportVo.A("法定代表人", Optional.ofNullable(q.getNAME()).orElse(DEFAULT_VALUE), DEFAULT_VALUE))
                .orElse(a1);
        LambdaQueryWrapper<XcrMajorMembers> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(XcrMajorMembers::getUniCode, uniCode);
        List<XcrMajorMembers> list = xcrMajorMembersMapper.selectList(queryWrapper);
        ArrayList<CreditReportVo.A> resList2 = new ArrayList<>();
        list.forEach(w -> {
            Optional.ofNullable(w.getPositionCn()).filter(StrUtil::isNotBlank).ifPresent(position -> {
                CreditReportVo.A a = new CreditReportVo.A();
                //设置职位
                a.setPosition(position);
                //设置姓名
                a.setName(Optional.ofNullable(w.getNAME()).filter(StrUtil::isNotBlank).orElse(DEFAULT_VALUE));
                //设置电话号码
                a.setPhone(Optional.ofNullable(w.getTEL()).filter(StrUtil::isNotBlank).orElse(DEFAULT_VALUE));
                resList2.add(a);
            });
        });
        resList2.add(0, a1);
        vo.setA(resList2);
    }

    private void processCreditReportVoB(CreditReportVo vo) {
        CreditReportVo.B b = new CreditReportVo.B();
        //设置地址
        LambdaQueryWrapper<XcrAnnualReportBaseInfo> w1 = new LambdaQueryWrapper<>();
        w1.eq(XcrAnnualReportBaseInfo::getUniCode, uniCode);
        XcrAnnualReportBaseInfo one = xcrAnnualReportBaseInfoMapper.selectOne(w1);
        String addr = Optional.ofNullable(one)
                .map(XcrAnnualReportBaseInfo::getADDR)
                .orElse(DEFAULT_VALUE);
        b.setAddr(addr);
        //设置网站
        LambdaQueryWrapper<XcrEnterpriseAnnualReportWebsite> w2 = new LambdaQueryWrapper<>();
        w2.eq(XcrEnterpriseAnnualReportWebsite::getUniCode, uniCode);
        XcrEnterpriseAnnualReportWebsite one1 = xcrEnterpriseAnnualReportWebsiteMapper.selectOne(w2);
        String site = Optional.ofNullable(one1)
                .map(XcrEnterpriseAnnualReportWebsite::getWEBSITE)
                .orElse(DEFAULT_VALUE);
        b.setSite(site);
        //设置微信公众号
        b.setWeixin(DEFAULT_VALUE);
        vo.setB(b);
    }

    private void processCreditReportVoC(CreditReportVo creditReportVo) {
        CreditReportVo.C c = new CreditReportVo.C();
        LambdaQueryWrapper<XcrEBaseinfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(XcrEBaseinfo::getUniCode, uniCode);
        XcrEBaseinfo one = xcrEBaseinfoMapper.selectOne(wrapper);
        //设置企业名称
        c.setEnterpriseName(Optional.ofNullable(one)
                .map(XcrEBaseinfo::getENTNAME)
                .orElse(DEFAULT_VALUE));
        //设置统一社会信用代码
        c.setUniCode(Optional.ofNullable(one)
                .map(XcrEBaseinfo::getUNISCID)
                .orElse(DEFAULT_VALUE));
        //设置住所
        c.setAddr(Optional.ofNullable(one)
                .map(XcrEBaseinfo::getDOM)
                .orElse(DEFAULT_VALUE));
        // 设置注册资本
        c.setRegisteredCapital(Optional.ofNullable(one)
                .map(q -> Optional.ofNullable(q.getREGCAP())
                        .map(regCap -> regCap + Optional.ofNullable(q.getRegcapcurCn()).orElse(""))
                        .orElse(DEFAULT_VALUE))
                .orElse(DEFAULT_VALUE));
        // 设置实缴资本
        c.setPaidInCapital(Optional.ofNullable(one)
                .map(q -> Optional.ofNullable(q.getREGCAP())
                        .map(regCap -> regCap + Optional.ofNullable(q.getRegcapcurCn()).orElse(""))
                        .orElse(DEFAULT_VALUE))
                .orElse(DEFAULT_VALUE));
        //设置法定代表人姓名
        c.setLegalRepresentative(Optional.ofNullable(one)
                .map(XcrEBaseinfo::getNAME)
                .orElse(DEFAULT_VALUE));
        //设置公司类型
        c.setCompanyType(Optional.ofNullable(one)
                .map(XcrEBaseinfo::getENTTYPE)
                .orElse(DEFAULT_VALUE));
        // 设置成立日期
        c.setEstablishedTime(Optional.ofNullable(one)
                .map(q -> Optional.ofNullable(q.getESTDATE())
                        .map(w -> {
                            SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
                            return f.format(w);
                        })
                        .orElse(DEFAULT_VALUE))
                .orElse(DEFAULT_VALUE));
        // 设置营业期限
        c.setBusinessTerm(Optional.ofNullable(one)
                .map(q -> Optional.ofNullable(q.getOPTO())
                        .map(w -> {
                            SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
                            return f.format(w);
                        })
                        .orElse(DEFAULT_VALUE))
                .orElse(DEFAULT_VALUE));
        //设置所属行业
        c.setSector(Optional.ofNullable(one)
                .map(XcrEBaseinfo::getINDUSTRYPHY)
                .orElse(DEFAULT_VALUE));
        //设置行业代码
        c.setIndustryCode(Optional.ofNullable(one)
                .map(XcrEBaseinfo::getINDUSTRYCO)
                .orElse(DEFAULT_VALUE));
        //设置企业状态
        c.setCompantStatus(Optional.ofNullable(one)
                .map(XcrEBaseinfo::getRegstateCn)
                .orElse(DEFAULT_VALUE));
        //设置登记机关
        c.setRegistrationAuthority(Optional.ofNullable(one)
                .map(XcrEBaseinfo::getREGORG)
                .orElse(DEFAULT_VALUE));
        //设置经营范围
        c.setBusinessScope(Optional.ofNullable(one)
                .map(XcrEBaseinfo::getOPSCOPE)
                .orElse(DEFAULT_VALUE));
        creditReportVo.setC(c);
    }

    private void processCreditReportVoD(CreditReportVo vo) {
        ArrayList<CreditReportVo.D> resList = new ArrayList<>();
        LambdaQueryWrapper<XcrEnterpriseAnnualReportShareholder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(XcrEnterpriseAnnualReportShareholder::getUniCode, uniCode);
        List<XcrEnterpriseAnnualReportShareholder> list = xcrEnterpriseAnnualReportShareholderMapper.selectList(wrapper);
        list.forEach(one -> {
            CreditReportVo.D d = new CreditReportVo.D();
            //设置股东名称
            d.setShareholderName(Optional.ofNullable(one)
                    .map(XcrEnterpriseAnnualReportShareholder::getINVNAME)
                    .orElse(DEFAULT_VALUE));
            //设置股份比例
            d.setOwnershipInterest(DEFAULT_VALUE);
            //设置认缴出资额
            d.setSubscribedCapital(Optional.ofNullable(one)
                    .map(q -> Optional.ofNullable(q.getLISUBCONAM())
                            .map(BigDecimal::toString)
                            .orElse(DEFAULT_VALUE))
                    .orElse(DEFAULT_VALUE));
            //设置认缴出资日期
            d.setSubscribedCapitalDate(Optional.ofNullable(one)
                    .map(q -> Optional.ofNullable(q.getSUBCONDATE())
                            .map(w -> {
                                SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
                                return f.format(w);
                            })
                            .orElse(DEFAULT_VALUE))
                    .orElse(DEFAULT_VALUE));
            resList.add(d);
        });
        vo.setD(resList);
    }

    private void processCreditReportVoE(CreditReportVo vo) {
        LambdaQueryWrapper<XcrChangeFiling> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(XcrChangeFiling::getUniCode, uniCode);
        List<XcrChangeFiling> list = xcrChangeFilingMapper.selectList(wrapper);
        ArrayList<CreditReportVo.E> resList = new ArrayList<>();
        list.forEach(one -> {
            CreditReportVo.E e = new CreditReportVo.E();
            //设置变更内容
            e.setChangeProject(Optional.ofNullable(one)
                    .map(XcrChangeFiling::getAltitemCn)
                    .orElse(DEFAULT_VALUE));
            //设置变更前内容
            e.setBeforeChangeContent(Optional.ofNullable(one)
                    .map(XcrChangeFiling::getALTBE)
                    .orElse(DEFAULT_VALUE));
            //设置变更后内容
            e.setAfterChangeContent(Optional.ofNullable(one)
                    .map(XcrChangeFiling::getALTAF)
                    .orElse(DEFAULT_VALUE));
            //设置变更日期
            e.setChangeDate(Optional.ofNullable(one)
                    .map(q -> Optional.ofNullable(q.getALTDATE())
                            .map(w -> {
                                SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
                                return f.format(w);
                            })
                            .orElse(DEFAULT_VALUE))
                    .orElse(DEFAULT_VALUE));
            resList.add(e);
        });
        vo.setE(resList);
    }

    private void processCreditReportVoF(CreditReportVo vo) {
        LambdaQueryWrapper<XcrBranchOfficesInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(XcrBranchOfficesInfo::getUniCode, uniCode);
        List<XcrBranchOfficesInfo> list = xcrBranchOfficesInfoMapper.selectList(wrapper);
        ArrayList<CreditReportVo.F> resList = new ArrayList<>();
        list.forEach(one -> {
            CreditReportVo.F f = new CreditReportVo.F();
            //设置分支机构名称
            f.setBranchName(Optional.ofNullable(one)
                    .map(XcrBranchOfficesInfo::getBRNAME)
                    .orElse(DEFAULT_VALUE));
            //设置负责人
            f.setHead(DEFAULT_VALUE);
            //设置登记状态
            f.setRegStatus(DEFAULT_VALUE);
            resList.add(f);
        });
        vo.setF(resList);
    }

    private void processCreditReportVoG(CreditReportVo vo) {
        LambdaQueryWrapper<XcrAnnualReportExternalInvestment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(XcrAnnualReportExternalInvestment::getUniCode, uniCode);
        List<XcrAnnualReportExternalInvestment> list = xcrAnnualReportExternalInvestmentMapper.selectList(wrapper);
        ArrayList<CreditReportVo.G> resList = new ArrayList<>();
        list.forEach(one -> {
            CreditReportVo.G g = new CreditReportVo.G();
            //设置被投资企业名称
            g.setInvestedEnterprise(Optional.ofNullable(one)
                    .map(XcrAnnualReportExternalInvestment::getENTNAME)
                    .orElse(DEFAULT_VALUE));
            //设置被投资企业统一社会信用代码
            g.setInvestedUniCode(Optional.ofNullable(one)
                    .map(XcrAnnualReportExternalInvestment::getUNISCID)
                    .orElse(DEFAULT_VALUE));
            resList.add(g);
        });
        vo.setG(resList);
    }

    private void processCreditReportVoH(CreditReportVo vo) {
        LambdaQueryWrapper<XcrAdministrativeLicensing> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(XcrAdministrativeLicensing::getUniCode, uniCode);
        List<XcrAdministrativeLicensing> list = xcrAdministrativeLicensingMapper.selectList(wrapper);

    }
}
