package com.house365.web.controller;

import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.house365.beans.entity.BaseAttachment;
import com.house365.beans.entity.BaseAttachmentRemoteUrl;
import com.house365.beans.entity.BaseAttachmentType;
import com.house365.beans.entity.UserEntity;
import com.house365.beans.system.Page;
import com.house365.rest.exception.ServiceException;
import com.house365.web.system.controller.BaseController;
import com.house365.web.util.FileLocationAttribute;
import com.house365.web.util.FileRemoteAttribute;
import com.house365.web.util.FileUtils;
import com.house365.web.util.HttpUtil;
import com.house365.ws.beans.request.AttachmentListRequest;
import com.house365.ws.beans.request.AttachmentRequest;
import com.house365.ws.beans.response.*;
import com.house365.ws.interfaces.server.IAttachmentInterface;
import com.house365.ws.interfaces.server.IAttachmentRemoteUrlInterface;
import com.house365.ws.interfaces.server.IAttachmentTypeInterface;
import com.house365.ws.interfaces.server.IUser;
import com.house365.ws.system.ReturnResult;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springside.modules.web.Servlets;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 附件 控制器<br>
 *
 * @author duhui
 * @version [v1.0.0, 2015-1-18]
 */
@Controller
@RequestMapping("/attachment")
public class AttachmentController extends BaseController {

    Logger roleLOG = LoggerFactory.getLogger(getClass());

    @Autowired
    private IUser user;

    @Autowired
    IAttachmentInterface attachmentInterface;
    @Autowired
    IAttachmentTypeInterface attachmentTypeInterface;
    @Autowired
    IAttachmentRemoteUrlInterface attachmentRemoteUrlInterface;

    /**
     * 功能描述: <br>
     * 简单附件列表查询
     *
     * @param resourceType 资源类型
     * @param resourceId   资源ID
     * @param editAble     是否可编辑
     * @param model        视图模型
     * @param request      请求
     * @return
     * @author chengjianfang
     * @version [v1.0.0, 2015年1月28日]
     * @since [产品/模块版本](可选)
     */
    @RequestMapping(value = "/sampleAttachmentListSection/{resourceType}/{resourceId}/{editAble}")
    public String sampleAttachmentListSection(@PathVariable("resourceType") String resourceType,
                                              @PathVariable("resourceId") Integer resourceId, @PathVariable("editAble") boolean editAble, Integer bizType, Model model,
                                              HttpServletRequest request) {
        // 获取查询条件
        Map<String, Object> searchParams = Servlets.getParametersStartingWith(request, "search_");
        searchParams.put("EQ_resourceType", resourceType);
        searchParams.put("EQ_resourceId", resourceId);
        if (null == bizType) {
            searchParams.put("LTE_bizType", 3);
        } else {
            searchParams.put("EQ_bizType", bizType);
        }
        AttachmentListRequest req = new AttachmentListRequest();
        req.setSearchParams(searchParams);
        AttachmentListResponse response = attachmentInterface.getAttachments(req);
        // 业务异常，直接跳转到列表页面
        if (!StringUtils.equals(response.getResultCode(), ReturnResult.SUCCESS.getResultCode())) {
            addErrorMessage(model, ReturnResult.FAIL.getResultMessage() + response.getResultMessage());
            return getAutoUrl();
        }
        model.addAttribute("resourceType", resourceType);
        model.addAttribute("resourceId", resourceId);
        model.addAttribute("bizType", bizType);
        model.addAttribute("editAble", editAble);
        model.addAttribute("attachmentList", response.getObjectList());
        return getAutoUrl();
    }

    /**
     * 附件列表
     *
     * @author duhui
     * @version [v1.0.0, 2015-1-18]
     */
    @RequestMapping(value = "/attachmentListSection/{resourceType}/{resourceId}")
    public String attachmentListSection(@PathVariable(value = "resourceType") String resourceType,
                                        @PathVariable(value = "resourceId") Integer resourceId, Integer number, Model model,
                                        HttpServletRequest request) {

        // 获取查询条件
        Map<String, Object> searchParams = Servlets.getParametersStartingWith(request, "search_");
        searchParams.put("EQ_resourceType", resourceType);
        searchParams.put("EQ_resourceId", resourceId);
        Page page = new Page(20);
        if (null != number) {
            page.setCurrentPage(number);
        }
        AttachmentListResponse response = new AttachmentListResponse();
        AttachmentListRequest req = new AttachmentListRequest();
        req.setPaging(page);
        req.setSearchParams(searchParams);
        response = attachmentInterface.getAttachments(req);
        // 业务异常，直接跳转到列表页面
        if (!StringUtils.equals(response.getResultCode(), ReturnResult.SUCCESS.getResultCode())) {
            addErrorMessage(model, ReturnResult.FAIL.getResultMessage() + response.getResultMessage());
            return getAutoUrl();
        }
        model.addAttribute("page", response.getPaging());
        model.addAttribute("attachmentList", response.getObjectList());
        return getAutoUrl();
    }

