package com.bcxin.web.controller;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bcxin.config.WPSConfig;
import com.bcxin.enums.SysNameEnum;
import com.bcxin.utils.ConfigUtil;
import com.bcxin.utils.constant.DictConst;
import com.bcxin.utils.wps.WPSUtils;
import com.bcxin.vo.wps.UserAclVo;
import com.bcxin.vo.wps.WatermarkVo;
import com.bcxin.vo.wps.WpsFileVo;
import com.bcxin.vo.wps.WpsUserVo;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @Description: 全部是wps回调接口控制器，只供wps开放平台回调使用
 * @Author: wangjianjun
 * @Date: 2019/9/30
 */
@Controller
@Slf4j
public class AcWpsController {
    /**
     * 获取文件元数据
     * 这个方法还要补充一些文件信息
     *
     *   fileId       这个是与WPS平台交换文件的唯一凭证，这里我们加上系统名,例如本来文件Id为123，来自PSS的就是PSS_123
     * @param _w_readonly  0是写，1是读
     * @param _w_filepath
     * @param _w_appid
     * @param _w_signature
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/v1/3rd/file/info", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Map<String, Object> fileInfo(String _w_readonly, String _w_filepath, String _w_appid, String _w_signature,String _w_param1, HttpServletRequest request, HttpServletResponse response) {
        log.info("获取文件元数据方法");
        Map<String, Object> resultMap = WPSUtils.newSuccessMap();
        HashMap<String, String> map = Maps.newHashMap();
        String token = WPSUtils.getToken(request);
        WpsFileVo wpsFileVo = new WpsFileVo();
        WpsUserVo wpsUserVo = new WpsUserVo();
        //fileId 这个是与WPS平台交换的文件的唯一凭证
        String fileId = WPSUtils.getFileId(request);
        String filePath = Base64.decodeStr(_w_filepath);
        log.info("fileId:" + fileId);
        Map<String, Object> paramMap = new HashMap<>();
//        try {
//            String sysUrl = SysNameEnum.getVal("SYS_" + fileId.substring(0, fileId.indexOf("_")));//不能设置默认值
//            paramMap.put("fileId", fileId.substring(fileId.indexOf("_") + 1));//PSS_123,变成123
//            String result = HttpUtil.post(sysUrl + "/getinfo", paramMap);//json string
//            map = new ObjectMapper().readValue(result, HashMap.class);//json转map
//        } catch (Exception e) {
////            log.error("连接错误或者在fileId解析出错", e);//日志打太多了，去掉堆栈日志。
//            log.error("连接错误或者在fileId解析出错");
//        }
        try {
            //根据readonly参数指定编辑或者预览
            if ((!StringUtils.isEmpty(_w_readonly)) && "0".equalsIgnoreCase(_w_readonly)) {
                wpsUserVo.setPermission(WPSConfig.PERMISSION_WRITE);
            } else {
                wpsUserVo.setPermission(WPSConfig.PERMISSION_READ);
            }
            //TODO 这些数据在上线之前必须请金山公司帮忙清空，而且很可能导致fileId重复
            String freeze = "", creator = "", create_time = "", modifier = "", modify_time = "", version = "", size = "", user_id = "", user_name = "";
            if (!map.isEmpty()) {
                freeze = map.getOrDefault("freeze", "");
                creator = map.getOrDefault("creator", "");
                create_time = map.getOrDefault("create_time", "");
                modifier = map.getOrDefault("modifier", "");
                modify_time = map.getOrDefault("modify_time", "");
                version = map.getOrDefault("version", "");
                size = map.getOrDefault("size", "");
                user_id = map.getOrDefault("user_id", "");
                user_name = map.getOrDefault("user_name", "");
            }
//            if (StrUtil.equals(freeze, DictConst.Y) && StrUtil.equals(wpsUserVo.getPermission(), WPSConfig.PERMISSION_READ)) {
//                wpsFileVo.setId(fileId + IdUtil.simpleUUID());//提交任务后，或者说冻结后，预览的时候不能用原来的ID了。
//            } else {
//                wpsFileVo.setId(fileId);//fileId非常重要，注意不要重复，是WPS和我们数据库唯一的关联值
//            }
            wpsFileVo.setId(fileId);//fileId非常重要，注意不要重复，是WPS和我们数据库唯一的关联值
            wpsFileVo.setName(filePath.substring(filePath.lastIndexOf("/") + 1));//从后向前，直接截取最后一部分
            wpsFileVo.setCreator(StringUtils.isEmpty(creator) ? "wangjianjunCreate" : creator);
            wpsFileVo.setCreate_time(StringUtils.isEmpty(create_time) || "null".equalsIgnoreCase(create_time) ? System.currentTimeMillis() / 1000 : Long.valueOf(create_time));
            wpsFileVo.setModifier(StringUtils.isEmpty(modifier) ? "wangjianjunModify" : modifier);
            wpsFileVo.setModify_time(StringUtils.isEmpty(modify_time) || "null".equalsIgnoreCase(modify_time) ? wpsFileVo.getCreate_time() : Long.valueOf(modify_time));
            wpsFileVo.setVersion(StringUtils.isEmpty(version) || "null".equalsIgnoreCase(version) ? 1 : Integer.valueOf(version));
            wpsFileVo.setSize(StringUtils.isEmpty(size) || "null".equalsIgnoreCase(size) ? getFileLength(filePath) : Integer.valueOf(size));
            wpsFileVo.setDownload_url(filePath);
            //加水印
            WatermarkVo watermark = new WatermarkVo();
            watermark.setType(0);//关闭水印
            watermark.setValue("百川信（厦门）网络信息服务有限公司");
            wpsFileVo.setWatermark(watermark);
            //权限
            UserAclVo userAclVo = new UserAclVo();
            userAclVo.setRename(0);//重命名权限，1为打开该权限，0为关闭该权限，默认为0
            userAclVo.setHistory(0);//历史版本权限，1为打开该权限，0为关闭该权限,默认为1
            wpsFileVo.setUser_acl(userAclVo);

            wpsUserVo.setId(StringUtils.isEmpty(user_id) ? "id1001" : String.valueOf(user_id));
            wpsUserVo.setName(StringUtils.isEmpty(user_name) ? "bcx-wjj" : Base64.decodeStr(String.valueOf(user_name)));


            resultMap.put("file", wpsFileVo);
            resultMap.put("user", wpsUserVo);
        } catch (Exception e) {
            log.error("获取元数据回调接口出错", e);
            resultMap.put("code", 9999);
            resultMap.put("msg", "获取元数据回调接口出错");
        }
        log.info("获取元数据-回调接口-返回数据：" + JSONArray.toJSONString(resultMap));
        return resultMap;
    }

    /**
     * 获取用户信息
     *
     * @param
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/v1/3rd/user/info", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Map<String, Object> userInfo(String _w_appid, String _w_signature, @RequestBody JSONObject reqObj, HttpServletRequest request, HttpServletResponse response) {

        log.info("获取用户信息");
        Map<String, Object> resultMap = WPSUtils.newSuccessMap();

        String token = WPSUtils.getToken(request);
        String fileId = WPSUtils.getFileId(request);

        if (log.isDebugEnabled()) {
            log.debug("token:" + token);
            log.debug("fileId:" + fileId);
            log.debug("_w_appid:" + _w_appid);
            log.debug("_w_signature:" + _w_signature);
            log.debug("reqObj:" + reqObj);
        }
//        logger.info("reqObj:" + reqObj);
        List<String> ids = null;
        if (reqObj != null) {
            if (reqObj.containsKey("ids")) {
                ArrayList reqObjIds = (ArrayList) reqObj.get("ids");
                StringBuilder sb = new StringBuilder();
                sb.append("[");
                for (int i = 0; i < reqObjIds.size(); i++) {
                    sb.append("\"");
                    sb.append(reqObjIds.get(i));
                    sb.append("\"");
                    if (i != reqObjIds.size() - 1) {
                        sb.append(",");
                    }
                }
                sb.append("]");
                ids = JSONArray.parseArray(sb.toString(), String.class);
            }
        }

        if (ids != null && !ids.isEmpty()) {
            List<WpsUserVo> users = new ArrayList<>();
            for (int i = 0; i < ids.size(); i++) {
                WpsUserVo user = new WpsUserVo();
                user.setId(ids.get(i));
                user.setName("admin" + i);
                users.add(user);
            }
            resultMap.put("users", users);
        }
        log.info("获取用户信息-回调接口-返回数据：" + JSONArray.toJSONString(resultMap));
        return resultMap;
    }

    /**
     * 通知此文件目前有那些人正在协作
     *
     * @param
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/v1/3rd/file/online", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Map<String, Object> fileOnline(String _w_appid, String _w_signature, HttpServletRequest request, HttpServletResponse response) {
        if (log.isDebugEnabled()) {
            log.debug("调用通知此文件目前有那些人正在协作");
        }
        Map<String, Object> resultMap = WPSUtils.newSuccessMap();

        String token = WPSUtils.getToken(request);
        String fileId = WPSUtils.getFileId(request);

        if (log.isDebugEnabled()) {
            log.debug("token:" + token);
            log.debug("fileId:" + fileId);
            log.debug("_w_appid:" + _w_appid);
            log.debug("_w_signature:" + _w_signature);
        }

        List<String> userids = new ArrayList<>();
        userids.add("1");

        resultMap.put("ids", userids);

        if (log.isDebugEnabled()) {
            log.debug("返回数据：" + resultMap);
        }
        return resultMap;
    }

    /**
     * 上传文件新版本
     *
     * @param _w_appid
     * @param _w_signature
     * @param request
     * @param response
     * @param multipartFile 要保存至服务器的文件
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/v1/3rd/file/save", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Map<String, Object> fileSave(String _w_appid, String _w_signature, HttpServletRequest request, HttpServletResponse response, @RequestParam("file") MultipartFile multipartFile, String _w_filepath,String _w_param1) throws IOException {
        log.info("上传文件新版本");
        Map<String, Object> resultMap = WPSUtils.newSuccessMap();
        String token = WPSUtils.getToken(request);
        String fileId = WPSUtils.getFileId(request);
        if (multipartFile.isEmpty()) {
            log.error("上传文件新版本回调接口出错:" + "文件流是空的");
            resultMap.put("code", 9999);
            resultMap.put("msg", "上传文件新版本回调接口出错");
            return resultMap;
        }
        //multipart转成file
        String tempPath = WPSConfig.WPS_FILE_TEMP_FOLDER + multipartFile.getOriginalFilename();
        File file = FileUtil.touch(tempPath);//判断临时下载目录是否存在，不存在则创建
        multipartFile.transferTo(file);
        Map<String, Object> paramMap = new HashMap<>();
//        paramMap.put("fileId", fileId);
//        paramMap.put("fileId", fileId.substring(fileId.indexOf("_") + 1));//PSS_123,变成123
        paramMap.put("file", file);
        paramMap.put("filePath", _w_filepath);

//        String sysUrl = SysNameEnum.getVal("SYS_" + fileId.substring(0, fileId.indexOf("_")));//不能设置默认值
        String sysUrl = ConfigUtil.getValue("pss_url") + "communicate/wps";//todo 只有pss能保存
        if(StrUtil.isNotBlank(_w_param1)){//预发布环境写死
            if("pre".equalsIgnoreCase(_w_param1)){
                sysUrl=ConfigUtil.getValue("pss_pre_url")+ "communicate/wps";
            }
        }
        log.info("sysUrl===" + sysUrl);
        String fileUrl = HttpUtil.post(sysUrl + "/savefile", paramMap);
        log.info("fileUrl===" + fileUrl);
        log.info("_w_filepath===" + _w_filepath);
        if (file.exists()) {
            file.delete();
        }
        if (StringUtils.isEmpty(fileUrl)) {
            log.error("上传文件新版本回调接口出错", fileUrl);
            resultMap.put("code", 9999);
            resultMap.put("msg", "上传文件新版本回调接口出错");
            return resultMap;
        }
        ImmutableMap<Object, Object> fileMap = ImmutableMap.builder()
                .put("id", fileId)//文件id，字符串长度小于40
                .put("name", multipartFile.getOriginalFilename())//文件名
                .put("version", System.currentTimeMillis() / 1000)//用时间戳当版本号j.当前版本号，位数小于11
                .put("size", multipartFile.getSize())
                .put("download_url", fileUrl).build();
        resultMap.put("file", fileMap);
        if (log.isDebugEnabled()) {
            log.debug("token:" + token);
            log.debug("fileId:" + fileId);
            log.debug("_w_appid:" + _w_appid);
            log.debug("_w_signature:" + _w_signature);
        }
        log.debug("返回数据：" + resultMap);
        return resultMap;
    }

    /**
     * 获取特定版本的文件版本信息
     *
     * @param
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/v1/3rd/file/version", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Map<String, Object> fileVersion(String _w_appid, String _w_signature, HttpServletRequest request, HttpServletResponse response) {
        if (log.isDebugEnabled()) {
            log.debug("获取特定版本的文件版本信息");
        }
        Map<String, Object> resultMap = WPSUtils.newSuccessMap();

        String token = WPSUtils.getToken(request);
        String fileId = WPSUtils.getFileId(request);

        if (log.isDebugEnabled()) {
            log.debug("token:" + token);
            log.debug("fileId:" + fileId);
            log.debug("_w_appid:" + _w_appid);
            log.debug("_w_signature:" + _w_signature);
        }


        if (log.isDebugEnabled()) {
            log.debug("返回数据：" + resultMap);
        }
        return resultMap;
    }

    /**
     * 文件重命名
     *
     * @param
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/v1/3rd/file/rename", method = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT})
    @ResponseBody
    public Map<String, Object> fileRename(String _w_appid, String _w_signature, HttpServletRequest request, HttpServletResponse response) {
        if (log.isDebugEnabled()) {
            log.debug("文件重命名");
        }
        Map<String, Object> resultMap = WPSUtils.newSuccessMap();

        String token = WPSUtils.getToken(request);
        String fileId = WPSUtils.getFileId(request);

        if (log.isDebugEnabled()) {
            log.debug("token:" + token);
            log.debug("fileId:" + fileId);
            log.debug("_w_appid:" + _w_appid);
            log.debug("_w_signature:" + _w_signature);
        }


        if (log.isDebugEnabled()) {
            log.debug("返回数据：" + resultMap);
        }
        return resultMap;
    }

    /**
     * 获取所有历史版本文件信息
     *
     * @param
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/v1/3rd/file/history", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Map<String, Object> fileHistory(String _w_appid, String _w_signature, HttpServletRequest request, HttpServletResponse response) {
        if (log.isDebugEnabled()) {
            log.debug("获取所有历史版本文件信息");
        }
        Map<String, Object> resultMap = WPSUtils.newSuccessMap();

        String token = WPSUtils.getToken(request);
        String fileId = WPSUtils.getFileId(request);

        if (log.isDebugEnabled()) {
            log.debug("token:" + token);
            log.debug("fileId:" + fileId);
            log.debug("_w_appid:" + _w_appid);
            log.debug("_w_signature:" + _w_signature);
        }


        if (log.isDebugEnabled()) {
            log.debug("返回数据：" + resultMap);
        }
        return resultMap;
    }

    /**
     * 新建文件
     *
     * @param
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/v1/3rd/file/new", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Map<String, Object> fileNew(String _w_appid, String _w_signature, HttpServletRequest request, HttpServletResponse response) {
        if (log.isDebugEnabled()) {
            log.debug("新建文件");
        }
        Map<String, Object> resultMap = WPSUtils.newSuccessMap();

        String token = WPSUtils.getToken(request);
        String fileId = WPSUtils.getFileId(request);

        if (log.isDebugEnabled()) {
            log.debug("token:" + token);
            log.debug("fileId:" + fileId);
            log.debug("_w_appid:" + _w_appid);
            log.debug("_w_signature:" + _w_signature);
        }

        if (log.isDebugEnabled()) {
            log.debug("返回数据：" + resultMap);
        }
        return resultMap;
    }

    /**
     * 通过url获取文件大小
     *
     * @param fileUrl
     * @return
     * @throws IOException
     */
    public static long getFileLength(String fileUrl) throws IOException {

        if (fileUrl == null || "".equals(fileUrl)) {
            return 0L;
        }
        URL url = new URL(fileUrl);
        HttpURLConnection conn = null;
        try {
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("HEAD");
            conn.setRequestProperty("Accept-Encoding", "identity");
            conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows 7; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.73 Safari/537.36 YNoteCef/5.8.0.1 (Windows)");
            return conn.getContentLengthLong();
        } catch (IOException e) {
            return 0L;
        } finally {
            conn.disconnect();
        }

    }
}