package com.tofly.feesapi.dzfp.controller;

import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tofly.feesapi.common.core.ResultRespone;
import com.tofly.common.core.util.StringUtil;
import com.tofly.common.core.util.io.IOUtil;
import com.tofly.feesapi.common.Excel.ExcleFileUtil;
import com.tofly.feesapi.common.core.dto.PageDto;
import com.tofly.feesapi.common.core.vo.PageResult;
import com.tofly.feesapi.common.exception.FeesErrorCode;
import com.tofly.feesapi.common.exception.FeesException;
import com.tofly.feesapi.dzfp.entity.dto.*;
import com.tofly.feesapi.dzfp.entity.EiFpkjRequest;
import com.tofly.feesapi.dzfp.entity.vo.EiFpkjRequestSelectTj;
import com.tofly.feesapi.dzfp.entity.vo.EiFpkjRequest_Excel;
import com.tofly.feesapi.dzfp.entity.vo.EiFpkjRequest_select;
import com.tofly.feesapi.dzfp.entity.vo.EiFpkjRequest_sum;
import com.tofly.feesapi.dzfp.service.EiFpkjRequestService;
import com.tofly.feesapi.file.fileconfiguration.FileStorageService;
import com.tofly.feesapi.security.util.SecurityUtils;
import com.tofly.feesapi.sfgl.entity.YySspjxx;
import com.tofly.feesapi.sfgl.mapper.YySspjxxMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/eifpkjrequest")
@Api(tags = "电子发票-电子发票汇总表接口")
public class EiFpkjRequestController {

    @Autowired
    private EiFpkjRequestService eiFpkjRequestService;
    @Autowired
    private FileStorageService fileStorageService;
    @Resource
    private YySspjxxMapper yySspjxxMapper;

    @GetMapping("/page")
    @ApiOperation(value = "分页查询-开票明细查询", tags = {"电子发票"})
    public ResultRespone<PageResult<EiFpkjRequest_select>> getEiFpkjRequestPage(@ModelAttribute PageDto pageDto, @ModelAttribute EiFpkjRequestFilter eiFpkjRequest) {
        return ResultRespone.success(eiFpkjRequestService.getPage(pageDto, eiFpkjRequest));
    }

    @GetMapping("/sum")
    @ApiOperation(value = "分页查询-开票明细查询汇总", response = EiFpkjRequest_sum.class, responseContainer = "List", tags = {"电子发票"})
    public ResultRespone<List<EiFpkjRequest_sum>> listSum(HttpServletResponse response, @ModelAttribute EiFpkjRequestFilter eiFpkjRequest) throws IOException {
        List<EiFpkjRequest_sum> list = eiFpkjRequestService.getListSum(eiFpkjRequest);
        return ResultRespone.success(list);
    }

    @GetMapping("/export")
    @ApiOperation(value = "导出开票明细Excel", tags = {"电子发票"})
    public void export(HttpServletResponse response, @ModelAttribute EiFpkjRequestFilter eiFpkjRequest) throws IOException {
        List<EiFpkjRequest_Excel> list = eiFpkjRequestService.getList(eiFpkjRequest);
        ExcleFileUtil.exportExcel(response, list, EiFpkjRequest_Excel.class, "用户开票明细.xlsx", eiFpkjRequest.getExportFields());
    }

    @GetMapping("/getFprkptjList")
    @ApiOperation(value = "发票日开票统计", tags = {"电子发票"})
    public ResultRespone<List<EiFpkjRequestSelectTj>> getFprkptjList(@ModelAttribute PageDto pageDto,
                                                                     @ModelAttribute EiFpkjRequestTjFilter filter) {
        List<EiFpkjRequestSelectTj> list = eiFpkjRequestService.getFprkptjList(filter);
        return ResultRespone.success(list);
    }

    @GetMapping("/page/fpjf")
    @ApiOperation(value = "分页查询-交付异常明细查询", tags = {"电子发票"})
    public ResultRespone<Page<EiFpkjRequest_select>> getEiFpkjRequestPageFpjf(Page page, @ModelAttribute EiFpkjRequest eiFpkjRequest) {
        eiFpkjRequest.setJfYxbz("0");//未交付
        eiFpkjRequest.setClCljg("2");//
        return ResultRespone.success(eiFpkjRequestService.page(page, Wrappers.query(eiFpkjRequest)));
    }

