package com.zehong.web.controller.transaction;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zehong.common.annotation.Log;
import com.zehong.common.core.controller.BaseController;
import com.zehong.common.core.domain.AjaxResult;
import com.zehong.common.core.exception.BusinessException;
import com.zehong.common.core.page.TableDataInfo;
import com.zehong.common.enums.BusinessType;
import com.zehong.common.utils.StringUtils;
import com.zehong.common.utils.poi.ExcelUtil;
import com.zehong.system.domain.TTradeProject;
import com.zehong.system.domain.vo.TTradeProjectExportVo;
import com.zehong.system.service.ITTradeProjectService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 交易项目Controller
 *
 * @author zehong
 * @date 2023-06-08
 */
@RestController
@RequestMapping("/trade/project")
public class TTradeProjectController extends BaseController
{
    @Autowired
    private ITTradeProjectService tTradeProjectService;

    /**
     * 查询交易项目列表
     */
    @PreAuthorize("@ss.hasPermi('trade:project:list')")
    @GetMapping("/list")
    public TableDataInfo list(TTradeProject tTradeProject)
    {
        startPage();
        List<TTradeProject> list = tTradeProjectService.selectTTradeProjectList(tTradeProject);
        return getDataTable(list);
    }

    @GetMapping("/selectTTradeProjectListByRoles")
    public TableDataInfo selectTTradeProjectListByRoles(TTradeProject tTradeProject){
        startPage();
        List<TTradeProject> list = tTradeProjectService.selectTTradeProjectListByRoles(tTradeProject);
        return getDataTable(list);
    }

