package com.trs.digital.module.manager.controller.admin.search.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.extra.ftp.Ftp;
import cn.hutool.extra.ssh.Sftp;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.trs.digital.framework.common.pojo.CommonResult;
import com.trs.digital.framework.common.pojo.PageParam;
import com.trs.digital.framework.common.pojo.PageResult;
import com.trs.digital.framework.common.util.io.FileUtils;
import com.trs.digital.framework.common.util.object.BeanUtils;
import com.trs.digital.framework.excel.core.util.ExcelUtils;
import com.trs.digital.framework.operatelog.core.annotations.OperateLog;

import com.trs.digital.module.manager.controller.admin.search.service.SearchService;
import com.trs.digital.module.manager.controller.admin.search.vo.AdvSearchReqVO;
import com.trs.digital.module.manager.controller.admin.search.vo.AdvSearchSaveLabelsReqVO;
import com.trs.digital.module.manager.controller.admin.search.vo.AdvSearchSaveLabelsReqVO2;
import com.trs.digital.module.manager.controller.admin.search.vo.DigSearchRespVO;
import com.trs.digital.module.manager.dal.dataobject.digftp.DigFtpSourceDO;
import com.trs.digital.module.system.dal.dataobject.dept.DeptDO;
import com.xingyuv.http.util.StringUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.beans.factory.annotation.Value;

import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import java.io.*;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.util.*;

import static com.trs.digital.framework.common.pojo.CommonResult.success;
import static com.trs.digital.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;

@Tag(name = "高级检索")
@RestController
@RequestMapping("/adv/search")
@PermitAll
@Slf4j
public class AdvSearchController {

    @Resource
    SearchService searchService;

    @Value("${sourcename.ftp1.host}")
    private String host_1;
    @Value("${sourcename.ftp1.ftpuser}")
    private String user_1;
    @Value("${sourcename.ftp1.password}")
    private String pwd_1;

    @Value("${sourcename.ftp2.host}")
    private String host_2;
    @Value("${sourcename.ftp2.ftpuser}")
    private String user_2;
    @Value("${sourcename.ftp2.password}")
    private String pwd_2;

    @Value("${ssh.remoteHost}")
    private String remoteHost;

    @Value("${ssh.port}")
    private Integer port;

    @Value("${ssh.username}")
    private String username;

    @Value("${ssh.password}")
    private String password;

    /**
     * 机密级
     * @param reqVO
     * @return
     */
    @CrossOrigin
    @Operation(summary = "检索")
    @PreAuthorize("@ss.hasPermission('adv/search:ftp1')")
    @RequestMapping("/ftp1")
    public CommonResult<PageResult<Map<String, Object>>> ftp1(@RequestBody AdvSearchReqVO reqVO) {
        reqVO.setMetaId(2l);
        return CommonResult.success(searchService.select(reqVO));
    }

    /**
     * 绝密级
     * @param reqVO
     * @return
     */
    @CrossOrigin
    @Operation(summary = "检索")
    @PreAuthorize("@ss.hasPermission('adv/search:ftp2')")
    @RequestMapping("/ftp2")
    public CommonResult<PageResult<Map<String, Object>>> ftp2(@RequestBody AdvSearchReqVO reqVO) {
        reqVO.setMetaId(1l);
        return CommonResult.success(searchService.select(reqVO));
    }

    /**
     * 用户级
     * @param reqVO
     * @return
     */
    @CrossOrigin
    @Operation(summary = "检索")
    @PreAuthorize("@ss.hasPermission('adv/search:ftp3')")
    @RequestMapping("/ftp3")
    public CommonResult<PageResult<Map<String, Object>>> ftp3(@RequestBody AdvSearchReqVO reqVO) {
        reqVO.setMetaId(3l);
        return CommonResult.success(searchService.select(reqVO));
    }

    @CrossOrigin
    @Operation(summary = "检索")
    @PermitAll
    @RequestMapping("/getlist")
    public CommonResult<PageResult<Map<String, Object>>> getlist(@RequestBody AdvSearchReqVO reqVO) {
        reqVO.setMetaId(1l);
        reqVO.setIsAip(1);
        return CommonResult.success(searchService.select(reqVO));
    }