    @GetMapping("/sf/page")
    @ApiOperation(value = "分页查询-水费已开票明细查询", tags = {"电子发票"})
    public ResultRespone<PageResult<EiFpkjRequest_select>> getEiFpkjSfRequestPage(@ModelAttribute PageDto pageDto, @ModelAttribute EiFpkjRequestFilter eiFpkjRequest) {
        return ResultRespone.success(eiFpkjRequestService.getSfPage(pageDto, eiFpkjRequest));
    }

    @GetMapping("/fp/page")
    @ApiOperation(value = "分页查询-已开票明细查询", tags = {"电子发票"})
    public ResultRespone<PageResult<EiFpkjRequest_select>> getEiFpkjFpRequestPage(@ModelAttribute PageDto pageDto, @ModelAttribute EiFpkjRequestFilter eiFpkjRequest) {
        return ResultRespone.success(eiFpkjRequestService.getFpPage(pageDto, eiFpkjRequest));
    }

    @GetMapping("/znj/page")
    @ApiOperation(value = "分页查询-违约金已开票明细查询", tags = {"电子发票"})
    public ResultRespone<PageResult<EiFpkjRequest_select>> getEiFpkjZnjRequestPage(@ModelAttribute PageDto pageDto, @ModelAttribute EiFpkjRequestFilter eiFpkjRequest) {
        return ResultRespone.success(eiFpkjRequestService.getZnjPage(pageDto, eiFpkjRequest));
    }


    @GetMapping("/wsf/page")
    @ApiOperation(value = "分页查询-污水费已开票明细查询", tags = {"电子发票"})
    public ResultRespone<PageResult<EiFpkjRequest_select>> getEiFpkjWsfRequestPage(@ModelAttribute PageDto pageDto, @ModelAttribute EiFpkjRequestFilter eiFpkjRequest) {
        return ResultRespone.success(eiFpkjRequestService.getWsfPage(pageDto, eiFpkjRequest));
    }

    /**
     * 开票申请
     */
    @ApiOperation(value = "开票申请", tags = {"电子发票"})
    @PutMapping("/kpsq")
    public ResultRespone updateSqById(@RequestBody EiFpkjRequest_sq eiFpkjRequest_sq) {
        EiFpkjRequest eiFpkjRequest = eiFpkjRequestService.getById(eiFpkjRequest_sq.getLsbh());
        if (ObjUtil.isNull(eiFpkjRequest)) {
            throw new FeesException("开票申请失败，未找到开票申请记录！", FeesErrorCode.BUSINESS_ERROR);
        }
        if (eiFpkjRequest.getFpSfkp().equals("1")) {
            throw new FeesException("开票申请失败，该记录已申请开票！", FeesErrorCode.BUSINESS_ERROR);
        }
        if (!eiFpkjRequest.getClerkid().equals(SecurityUtils.getUserId().toString())) {
            //3系统自动扣减
            if (eiFpkjRequest.getClerkid().equals("3")) {
                eiFpkjRequest.setClerkid(SecurityUtils.getUserId().toString());
                eiFpkjRequest.setClerk(SecurityUtils.getUser().getRealName());
            } else {
                throw new FeesException("开票申请失败，你不是该记录的收费人员！", FeesErrorCode.BUSINESS_ERROR);
            }
        }
        eiFpkjRequest.setFpSfkp("1");
//        eiFpkjRequest.setJfYxbz("0");
//        eiFpkjRequest.setClLock("0");
//        eiFpkjRequest.setClCljg("0");
        return ResultRespone.success(eiFpkjRequestService.updateById(eiFpkjRequest));
    }

    @ApiOperation(value = "开票信息完善", tags = {"电子发票"})
    @PutMapping("/kpws")
    public ResultRespone updateKpwsById(@RequestBody EiFpkjRequest_Invoice eiFpkjRequest_invoice) {
        EiFpkjRequest eiFpkjRequest = eiFpkjRequestService.getById(eiFpkjRequest_invoice.getLsbh());
        if (StringUtil.isNull(eiFpkjRequest)) {
            throw new FeesException("开票信息完善失败，未找到开票申请记录！", FeesErrorCode.BUSINESS_ERROR);
        }
        if (eiFpkjRequest.getClCljg().equals("1")) {
            throw new FeesException("开票信息完善失败，该记录已完成开票！", FeesErrorCode.BUSINESS_ERROR);
        }
        if (eiFpkjRequest.getClCljg().equals("3")) {
            throw new FeesException("开票信息完善失败，该记录正在开票中！", FeesErrorCode.BUSINESS_ERROR);
        }
        BeanUtils.copyProperties(eiFpkjRequest_invoice, eiFpkjRequest);
        return ResultRespone.success(eiFpkjRequestService.updateById(eiFpkjRequest));
    }