    /**
     * 导出交易项目列表
     */
    @PreAuthorize("@ss.hasPermi('trade:project:export')")
    @Log(title = "交易项目", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(TTradeProject tTradeProject)
    {
        startPage();
        List<TTradeProject> list = tTradeProjectService.selectTTradeProjectListByRoles(tTradeProject);
        List<TTradeProjectExportVo> listVo = list.stream().map(item ->{
            TTradeProjectExportVo vo = new TTradeProjectExportVo();
            BeanUtils.copyProperties(item,vo);
            return vo;
        }).collect(Collectors.toList());
        ExcelUtil<TTradeProjectExportVo> util = new ExcelUtil<>(TTradeProjectExportVo.class);
        return util.exportExcel(listVo, "交易项目数据");
    }

    /**
     * 获取交易项目详细信息
     */
    @PreAuthorize("@ss.hasPermi('trade:project:query')")
    @GetMapping(value = "/{tradeId}")
    public AjaxResult getInfo(@PathVariable("tradeId") Long tradeId)
    {
        return AjaxResult.success(tTradeProjectService.selectTTradeProjectById(tradeId));
    }

    /**
     * 新增交易项目
     */
    @PreAuthorize("@ss.hasPermi('trade:project:add')")
    @Log(title = "交易项目", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody TTradeProject tTradeProject)
    {
        int rows = tTradeProjectService.insertTTradeProject(tTradeProject);
        if(rows >0){
            return AjaxResult.success(tTradeProject);
        }
        return AjaxResult.error();
    }

    /**
     * 修改交易项目
     */
    @PreAuthorize("@ss.hasPermi('trade:project:edit')")
    @Log(title = "交易项目", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody TTradeProject tTradeProject)
    {
        return toAjax(tTradeProjectService.updateTTradeProject(tTradeProject));
    }

    /**
     * 删除交易项目
     */
    @PreAuthorize("@ss.hasPermi('trade:project:remove')")
    @Log(title = "交易项目", businessType = BusinessType.DELETE)
	@DeleteMapping("/{tradeIds}")
    public AjaxResult remove(@PathVariable Long[] tradeIds)
    {
        return toAjax(tTradeProjectService.deleteTTradeProjectByIds(tradeIds));
    }

    /**
     * 交易结算
     * @param tTradeProject
     * @return
     */
    @PostMapping("/settlementTrade")
    public AjaxResult settlementTrade(@RequestBody TTradeProject tTradeProject){
        return toAjax(tTradeProjectService.settlementTrade(tTradeProject));
    }

    @GetMapping("/getIncomeOrPayableList")
    public TableDataInfo getIncomeOrPayableList(TTradeProject tTradeProject)
    {
        startPage();
        List<TTradeProject> list = tTradeProjectService.getIncomeOrPayableList(tTradeProject);
        return getDataTable(list);
    }

    /**
     * 手动结算尾款
     * @param tTradeProject
     * @return
     */
    @PostMapping("/settlePendingPayment")
    public AjaxResult settlePendingPayment(@RequestBody TTradeProject tTradeProject) {
        return toAjax(tTradeProjectService.settlePendingPayment(tTradeProject));
    }

    @GetMapping("/batchDownload/{tradeId}")
    public void batchDownload(@PathVariable("tradeId") Long tradeId, HttpServletResponse response){
        try {
            TTradeProject tradeProject = tTradeProjectService.selectTTradeProjectById(tradeId);
            String attachment = tradeProject.getAttachmentUrl();
            List<JSONObject> attachmentJson = JSON.parseArray(attachment,JSONObject.class);
            // 清空response
            response.reset();
            // 设置response的Header
            //response.setCharacterEncoding("UTF-8");
            //Content-Disposition的作用：告知浏览器以何种方式显示响应返回的文件，用浏览器打开还是以附件的形式下载到本地保存
            //attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.mp3"
            // filename表示文件的默认名称，因为网络传输只支持URL编码的相关支付，因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
            // 它会同时设置服务器和客户端都使用 UTF-8 字符集，还设置了响应头
            // 此方法一定要在获取流对象之前调用才有效
            response.setContentType("text/html; charset=UTF-8");
            //设置响应格式，已文件流的方式返回给前端。
            response.setContentType("application/octet-stream");
            // 告知浏览器文件的大小
            OutputStream outputStream = response.getOutputStream();
            if(attachmentJson.size()>1){
                //打包下载
                toZip(response,attachmentJson);
                return;

            }
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(getFileName(attachmentJson.get(0)), "UTF-8"));
            URLConnection file = new URL(getFileUrl(attachmentJson.get(0).getString("url"))).openConnection();
            InputStream is = file.getInputStream();
            // 1K的数据缓冲
            byte[] bs = new byte[1024];
            // 读取到的数据长度
            int len;
            // 输出的文件流
            while ((len = is.read(bs)) != -1) {
                outputStream.write(bs, 0, len);
            }
            // 完毕，关闭所有链接
            outputStream.close();
            is.close();
            outputStream.flush();

        } catch (Exception e) {
            logger.error("附件下载失败：" + e);
            throw new BusinessException("附件下载失败！");
        }

    }

    /**
     * 大压缩包下载
     * @param response 返回
     * @param attachmentJson 附件信息
     * @throws IOException
     */
    private void toZip(HttpServletResponse response,List<JSONObject> attachmentJson) throws IOException {
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("附件-"+ new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".zip", "UTF-8"));
        ZipOutputStream  zipOutputStream = new ZipOutputStream(response.getOutputStream());
        for(JSONObject am : attachmentJson){
               URLConnection file = new URL(getFileUrl(am.getString("url"))).openConnection();
               InputStream is = file.getInputStream();
               //设置压缩包内文件的名称
               zipOutputStream.putNextEntry(new ZipEntry(getFileName(am)));
               int size;
               byte[] buffer = new byte[4096];
               while ((size = is.read(buffer)) > 0) {
                   zipOutputStream.write(buffer, 0, size);
               }
               zipOutputStream.closeEntry();
               is.close();
           }
            zipOutputStream.close();
            zipOutputStream.flush();
    }

    /**
     * 获取文件名称
     * @param fileInfo 附件信息
     * @return
     */
    private String getFileName(JSONObject fileInfo){
        String name = fileInfo.getString("name");
        if(StringUtils.isNotEmpty(name)){
            return name;
        }

        String[] urlStr = fileInfo.getString("url").split("/");
        return urlStr[urlStr.length - 1];
    }

    private String getFileUrl(String url){
        return url.contains("36.139.131.221:8904") ? url.replace("36.139.131.221:8904","127.0.0.1:8668") : url;
    }
}