    @CrossOrigin
    @Operation(summary = "检索-修改标签")
//    @PreAuthorize("@ss.hasPermission('adv/search:ftp1')")
    @PermitAll
    @RequestMapping("/update")
    public CommonResult<Boolean> update(@RequestBody AdvSearchSaveLabelsReqVO reqVO) {
        searchService.update(reqVO);
        return success(true);
    }

    //点赞量
    @CrossOrigin
    @Operation(summary = "检索-访问量")
//    @PreAuthorize("@ss.hasPermission('adv/search:ftp1')")
    @PermitAll
    @RequestMapping("/visit")
    public CommonResult<Boolean> visit(@RequestBody AdvSearchSaveLabelsReqVO reqVO) {
        searchService.visit(reqVO);
        return success(true);
    }

    @CrossOrigin
    @Operation(summary = "检索-收藏量")
//    @PreAuthorize("@ss.hasPermission('adv/search:ftp1')")
    @PermitAll
    @RequestMapping("/collect")
    public CommonResult<Boolean> collect(@RequestBody AdvSearchSaveLabelsReqVO reqVO) {
        searchService.collect(reqVO);
        return success(true);
    }

    @Operation(summary = "取消收藏")
//    @PreAuthorize("@ss.hasPermission('adv/search:ftp1')")
    @PermitAll
    @RequestMapping("/uncollect")
    public CommonResult<Boolean> uncollect(@RequestBody AdvSearchSaveLabelsReqVO reqVO) {
        searchService.uncollect(reqVO);
        return success(true);
    }