    @ApiOperation(value = "重新交付", tags = {"电子发票"})
    @PutMapping("/cxjf")
    public ResultRespone updateCxjfById(@RequestBody EiFpkjRequest_sq eiFpkjRequest_sq) {
        EiFpkjRequest eiFpkjRequest = eiFpkjRequestService.getById(eiFpkjRequest_sq.getLsbh());
        if (StringUtil.isNull(eiFpkjRequest)) {
            throw new FeesException("重新交付失败，未找到开票申请记录！", FeesErrorCode.BUSINESS_ERROR);
        }
        return ResultRespone.success(eiFpkjRequestService.lambdaUpdate()
                .set(EiFpkjRequest::getJfYxbz, "0")
                .eq(EiFpkjRequest::getLsbh, eiFpkjRequest_sq.getLsbh())
                .update());
    }

    @ApiOperation(value = "发票删除", tags = {"电子发票"})
    @PutMapping("/fpsc")
    public ResultRespone updatefpscById(@RequestBody EiFpkjRequest_sq eiFpkjRequest_sq) {
        EiFpkjRequest eiFpkjRequest = eiFpkjRequestService.getById(eiFpkjRequest_sq.getLsbh());
        if (StringUtil.isNull(eiFpkjRequest)) {
            throw new FeesException("发票删除失败，未找到开票申请记录！", FeesErrorCode.BUSINESS_ERROR);
        }
        if ("2".equals(eiFpkjRequest.getClCljg()) && "4".equals(eiFpkjRequest.getClCljg())) {
            throw new FeesException("发票删除失败，不是开票失败的记录！", FeesErrorCode.BUSINESS_ERROR);
        }
        return ResultRespone.success(eiFpkjRequestService.lambdaUpdate()
                .set(EiFpkjRequest::getClCljg, "9")
                .set(EiFpkjRequest::getClLock, "0")
                .eq(EiFpkjRequest::getLsbh, eiFpkjRequest_sq.getLsbh())
                .update());
    }

    @ApiOperation(value = "开票重试", tags = {"电子发票"})
    @PutMapping("/kpcs")
    public ResultRespone updateKpcsById(@RequestBody EiFpkjRequest_sq eiFpkjRequest_sq) {
        EiFpkjRequest eiFpkjRequest = eiFpkjRequestService.getById(eiFpkjRequest_sq.getLsbh());
        if (StringUtil.isNull(eiFpkjRequest)) {
            throw new FeesException("开票重试失败，未找到开票申请记录！", FeesErrorCode.BUSINESS_ERROR);
        }
        if (eiFpkjRequest.getClCljg().equals("6")) {
            throw new FeesException("提示：该条票据信息正在获取红字确认单中，请勿重复开票！", FeesErrorCode.BUSINESS_ERROR);
        }
        if (eiFpkjRequest.getClCljg().equals("3")) {
            throw new FeesException("提示：该条票据信息正在开票中，请勿重复开票！", FeesErrorCode.BUSINESS_ERROR);
        }
        if (eiFpkjRequest.getClCljg().equals("1")) {
            throw new FeesException("提示：该条票据信息已开票，请勿重复开票！", FeesErrorCode.BUSINESS_ERROR);
        }
        return ResultRespone.success(eiFpkjRequestService.lambdaUpdate()
                .set(EiFpkjRequest::getClCljg, "0")
                .set(EiFpkjRequest::getClLock, "0")
                .eq(EiFpkjRequest::getLsbh, eiFpkjRequest_sq.getLsbh())
                .update()
        );
    }