    /**
     * 去添加附件页
     *
     * @author duhui
     * @version [v1.0.0, 2015-1-18]
     */
    @RequestMapping(value = "/attachmentToAddSection/{resourceType}/{resourceId}")
    public String toAddSection(HttpServletRequest request, @PathVariable(value = "resourceType") String resourceType,
                               @PathVariable(value = "resourceId") String resourceId) {
        request.setAttribute("resourceType", resourceType);
        request.setAttribute("resourceId", resourceId);
        return getAutoUrl("attachmentAddSection");
    }

    /**
     * 功能描述: <br>
     * 去添加附件页
     *
     * @param request      请求
     * @param resourceType 资源类型
     * @param resourceId   资源ID
     * @return
     * @author chengjianfang
     * @version [v1.0.0, 2015年1月29日]
     * @since [产品/模块版本](可选)
     */
    @RequestMapping(value = "sampleAttachmentToAddSection/{resourceType}/{resourceId}")
    public String sampleToAddSection(HttpServletRequest request,
                                     @PathVariable("resourceType") String resourceType,
                                     @PathVariable("resourceId") String resourceId,
                                     Integer bizType) {
        request.setAttribute("resourceType", resourceType);
        request.setAttribute("resourceId", resourceId);
        request.setAttribute("bizType", bizType);
        return getAutoUrl("sampleAttachmentAddSection");
    }

    /**
     * 功能描述: <br>
     * 保存附件
     *
     * @param request
     * @param attachment
     * @param model
     * @author chengjianfang
     * @version [v1.0.0, 2015年1月29日]
     * @since [产品/模块版本](可选)
     */
    @RequestMapping(value = "sampleAttachmentAddSection", method = {RequestMethod.POST})
    @ResponseBody
    public void sampleAttachmentAddSection(MultipartHttpServletRequest request, BaseAttachment attachment, Model model) {
        try {
            MultipartFile file = request.getFile("file");
            try {
                FileLocationAttribute fileLocationAttribute = new FileLocationAttribute(file);
                attachment.setSize(fileLocationAttribute.getSize());
                attachment.setSuffix(fileLocationAttribute.getSuffix());
                String remotePath = com.house365.commons.system.FastDFSUtil.uploadFile(fileLocationAttribute
                        .getStoreLocation().getPath());
                attachment.setRemotePath(remotePath);
            } catch (Exception e) {
                throw new Exception(e.getMessage());
            }
            AttachmentRequest req = new AttachmentRequest();
            req.setAttachment(attachment);
            attachmentInterface.addAttachment(req);
        } catch (Exception se) {
            se.getStackTrace();
        }
    }

    /**
     * 保存附件
     *
     * @author duhui
     * @version [v1.0.0, 2015-1-18]
     */
    @RequestMapping(value = "attachmentAddSection", method = {RequestMethod.POST})
    @ResponseBody
    public void attachmentAddSection(MultipartHttpServletRequest request, BaseAttachment attachment, Model model) {
        try {
            MultipartFile file = request.getFile("file");
            String name = request.getParameter("name");
            String remark = request.getParameter("remark");
            int bizType = Integer.valueOf(request.getParameter("bizType"));
            String regx = "";
            int attachmentTypeId = 0;
            if (null != file.getOriginalFilename()) {
                if (file.getOriginalFilename().contains(".")) {
                    regx = file.getOriginalFilename().split("\\.")[1];
                    AttachmentTypeListResponse response = attachmentTypeInterface.getAttachmentTypesBySuffix(regx);
                    BaseAttachmentType attachmentType = (BaseAttachmentType) response.getObjectList().get(0);
                    attachmentTypeId = attachmentType.getId();
                }
            }
            try {
                attachment.setName(name);
                attachment.setAttachmentTypeId(attachmentTypeId);
                attachment.setRemark(remark);
                attachment.setBizType(bizType);
                FileLocationAttribute fileLocationAttribute = new FileLocationAttribute(file);
                attachment.setSize(fileLocationAttribute.getSize());
                attachment.setSuffix(fileLocationAttribute.getSuffix());
                FileRemoteAttribute fileRemoteAttribute = FileUtils.sendToRemote(fileLocationAttribute);
                attachment.setRemotePath(fileRemoteAttribute.getRemotePath());
                attachment.setRemoteServerUrlid(fileRemoteAttribute.getRemoteServerUrlId());
            } catch (Exception e) {
                throw new Exception(e.getMessage());
            }
            AttachmentRequest req = new AttachmentRequest();
            req.setAttachment(attachment);
            attachmentInterface.addAttachment(req);
        } catch (Exception se) {
            se.getStackTrace();
        }
    }

