package jnpf.doclibrary.controller;

import cn.xuyanwu.spring.file.storage.FileInfo;
import com.github.pagehelper.PageInfo;
import jnpf.base.ActionResult;
import jnpf.base.vo.PageListVO;
import jnpf.doclibrary.service.SpaceService;
import jnpf.entity.Information;
import jnpf.exception.HandleException;
import jnpf.model.doclibrary.dto.*;
import jnpf.model.doclibrary.vo.*;
import jnpf.util.CustomTenantUtil;
import jnpf.util.FtbUtil;
import jnpf.util.NoDataSourceBind;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * 共享空间控制器
 *
 * @author yanwenfu
 * @create 2023-07-20
 */
@RestController
@RequestMapping(value = "/doclibrary")
public class SpaceController {

    @Resource
    private SpaceService spaceService;
    @Resource
    private CustomTenantUtil customTenantUtil;

    /**
     * 点击共享空间/空间/文件夹查询下面的所有内容
     * @param pid 父id
     * @return jnpf.base.ActionResult<jnpf.model.doclibrary.vo.MiniInformationVo>
     */
    @GetMapping(value = "/fileList/{pid}")
    public ActionResult<List<MiniInformationVo>> getMyResourceList(@PathVariable(value = "pid") String pid) {

        List<MiniInformationVo> list = spaceService.getMyResourceList(pid);
        return ActionResult.success(list);
    }

    /**
     * 点击共享空间/空间/文件夹查询下面的所有内容(分页)
     * @param pid 父id
     * @param queryDto 查询条件
     * @return jnpf.base.ActionResult<jnpf.model.doclibrary.vo.MiniInformationVo>
     */
    @GetMapping(value = "/filePage/{pid}")
    public ActionResult<PageListVO<MiniInformationVo>> getMyResourcePage(@PathVariable(value = "pid") String pid, InformationQueryDto queryDto) {

        PageInfo<MiniInformationVo> page = spaceService.getMyResourcePage(pid, queryDto);
        return ActionResult.page(page.getList(), FtbUtil.getPagination(page));
    }

    /**
     * 查询空间/文件夹/文件id占用空间的大小
     * @param id 空间/文件夹/文件id
     * @return jnpf.base.ActionResult<jnpf.model.doclibrary.vo.SpaceVo>
     */
    @GetMapping(value = "/information/space/{id}")
    public ActionResult<SpaceVo> getInformationSpace(@PathVariable(value = "id") String id) {

        SpaceVo space = spaceService.getInformationSpace(id);
        return ActionResult.success(space);
    }

    /**
     * 查询空间/文件夹/文件关联的成员
     * @param id 空间/文件夹/文件id
     * @return jnpf.base.ActionResult<java.util.List<jnpf.model.doclibrary.vo.UserInfoVo>>
     */
    @GetMapping(value = "/information/member/list/{id}")
    public ActionResult<List<UserInfoVo>> getInformationMemberList(@PathVariable(value = "id") String id) {

        List<UserInfoVo> list = spaceService.getInformationMemberList(id);
        return ActionResult.success(list);
    }

    /**
     * 查看空间/文件夹/文件信息
     * @param id 空间/文件夹/文件id
     * @return jnpf.base.ActionResult<jnpf.model.doclibrary.vo.InformationDetailVo>
     */
    @GetMapping(value = "/information/{id}")
    public ActionResult<InformationDetailVo> getInformation(@PathVariable(value = "id") String id) throws Exception {

        InformationDetailVo detail = spaceService.getInformation(id);
        return ActionResult.success(detail);
    }

    /**
     * 新增/更新浏览记录
     * @param viewDto 查看记录dto
     * @return jnpf.base.ActionResult
     */
    @PostMapping(value = "/viewRecord")
    public Object addViewRecord(@RequestBody @Valid ViewDto viewDto) {

        spaceService.addViewRecord(viewDto);
        return ActionResult.success();
    }

    /**
     * 回收站 - 列表
     * @param queryType 查询类型(1: 文件夹/2: 空间)
     * @param queryCondition 查询条件(文件名)
     * @return jnpf.base.ActionResult<jnpf.model.doclibrary.vo.RubbishVo>
     */
    @GetMapping(value = "/rubbish/list")
    public ActionResult<List<RubbishInfoVo>> getRubbishList(@RequestParam(value = "queryType") Integer queryType, @RequestParam(value = "queryCondition", required = false) String queryCondition) {

        List<RubbishInfoVo> list = spaceService.getRubbishList(queryType, queryCondition);
        return ActionResult.success(list);
    }

    /**
     * 回收站 - 列表(分页)
     * @param queryDto 查询条件
     * @return jnpf.base.ActionResult<jnpf.model.doclibrary.vo.RubbishVo>
     */
    @GetMapping(value = "/rubbish/page")
    public ActionResult<PageListVO<RubbishInfoVo>> getRubbishPage(@Valid RubbishQueryDto queryDto) {

        PageInfo<RubbishInfoVo> page = spaceService.getRubbishPage(queryDto);
        return ActionResult.page(page.getList(), FtbUtil.getPagination(page));
    }