    @ApiOperation(value = "发票下载PDF", tags = {"电子发票"})
    @PostMapping("/fpdown")
    @SneakyThrows
    public void updateFpdownById(@RequestBody EiFpkjRequest_sq eiFpkjRequest_sq, HttpServletResponse response, HttpServletRequest request) {
        EiFpkjRequest eiFpkjRequest = eiFpkjRequestService.getById(eiFpkjRequest_sq.getLsbh());
        if (!eiFpkjRequest.getClCljg().equals("1")) {
            throw new FeesException("提示：该条票据信息发票未开出，不支持发票下载！", FeesErrorCode.BUSINESS_ERROR);
        }
        if (StringUtil.isEmpty(eiFpkjRequest.getPdfurl())) {
            throw new FeesException("提示：该条票据信息发票下载地址不存在，不支持发票下载！", FeesErrorCode.BUSINESS_ERROR);
        }
        byte[] data;
        if (eiFpkjRequest.getPdfurl().startsWith("https://inv.jss.com.cn")) {
            URLConnection connection = new URL(eiFpkjRequest.getPdfurl()).openConnection();
            connection.setConnectTimeout(5000); // 5秒连接超时
            connection.setReadTimeout(30000); // 30秒读取超时
            try (InputStream inputStream = connection.getInputStream();
                 ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
                data = outputStream.toByteArray();
            } catch (IOException e) {
                throw new FeesException("提示：发票下载失败，请稍后重试！", FeesErrorCode.BUSINESS_ERROR);
            }
        } else {
            data = fileStorageService.getByteDataforFile(eiFpkjRequest.getPdfurl());
        }
        response.reset();
        response.setCharacterEncoding("UTF-8");
        String userAgent = request.getHeader("User-Agent");
        String formFileName = eiFpkjRequest.getJfPdffilename();
        if (StringUtil.isEmpty(formFileName)) {
            formFileName = UUID.randomUUID().toString().replace("-", "").toUpperCase() + ".pdf";
        }
        if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
            // 针对IE或者以IE为内核的浏览器：
            formFileName = URLEncoder.encode(formFileName, "UTF-8");
        } else {
            // 非IE浏览器的处理：
            formFileName = new String(formFileName.getBytes("UTF-8"), "ISO-8859-1");
        }
        response.setHeader("Content-Disposition", String.format("attachment; filename=%s", formFileName));
        response.addHeader("Content-Length", "" + data.length);
        response.setContentType("application/octet-stream; charset=UTF-8");
        response.setHeader("content-type", "application/octet-stream; charset=UTF-8");
        try {
            IOUtil.write(response.getOutputStream(), Boolean.TRUE, data);
        } catch (IOException e) {
            //log.error(e.getMessage());
            e.getMessage();
        }
    }

    @ApiOperation(value = "发票冲红", tags = {"电子发票"})
    @PutMapping("/fpch")
    public ResultRespone<Boolean> updateFpchById(@RequestBody EiFpkjRequest_sq eiFpkjRequest_sq) {
        EiFpkjRequest eiFpkjRequest = eiFpkjRequestService.getById(eiFpkjRequest_sq.getLsbh());
        if (eiFpkjRequest.getZfZfbz().equals("1") || eiFpkjRequest.getZfZfbz().equals("2")) {
            throw new FeesException("提示：该条票据信息发票已冲红，不支持发票冲红！", FeesErrorCode.BUSINESS_ERROR);
        }
        if (eiFpkjRequest.getIsykfp().equals("1")) {
            LambdaQueryWrapper<YySspjxx> wrapper = Wrappers.<YySspjxx>lambdaQuery()
                    .eq(YySspjxx::getFpglh, eiFpkjRequest.getSfid())
                    .eq(YySspjxx::getChbz, "0");
            long count = yySspjxxMapper.selectCount(wrapper);
            if (count > 0) {
                throw new FeesException("提示：该条票据信息发票是预开发票已销账，发票冲红需先进行票据冲红！", FeesErrorCode.BUSINESS_ERROR);
            }
        }
        boolean result = eiFpkjRequestService.dzfpch(eiFpkjRequest);
        return result ? ResultRespone.success(true, "发票冲红成功") : ResultRespone.failed(false, "发票冲红失败");
    }

    @ApiOperation(value = "报装开票信息添加", tags = {"电子发票"})
    @PostMapping("/bzkpxxtj")
    public ResultRespone bzkpxxtj(@RequestBody EiFpkjRequest eiFpkjRequest) {
        String result = eiFpkjRequestService.bzkpxxtj(eiFpkjRequest);
        return ResultRespone.success(result);
    }

    @ApiOperation(value = "根据流水编号查询开票信息")
    @GetMapping("/{lsbh}")
    public ResultRespone<EiFpkjRequest> getEiFpkjRequestById(@PathVariable String lsbh) {
        EiFpkjRequest eiFpkjRequest = eiFpkjRequestService.getById(lsbh);
        return ResultRespone.success(eiFpkjRequest);
    }

    @ApiOperation(value = "电子发票申请", tags = {"票据管理"})
    @PostMapping("/dzfpsq")
    public ResultRespone dzfpsq(@RequestBody EiFpkjRequest_dzfpsq eifpkjrequest_dzfpsq) {
        boolean result = eiFpkjRequestService.dzfpsq(eifpkjrequest_dzfpsq);
        if (result) {
            return ResultRespone.success("电子发票申请成功！");
        }
        return ResultRespone.failed("电子发票申请失败！");
    }

}