    /**
     * 删除附件
     * 同时将删除头像消息同步到IM
     *
     * @author duhui
     * @version [v1.0.0, 2015-1-18]
     */
    @RequestMapping(value = "/delete/{id}", method = {RequestMethod.DELETE})
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public String deleteAttachment(@PathVariable(value = "id") Integer id, Model model) {
        //先获取accId
        AttachmentResponse response = attachmentInterface.getAttachment(id);
        // create request and response
        AttachmentResponse rsp = new AttachmentResponse();
        rsp = attachmentInterface.deleteAttachment(id);
        if (response != null && response.getAttachment() != null) {
            BaseAttachment attachment = response.getAttachment();
            Integer resourceId = attachment.getResourceId();
            UserEntity userEntity = new UserEntity();
            UserResponse userResponse = user.getUserById(Integer.valueOf(resourceId));
            if (userResponse.getEntity() != null) {
                userEntity = userResponse.getEntity();
            }
            String accId = userEntity.getAccId();
            //通知IM头像修改
            try {
                String deciceId = com.house365.web.util.StringUtils.getRandomNumber(10);
                String randStr = com.house365.web.util.StringUtils.getRandomChars(13);
                String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
                String signature = HttpUtil.getSignature2(deciceId, randStr, timestamp);
                //获取accesstoken
                HashMap<String, String> accesstokenMap = new HashMap<>();
                accesstokenMap.put("version", "v3.0");
                //获取acceToken接口URl
                String getAccessTokenUrl = "http://yunxinim.house365.com/api/5b0cc34464a64";
                List<NameValuePair> tokenInParam = new ArrayList<>();
                tokenInParam.add(new BasicNameValuePair("app_id", "89962055"));
                tokenInParam.add(new BasicNameValuePair("app_secret", "pMHTUWAoOGSjaToIhHKwmQJKWZcAAvjN"));
                tokenInParam.add(new BasicNameValuePair("device_id", deciceId));
                tokenInParam.add(new BasicNameValuePair("rand_str", randStr));
                tokenInParam.add(new BasicNameValuePair("timestamp", timestamp));
                tokenInParam.add(new BasicNameValuePair("signature", signature));

                List<String> newTokenParams = new ArrayList<>();
                for (NameValuePair pair : tokenInParam) {
                    newTokenParams.add(pair.getName() + "=" + pair.getValue());
                }
                String newTokenUrl = getAccessTokenUrl + "?" + Joiner.on("&").join(newTokenParams);
                String tokenResult = "";
                tokenResult = HttpUtil.getHttpRequest(newTokenUrl, accesstokenMap, 100000, "utf-8");
                if (Strings.isNullOrEmpty(tokenResult)) {
                    throw new ServiceException("get token failed");
                }
                JSONObject json = JSONObject.fromObject(tokenResult);
                JSONObject jo = json.getJSONObject("data");
                String accessToken = jo.getString("access_token");
                roleLOG.error("******ACCESS_TOKEN*******" + accessToken);
                //2.通知IM更新用户
                HashMap<String, String> accidMap = new HashMap<>();
                List<NameValuePair> cornetInParam = new ArrayList<>();
                cornetInParam.add(new BasicNameValuePair("accid", accId));
                cornetInParam.add(new BasicNameValuePair("avatar", ""));
                HttpUtil.doPostWithHeader("http://yunxinim.house365.com/api/5b9235bea9f88", cornetInParam, accessToken, "");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        // 直接返回结果码，页面会根据结果码来处理
        return rsp.getResultCode();
    }

    /**
     * 功能描述: <br>
     * 获取建议下载，返回相应路径
     *
     * @param attachmentId 附件编号
     * @return
     * @author chengjianfang
     * @version [v1.0.0, 2015年1月29日]
     * @since [产品/模块版本](可选)
     */
    public String sampleDownload(@PathVariable("attachmentId") Integer attachmentId) {
        AttachmentResponse rsp = attachmentInterface.getAttachment(attachmentId);
        BaseAttachment attachment = rsp.getAttachment();
        if (null == attachment) {
            return null;
        }
        return attachment.getRemotePath();
    }

    /**
     * 附件下载
     *
     * @author duhui
     * @version [v1.0.0, 2015-1-18]
     */
    @RequestMapping(value = "attachmentDownload/{attachmentId}", method = RequestMethod.GET)
    @ResponseBody
    public ResponseEntity<byte[]> download(@PathVariable("attachmentId") Integer attachmentId) {
        // 权限控制
        boolean auth = true;
        if (auth) {
            return downloadById(attachmentId);
        } else {
            return null;
        }
    }

    /**
     * 附件下载
     *
     * @author duhui
     * @version [v1.0.0, 2015-1-18]
     */
    protected final ResponseEntity<byte[]> downloadById(Integer id) {
        HttpHeaders headers = new HttpHeaders();
        try {

            AttachmentResponse rsp = attachmentInterface.getAttachment(id);
            BaseAttachment attachment = rsp.getAttachment();
            // 文件不被系统管理
            if (null == attachment) {
                // 请求的文件在系统中不存在
                return null;
            }
            String filename = attachment.getName() + "." + attachment.getSuffix();
            File file = getRealFile(attachment);
            // 文件不存在
            if (null == file || !file.exists()) {
                return null;
            }
            // 指定路径不是文件
            if (file.isDirectory() || !file.isFile()) {
                return null;
            }
            byte[] fileByteArray = null;
            try {
                fileByteArray = FileUtils.readFileToByteArray(file);
            } catch (Exception e) {
                return null;
            }
            // 读取文件失败
            if (null == fileByteArray) {
                return null;
            }
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setContentDispositionFormData("attachment", URLEncoder.encode(filename, "UTF-8"));
            return new ResponseEntity<byte[]>(fileByteArray, headers, HttpStatus.OK);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 附件真实路径
     *
     * @author duhui
     * @version [v1.0.0, 2015-1-18]
     */
    private final File getRealFile(BaseAttachment attachment) {
        AttachmentRemoteUrlResponse response = attachmentRemoteUrlInterface.getAttachmentRemoteUrl(attachment
                .getRemoteServerUrlid());
        BaseAttachmentRemoteUrl attachmentRemoteUrl = response.getAttachmentRemoteUrl();
        attachment.getRemoteServerUrlid();
        return new File(attachmentRemoteUrl.getRemoteServerUrl() + File.separatorChar + attachment.getRemotePath());
    }

    /**
     *
     */
    @RequestMapping(value = "/upload/{uploadtype}/{resourceId}")
    @ResponseBody
    public void uploadFile(@PathVariable(value = "uploadtype") String uploadtype,
                           @PathVariable(value = "resourceId") Integer resourceId, MultipartHttpServletRequest request, Model model) {
        try {
            BaseAttachment attachment = null;
            MultipartFile file = request.getFile("file");
            String name = request.getParameter("name");
            String remark = request.getParameter("remark");
            String regx = "";
            int attachmentTypeId = 0;
            if (null != file.getOriginalFilename()) {
                if (file.getOriginalFilename().contains(".")) {
                    regx = file.getOriginalFilename().split("\\.")[1];
                    AttachmentTypeListResponse response = attachmentTypeInterface.getAttachmentTypesBySuffix(regx);
                    BaseAttachmentType attachmentType = (BaseAttachmentType) response.getObjectList().get(0);
                    attachmentTypeId = attachmentType.getId();
                }
            }
            try {
                FileLocationAttribute fileLocationAttribute = new FileLocationAttribute(file);
                FileRemoteAttribute fileRemoteAttribute = FileUtils.sendToRemote(fileLocationAttribute);
                attachment = new BaseAttachment();
                attachment.setName(name);
                attachment.setAttachmentTypeId(attachmentTypeId);
                attachment.setRemark(remark);
                attachment.setSize(fileLocationAttribute.getSize());
                attachment.setSuffix(fileLocationAttribute.getSuffix());
                attachment.setRemotePath(fileRemoteAttribute.getRemotePath());
                attachment.setRemoteServerUrlid(fileRemoteAttribute.getRemoteServerUrlId());
                attachment.setResourceId(0);
                attachment.setRemark(name);
                // 业务类型 编码 0 :web 1:wap
                if (uploadtype.equals("web")) {
                    attachment.setBizType(0);
                } else {
                    attachment.setBizType(1);
                }

            } catch (Exception e) {
                throw new Exception(e.getMessage());
            }
            AttachmentRequest req = new AttachmentRequest();
            req.setAttachment(attachment);
            attachmentInterface.addAttachment(req);
        } catch (Exception se) {
            se.getStackTrace();
        }
    }
}