    @CrossOrigin
    @Operation(summary = "收藏量列表")
//    @PreAuthorize("@ss.hasPermission('adv/search:ftp2')")
    @PermitAll
    @RequestMapping("/collectlist")
    public CommonResult<PageResult<Map<String, Object>>> collectlist(@RequestBody AdvSearchReqVO reqVO) {
        reqVO.setMetaId(1l);
        return CommonResult.success(searchService.collectlist(reqVO));
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出收藏列表 Excel")
//    @PreAuthorize("@ss.hasPermission('adv/search:ftp2')")
    @PermitAll
    @OperateLog(type = EXPORT)
    public void exportDigFtpSourceExcel(AdvSearchReqVO reqVO,
                                        HttpServletResponse response) throws IOException {
        List collectselectlist = searchService.collectselectlist(reqVO);
        // 导出 Excel
        ExcelUtils.write(response, "收藏列表.xls", "数据", DigSearchRespVO.class,
                BeanUtils.toBean(collectselectlist, DigSearchRespVO.class));
    }

    @CrossOrigin
    @Operation(summary = "检索-下载")
    //@PreAuthorize("@ss.hasPermission('adv/search:ftp1')")
    @PermitAll
    @RequestMapping("/download")
    public byte[] download(@RequestBody AdvSearchSaveLabelsReqVO reqVO) {
        String filePath = reqVO.getFilePath();
        String sourcename = reqVO.getSourcename();
        Ftp ftp;

        if ("ftp02".equals(sourcename)) {
            ftp = new Ftp(host_2, 21, user_2, pwd_2);
        } else {
            ftp = new Ftp(host_1, 21, user_1, pwd_1);
        }

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            ftp.reconnectIfTimeout();
//            String filepath = filePath.substring(0, filePath.lastIndexOf("/"));
//            String filename = filePath.substring(filePath.lastIndexOf("/") + 1);
            // 转换路径分隔符为 FTP 格式
            String ftpPath = filePath.replace("\\", "/").substring(filePath.indexOf("/") + 1);
            String filepath = ftpPath.substring(0, ftpPath.lastIndexOf("/"));
            String filename = ftpPath.substring(ftpPath.lastIndexOf("/") + 1);
            ftp.download(filepath, filename, out);

//            HttpHeaders headers = new HttpHeaders();
//            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"");
//            headers.add(HttpHeaders.CONTENT_TYPE, "application/octet-stream");

//            return new ResponseEntity<>(out.toByteArray(), headers, HttpStatus.OK);
            return out.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
//            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
            return null;
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    //点赞量
    @CrossOrigin
    @Operation(summary = "检索-点击量")
//    @PreAuthorize("@ss.hasPermission('adv/search:ftp1')")
    @PermitAll
    @RequestMapping("/click")
    public CommonResult<Boolean> click(@RequestBody AdvSearchSaveLabelsReqVO reqVO) {
        searchService.clicklog(reqVO);
        return success(true);
    }

    @CrossOrigin
    @Operation(summary = "检索-搜索量")
//    @PreAuthorize("@ss.hasPermission('adv/search:ftp1')")
    @PermitAll
    @RequestMapping("/searchlog")
    public CommonResult<Boolean> search(@RequestBody AdvSearchSaveLabelsReqVO reqVO) {
        searchService.searchlog(reqVO);
        return success(true);
    }

    @CrossOrigin
    @Operation(summary = "首页面板")
//    @PreAuthorize("@ss.hasPermission('adv/search:ftp1')")
    @PermitAll
    @RequestMapping("/indexdata")
    public CommonResult<JSONObject> indexdata() {
        JSONObject indexdata = searchService.indexdata();
        return success(indexdata);
    }

    @CrossOrigin
    @Operation(summary = "首页面板2")
//    @PreAuthorize("@ss.hasPermission('adv/search:ftp1')")
    @PermitAll
    @RequestMapping("/indexdataline")
    public CommonResult<JSONObject> indexdataline() {
        JSONObject indexdataline = searchService.indexdataline();
        return success(indexdataline);
    }

    @CrossOrigin
    @Operation(summary = "部门列表")
    @RequestMapping("/deptlist")
    public CommonResult<List<DeptDO>> deptlist(@RequestBody AdvSearchReqVO reqVO) {
        return success(searchService.deptlist(reqVO));
    }

    @CrossOrigin
    @Operation(summary = "稿件分配给部门列表")
    @RequestMapping("/docdeptlist")
    public CommonResult<JSONArray> docdeptlist(@RequestBody AdvSearchReqVO reqVO) {
        return success(searchService.docdeptlist(reqVO));
    }


    @CrossOrigin
    @Operation(summary = "分配待办")
//    @PreAuthorize("@ss.hasRole('jd_daiban_admin')")
    @PermitAll
    @RequestMapping("/daiban")
    public CommonResult<Boolean> daiban(@RequestBody AdvSearchSaveLabelsReqVO2 reqVO) {
        searchService.daiban(reqVO);
        return success(true);
    }

    @CrossOrigin
    @Operation(summary = "处理待办")
    @RequestMapping("/dealdaiban")
    public CommonResult<Boolean> dealdaiban(@RequestBody AdvSearchSaveLabelsReqVO2 reqVO) {
        searchService.dealdaiban(reqVO);
        return success(true);
    }

/*    @Operation(summary = "取消待办")
    @PreAuthorize("@ss.hasPermission('adv/search:ftp1')")
    @RequestMapping("/undaiban")
    public CommonResult<Boolean> undaiban(@RequestBody AdvSearchSaveLabelsReqVO2 reqVO) {
        searchService.undaiban(reqVO);
        return success(true);
    }*/

    @CrossOrigin
    @Operation(summary = "待办列表")
//    @PreAuthorize("@ss.hasPermission('adv/search:ftp2')")
    @PermitAll
    @RequestMapping("/daibanlist")
    public CommonResult<PageResult<Map<String, Object>>> daibanlist(@RequestBody AdvSearchReqVO reqVO) {
        reqVO.setMetaId(1l);
        return CommonResult.success(searchService.daibanlist(reqVO));
    }

    @GetMapping("/export-excel-daiban")
    @Operation(summary = "导出待办列表 Excel")
//    @PreAuthorize("@ss.hasPermission('adv/search:ftp2')")
    @PermitAll
    @OperateLog(type = EXPORT)
    public void exportdaibanExcel(AdvSearchReqVO reqVO,
                                        HttpServletResponse response) throws IOException {
        List collectselectlist = searchService.daibanselectlist(reqVO);
        // 导出 Excel
        ExcelUtils.write(response, "待办列表.xls", "数据", DigSearchRespVO.class,
                BeanUtils.toBean(collectselectlist, DigSearchRespVO.class));
    }


    /**
     * 创建 SFTP Session
     */
    private Session createSftpSession(String host, int port, String username, String password) throws JSchException {
        JSch jsch = new JSch();
        Session session = jsch.getSession(username, host, port);
        session.setPassword(password);
        session.setConfig("StrictHostKeyChecking", "no"); // 禁用主机验证
        session.connect();
        return session;
    }

    @CrossOrigin
    @Operation(summary = "检索-下载")
//    @PreAuthorize("@ss.hasPermission('adv/search:ftp1')")
    @PermitAll
    @RequestMapping("/download2")
    public byte[] download2(@RequestBody AdvSearchSaveLabelsReqVO reqVO) {
        String filePath = reqVO.getFilePath();
        Ftp ftp;

        ftp = new Ftp(host_1, 21, user_1, pwd_1);

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            ftp.reconnectIfTimeout();
            String filepath = filePath.substring(0, filePath.lastIndexOf("/"));
            String filename = filePath.substring(filePath.lastIndexOf("/") + 1);
            ftp.download(filepath, filename, out);

//            HttpHeaders headers = new HttpHeaders();
//            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"");
//            headers.add(HttpHeaders.CONTENT_TYPE, "application/octet-stream");

//            return new ResponseEntity<>(out.toByteArray(), headers, HttpStatus.OK);
            return out.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
//            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
            return null;
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }




    @CrossOrigin
    @Operation(summary = "检索-下载")
    //@PreAuthorize("@ss.hasPermission('adv/search:ftp1')")
    @PermitAll
    @RequestMapping("/download3")
    public void download3(@RequestParam("filePath") String filePath,@RequestParam("sourcename") String sourcename,HttpServletResponse response) throws IOException {
//        String filePath = reqVO.getFilePath();
//        String sourcename = reqVO.getSourcename();
        String host = "";
        String user = "";
        String pass = "";

        if ("ftp02".equals(sourcename)) {
            host = host_1;
            user = user_1;
            pass = pwd_1;
        } else {
            host = host_2;
            user = user_2;
            pass = pwd_2;
        }
        FTPClient client = new FTPClient();
        client.setControlEncoding("UTF-8");
        client.connect(host, 21);
        if (FTPReply.isPositiveCompletion(client.getReplyCode())) {
            String userName = user;
            String password = pass;
            if (StringUtil.isEmpty(userName)) {
                userName = "anonymous"; //$NON-NLS-1$
                password = ""; //$NON-NLS-1$
            }
            if (!client.login(userName, password)) {
                throw new IOException("user name or password is not correct, please check it."); //$NON-NLS-1$
            }
            client.setBufferSize(1024 * 1024);
            client.setFileType(FTP.BINARY_FILE_TYPE);
        }
        String ftpPath = filePath.replace("\\", "/").substring(filePath.indexOf("/") + 1);
        String filepath = ftpPath.substring(0, ftpPath.lastIndexOf("/"));
        String filename = ftpPath.substring(ftpPath.lastIndexOf("/") + 1);
        InputStream inputStream = client.retrieveFileStream(filePath);

        // 设置响应头，指示浏览器触发下载
        // 设置响应头部，确保浏览器下载文件时显示正确的文件名
        response.setContentType("application/octet-stream");
        response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("Expires", 0);

        // 对文件名进行 URL 编码，确保中文和特殊字符正常显示
        String encodedFilename = URLEncoder.encode(filename, "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFilename + "\"");

        // 获取输出流并将文件写入响应流
        try (OutputStream outputStream = response.getOutputStream()) {
            byte[] buffer = new byte[1024];
            int bytesRead;

            // 将文件内容从 FTP 输入流写入 HTTP 响应流
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭输入流和 FTP 连接
            inputStream.close();
            client.logout();
            client.disconnect();
        }
    }


/*    @CrossOrigin
    @Operation(summary = "检索-下载")
    //@PreAuthorize("@ss.hasPermission('adv/search:ftp1')")
    @PermitAll
    @RequestMapping("/download4")
    public byte[] download4(@RequestBody AdvSearchSaveLabelsReqVO reqVO) throws IOException  {

        String filePath = reqVO.getFilePath();
        String sourcename = reqVO.getSourcename();
        String host = "";
        String user = "";
        String pass = "";

        if ("ftp02".equals(sourcename)||"ftp2".equals(sourcename)) {
            host = host_1;
            user = user_1;
            pass = pwd_1;
        } else {
            host = host_2;
            user = user_2;
            pass = pwd_2;
        }
        // 创建 FTP 客户端
        FTPClient client = new FTPClient();
        client.setControlEncoding("UTF-8");
        client.connect(host, 21);
        if (FTPReply.isPositiveCompletion(client.getReplyCode())) {
            String userName = user;
            String password = pass;
            if (StringUtil.isEmpty(userName)) {
                userName = "anonymous"; //$NON-NLS-1$
                password = ""; //$NON-NLS-1$
            }
            if (!client.login(userName, password)) {
                throw new IOException("user name or password is not correct, please check it."); //$NON-NLS-1$
            }
            client.setBufferSize(1024 * 1024);
            client.setFileType(FTP.BINARY_FILE_TYPE);
        }
        // 获取文件内容
        String ftpPath = filePath.replace("\\", "/").substring(filePath.indexOf("/") + 1);
        String filepath = ftpPath.substring(0, ftpPath.lastIndexOf("/"));
        String filename = ftpPath.substring(ftpPath.lastIndexOf("/") + 1);
        InputStream inputStream = client.retrieveFileStream(filePath);

        // 使用 ByteArrayOutputStream 将文件内容写入字节数组
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int bytesRead;

        try {
            //
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                byteArrayOutputStream.write(buffer, 0, bytesRead);
            }
        } finally {
            // 关闭流和FTP连接
            inputStream.close();
            client.logout();
            client.disconnect();
        }

        // 获取字节数组
        return byteArrayOutputStream.toByteArray();
    }*/


    @CrossOrigin
    @Operation(summary = "检索-下载")
    //@PreAuthorize("@ss.hasPermission('adv/search:ftp1')")
    @PermitAll
    @RequestMapping("/download4")
    public byte[] download4(@RequestBody AdvSearchSaveLabelsReqVO reqVO) throws IOException  {

        String filePath = reqVO.getFilePath();
        /*String sourcename = reqVO.getSourcename();
        String host = "";
        String user = "";
        String pass = "";

        if ("ftp02".equals(sourcename)||"ftp2".equals(sourcename)) {
            host = host_1;
            user = user_1;
            pass = pwd_1;
        } else {
            host = host_2;
            user = user_2;
            pass = pwd_2;
        }*/
        // 创建 FTP 客户端
        /*FTPClient client = new FTPClient();
        client.setControlEncoding("UTF-8");
        client.connect(host, 21);
        if (FTPReply.isPositiveCompletion(client.getReplyCode())) {
            String userName = user;
            String password = pass;
            if (StringUtil.isEmpty(userName)) {
                userName = "anonymous"; //$NON-NLS-1$
                password = ""; //$NON-NLS-1$
            }
            if (!client.login(userName, password)) {
                throw new IOException("user name or password is not correct, please check it."); //$NON-NLS-1$
            }
            client.setBufferSize(1024 * 1024);
            client.setFileType(FTP.BINARY_FILE_TYPE);
        }*/
        // 获取文件内容
//        String ftpPath = filePath.replace("\\", "/").substring(filePath.indexOf("/") + 1);
        String ftpPath = "/ftp"+filePath;
        Sftp sftp = new Sftp(remoteHost, port, username, password);
        File destFile = FileUtils.createTempFile();
        sftp.download(ftpPath, destFile);
        /*String filepath = ftpPath.substring(0, ftpPath.lastIndexOf("/"));
        String filename = ftpPath.substring(ftpPath.lastIndexOf("/") + 1);
        InputStream inputStream = client.retrieveFileStream(filePath);

        // 使用 ByteArrayOutputStream 将文件内容写入字节数组
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int bytesRead;

        try {
            //
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                byteArrayOutputStream.write(buffer, 0, bytesRead);
            }
        } finally {
            // 关闭流和FTP连接
            inputStream.close();
            client.logout();
            client.disconnect();
        }*/

        // 获取字节数组
//        return byteArrayOutputStream.toByteArray();
        return FileUtil.readBytes(destFile);
    }



}