    /**
     * 回收站 - 彻底删除
     * @param rubbishId 垃圾id
     * @return jnpf.base.ActionResult
     */
    @DeleteMapping(value = "/rubbish/{rubbishId}")
    public Object deleteRubbish(@PathVariable(value = "rubbishId") String rubbishId) {

        spaceService.deleteRubbish(rubbishId);
        return ActionResult.success();
    }

    /**
     * 回收站 - 恢复(空间/文件夹/文件)
     * @param undeleteDto 撤销删除dto
     * @return jnpf.base.ActionResult
     */
    @PutMapping(value = "/rubbish/undelete")
    public Object updateToUndelete(@RequestBody @Valid UndeleteDto undeleteDto) throws HandleException {

        spaceService.updateToUndelete(undeleteDto);
        return ActionResult.success();
    }

    /**
     * 回收站 - 恢复资源验证
     * @param rubbishId 垃圾id
     * @return jnpf.base.ActionResult
     */
    @GetMapping(value = "/rubbish/undelete/{rubbishId}")
    public ActionResult<CheckRubbishVo> checkUndelete(@PathVariable(value = "rubbishId") String rubbishId) {

        CheckRubbishVo checkRubbish = spaceService.checkUndelete(rubbishId);
        return ActionResult.success(checkRubbish);
    }

    /**
     * 新增文档/表格/PPT
     * @param uploadDto 上传dto
     * @return jnpf.base.ActionResult
     */
    @PostMapping(value = "/information/file")
    public ActionResult<Information> addInformationFile(@RequestBody @Valid UploadDto uploadDto) throws Exception {

        Information info = spaceService.addInformationFile(uploadDto);
        return ActionResult.success(info);
    }

    /**
     * 批量新增资源库数据(图片/视频/文件)
     * @param list 信息列表
     * @return jnpf.base.ActionResult
     */
    @PostMapping(value = "/information/details")
    public Object addInformationDetails(@RequestBody @Valid List<InfoDetailDto> list) {

        spaceService.addInformationDetails(list);
        return ActionResult.success();
    }

    /**
     * 上传文件
     * @param multipartFile 文件
     * @param fileName 文件名
     * @return jnpf.base.ActionResult<cn.xuyanwu.spring.file.storage.FileInfo>
     */
    @PostMapping(value = "/uploadFile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ActionResult<FileInfo> uploadFile(@RequestPart("multipartFile") MultipartFile multipartFile, @RequestParam(value = "fileName", required = false) String fileName) {

        FileInfo info = spaceService.uploadFile(multipartFile, fileName);
        return ActionResult.success(info);
    }

    /**
     * 畅写回调
     * @param request HttpServletRequest
     * @param response HttpServletResponse
     */
    @NoDataSourceBind
    @PostMapping("/changxie/callback")
    public void singleFileUploads(HttpServletRequest request, HttpServletResponse response) throws Exception {

        customTenantUtil.checkOutTenant(request.getParameter("tenantId"));
        spaceService.singleFileUploads(request, response);
    }

    @NoDataSourceBind
    @GetMapping(value = "/file")
    public void getFile(@RequestParam String url, @RequestParam String fileName, HttpServletResponse response) throws Exception {

        URL fileUrl = new URL(url);
        HttpURLConnection connection = (HttpURLConnection) fileUrl.openConnection();
        InputStream in = connection.getInputStream();
        if (null == in) {
            throw new Exception("下载失败...");
        }
        String subStr = url.substring(url.lastIndexOf("."));
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/octet-stream;charset=utf-8");
        // 6. 禁止图像缓存。
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + subStr, StandardCharsets.UTF_8));
        response.setDateHeader("Expires", 0);
        int count;
        byte[] by = new byte[1024];
        //通过response对象获取OutputStream流
        OutputStream out = response.getOutputStream();
        while ((count = in.read(by)) != -1) {
            //将缓冲区的数据输出到浏览器
            out.write(by, 0, count);
        }
        in.close();
        out.flush();
        out.close();
    }


    /**
     * 查询我的所有文件夹（返回tree）
     *
     * @param keyWord 文件夹名称
     * @return 返回一颗tree
     */
    @GetMapping(value = "/query-my-folder")
    public ActionResult<List<MiniInformationTreeVo>> queryMyResourceFolder(@RequestParam("keyWord") String keyWord) {
        return ActionResult.success("成功", spaceService.queryMyResourceFolder(keyWord));
    }

    /**
     * 查询文件夹下的所有文件
     *
     * @param req 请求参数
     * @return 文件列表
     */
    @GetMapping(value = "/query-my-files")
    public ActionResult<PageListVO<MiniInformationVo>> queryMyFilesForFolderId(QueryMyFilesReq req) {
        PageInfo<MiniInformationVo> page  =spaceService.queryMyFilesForFolderId(req);
        return ActionResult.page(page.getList(), FtbUtil.getPagination(page));
    }
}
