package com.cftech.cos.uploader.web;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cftech.core.scope.OrderType;
import com.cftech.core.sql.Conds;
import com.cftech.core.sql.Sort;
import com.cftech.core.util.*;
import com.cftech.cos.alioss.AliOssStorageService;
import com.cftech.cos.config.cosconfig.model.Cosconfig;
import com.cftech.cos.config.cosconfig.service.CosconfigService;
import com.cftech.cos.core.CosService;
import com.cftech.cos.qcloud.QcloudStorageService;
import com.cftech.cos.qiniu.QiniuStorageService;
import com.cftech.cos.uploader.CosFileUploader;
import com.cftech.cos.uploader.category.model.MaterialCategory;
import com.cftech.cos.uploader.category.service.MaterialCategoryService;
import com.cftech.cos.uploader.model.Material;
import com.cftech.cos.uploader.service.MaterialUploadService;
import com.cftech.sys.security.UserUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.map.HashedMap;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;


/**
 * 上传素材Controller
 *
 * @author mubo
 * @date: 2017-05-04 09:16
 */
@Slf4j
@Controller
@RequestMapping("/a/materialUpload")
public class MaterialUploadController {

    private CosService cosService;
    private Cosconfig cosconfig;

    @Autowired
    private MaterialUploadService materialUploadService;

    @Autowired
    private CosconfigService cosconfigService;

    @Autowired
    private MaterialCategoryService materialCategoryService;

    private final static String rootQCName = SystemConfig.p.getProperty("ROOT_MATERIALCATEGORY_NAME");

    // 本地图片目录
    public static final String USER_IMAGES_DIR = SystemConfig.p.getProperty("userfiles.imgdir");
    //素材查看权限
    public static final String MATERIAL_VIEW = "material:view";
    //素材编辑权限
    public static final String MATERIAL_EDIT = "material:edit";

    //列表页面
    @RequestMapping("/list")
    @RequiresPermissions(value = MATERIAL_VIEW)
    public String list(HttpServletRequest request, Model model) {

        return "upload/materialUploadlist";
    }

    //获取列表数据
    @RequiresPermissions(value = MATERIAL_VIEW)
    @RequestMapping(value = "/listData")
    @ResponseBody
    public JSONObject listData(int iDisplayStart, int iDisplayLength, Material material, HttpServletRequest request) {
        Long userId = UserUtils.getUser().getId();
        Conds conds = new Conds();
        conds.equal("t.del_flag", Constants.DEL_FLAG_0);
//        conds.equal("t.create_by", userId);
        if (StringUtils.isNotBlank(material.getTitle())) {
            conds.like("t.title", material.getTitle());
        }
        Sort sort = new Sort("t.create_time", OrderType.DESC);
        List<Material> list = materialUploadService.fetchSearchByPageVo(material.getCategoryid(), conds, sort, iDisplayStart, iDisplayLength);
        Integer counts = materialUploadService.countVo(material.getCategoryid(), conds);
        JSONObject rtnJson = new JSONObject();
        rtnJson.put("iTotalRecords", counts);
        rtnJson.put("iTotalDisplayRecords", counts);
        rtnJson.put("aaData", list);
        return rtnJson;
    }

    //获取列表数据
    @RequiresPermissions(value = MATERIAL_VIEW)
    @RequestMapping(value = "/catlistData")
    @ResponseBody
    public JSONObject catlistData(int iDisplayStart, int iDisplayLength, Long categoryId, HttpServletRequest request) {
        if (categoryId == null) {
            JSONObject rtnJson = new JSONObject();
            rtnJson.put("aaData", new JSONArray());
            return rtnJson;
        }
        Long userId = UserUtils.getUser().getId();
        Conds conds = new Conds();
        conds.equal("t.del_flag", Constants.DEL_FLAG_0);
        /*conds.equal("t.create_by", userId);*/

        Sort sort = new Sort("t.create_time", OrderType.DESC);
        List<Material> list = materialUploadService.fetchSearchByPageVo(categoryId, conds, sort, iDisplayStart, iDisplayLength);
        JSONObject rtnJson = new JSONObject();

        rtnJson.put("aaData", list);
        return rtnJson;
    }

    /**
     * 增加页面
     */
    @RequiresPermissions(value = MATERIAL_EDIT)
    @RequestMapping("/form")
    public String form(HttpServletRequest request, Material material, Model model) {
        Long userId = UserUtils.getUser().getId();
        Conds conds = new Conds();
        conds.equal("del_flag", Constants.DEL_FLAG_0);
        List<Cosconfig> cosconfigList = cosconfigService.fetchSearchByPage(conds, null, 0, 0);
        //for (Cosconfig cosconfig : cosconfigList) {
        model.addAttribute("cosconfigList", cosconfigList);
        //}
        Long id = material.getId();
        if (id != null) {
            material = materialUploadService.fetchById(id);
            if (material.getCategoryid() == 0) {
                material.setCategoryName(rootQCName);
            } else {
                MaterialCategory category = materialCategoryService.fetchById(material.getCategoryid());
                material.setCategoryName(category.getName());
            }
        }
        model.addAttribute("data", material);

        return "upload/materialUploadform";
    }

    @RequiresPermissions(value = MATERIAL_EDIT)
    @RequestMapping("/upload")
    @ResponseBody
    public JSONObject upload(HttpServletRequest request, Long cosconfigId, Long categoryId, MultipartHttpServletRequest mhsr) {
        JSONObject rtnJson = new JSONObject();
        Long userid = UserUtils.getUser().getId();
        //全部本地存储
        cosconfig = null;
//        if (cosconfigId != 0) {
//            cosconfig = cosconfigService.fetchById(cosconfigId);
//        } else {
//            cosconfig = null;
//        }
        List<MultipartFile> files = mhsr.getFiles("upfile");

        for (MultipartFile file : files) {
            Material material = new Material();
            String fileName = file.getOriginalFilename().substring(0, file.getOriginalFilename().lastIndexOf("."));
            material.setTitle(fileName);

            material.setCategoryid(categoryId);

            Map<String, Object> params = new HashMap<String, Object>();
            params.put("titlePrefix", fileName);

            Conds conds = new Conds();
            conds.equal("del_flag", Constants.DEL_FLAG_0);
            conds.like("title", fileName + "-");

            Integer counts = materialUploadService.count(conds);

            material.setTitle(fileName + "-" + counts);

            String url = "";
            if (cosconfig == null) {
                //上传到本地
                Map<String, Object> resultMap = uploadMedia(UserUtils.getmpaccounts(request), material.getTitle(), file, request);
                url = resultMap.get("mediaUrl").toString();
                String key = resultMap.get("localPath").toString();
                material.setKey(key);
                material.setUploadType("local");
                material.setUrl(url);

            } else {
                boolean resultTemp = getUploadService(cosconfig.getCosType());
                Map<String, Object> jsonObject = null;
                CosFileUploader cosFileUploader = new CosFileUploader(cosconfig, cosService);
                String format = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
                try {
//                    jsonObject=cosFileUploader.uploadFile(file.getBytes(),format);
                    jsonObject = UploadUtils.uploadImageFilesByQcloudInputStearm(request, "newRecommend", file, "/gogi/newReCommend/");
                } catch (Exception e) {
                    log.error(e.getMessage());
                }
                material.setKey(null);
                material.setUploadType(cosconfig.getCosType());
                url = jsonObject.get("fileUrl") == null ? "" : jsonObject.get("fileUrl").toString();
                url += SystemConfig.p.getProperty("Qcloud_STYLE_NAME");
                material.setUrl(url);
                material.setCosId(cosconfigId);
            }

            rtnJson.put("url", url);
            rtnJson.put("title", material.getTitle());
            rtnJson.put("original", material.getTitle());


            material.setCreateBy(userid);
            material.setDelFlag("0");
            material.setUpdateBy(userid);
            Boolean result = materialUploadService.save(material);


        }
        rtnJson.put("state", "SUCCESS");
        return rtnJson;
    }


    /**
     * 创建素材
     * ali:阿里
     * qiniu:七牛
     * qcloud：腾讯
     * local:本地
     */
    @RequiresPermissions(value = MATERIAL_EDIT)
    @RequestMapping("/formData")
    @ResponseBody
    public JSONObject formData(HttpServletRequest request, Material material, Long cosconfigId, MultipartHttpServletRequest mhsr, MultipartFile file) {
        JSONObject rtnJson = new JSONObject();
        Long userid = UserUtils.getUser().getId();
        cosconfig = cosconfigService.fetchById(cosconfigId);
        MultipartFile imgArr = mhsr.getFile("qqfile");
        //未取标题使用uuid作为名称
        String titlePrefix = StringUtils.isBlank(material.getTitle()) ? UUID.randomUUID().toString().replaceAll("-", "") : material.getTitle();
        int number = 0;
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("titlePrefix", titlePrefix);
        Map<String, Object> mapNumber = materialUploadService.fetchSeaechByNumber(params);
        if (mapNumber != null) {
            Object obj = mapNumber.get("number");
            try {
                number = Integer.valueOf(obj.toString());
            } catch (Exception e) {

            }
        }
        number += 1;
        material.setTitle(titlePrefix + "-" + number);
        try {
            if (cosconfig == null) {
                //上传到本地
                Map<String, Object> resultMap = uploadMedia(UserUtils.getmpaccounts(request), material.getTitle(), imgArr, request);
                String url = resultMap.get("mediaUrl").toString();
                String key = resultMap.get("localPath").toString();
                material.setKey(key);
                material.setUploadType("local");
                material.setUrl(url);
            } else {
                boolean resultTemp = getUploadService(cosconfig.getCosType());
                JSONObject jsonObject = null;
                CosFileUploader cosFileUploader = new CosFileUploader(cosconfig, cosService);
                String format = imgArr.getOriginalFilename().substring(imgArr.getOriginalFilename().lastIndexOf(".") + 1);
                //  jsonObject=cosFileUploader.uploadFile(imgArr.getBytes(),format);

                try {
                    Map<String, Object> map = UploadUtils.uploadImageFilesByQcloudInputStearm(request, "newRecommend", imgArr, "/gogi/newReCommend/");  // cosFileUploader.uploadFile(file.getBytes(),format);
                    material.setKey(null);
                    material.setUploadType(cosconfig.getCosType());
                    String url = map.get("fileUrl") == null ? "" : map.get("fileUrl").toString();
                    url += SystemConfig.p.getProperty("Qcloud_STYLE_NAME");
                    material.setUrl(url);
                    material.setCosId(cosconfigId);
                } catch (Exception e) {
                    log.error(e.getMessage());
                }


            }
            material.setCreateBy(userid);
            material.setDelFlag("0");
            material.setUpdateBy(userid);
            Boolean result = materialUploadService.save(material);
        } catch (Exception e) {
            rtnJson.put("errorNo", 1);
            e.printStackTrace();
        }
        rtnJson.put("success", "ok");
        return rtnJson;
    }

    //删除数据
    @RequiresPermissions(value = MATERIAL_EDIT)
    @RequestMapping("/delete")
    @ResponseBody
    public JSONObject delete(Long id) {
        JSONObject rtnJosn = new JSONObject();
        try {
            Material material = materialUploadService.fetchById(id);
            boolean resultTemp = getUploadService(material.getUploadType());
            if (!resultTemp) {
                //删除本地图片
                File file = new File(material.getKey());
                // 路径为文件且不为空则进行删除
                if (file.isFile() && file.exists()) {
                    file.delete();
                }
            }
            boolean result = materialUploadService.delete(id);
            if (result) {
                rtnJosn.put("errorNo", 0);
                return rtnJosn;
            }
        } catch (Exception e) {
            rtnJosn.put("errorNo", 1);
            e.printStackTrace();
        }
        return rtnJosn;
    }

    /**
     * 上传到本地
     */
    public static Map<String, Object> uploadMedia(Long userId, String moduleName, MultipartFile file, HttpServletRequest request) {
        Map<String, Object> params = new HashedMap();
        BufferedInputStream bis = null;
        FileOutputStream fos = null;
        HttpURLConnection conn = null;
        String finalFileName = "";
        try {
            String dir = USER_IMAGES_DIR + "";
            File ff = new File(dir);
            if (!ff.exists()) {
                ff.mkdir();
            }
            String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));//文件扩展名
            String fileName = UUID.randomUUID().toString();
            finalFileName = fileName + suffix;

            String realPath = dir + File.separator + finalFileName;
            params.put("localPath", realPath);
            File localFile = new File(realPath);
            if (!localFile.exists() && !localFile.isFile()) {
                file.transferTo(localFile);
            }
        } catch (IOException e) {
            log.error("上传文件失败：{}", e.getMessage());
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    log.error("上传文件失败 IOException：{}", e.getMessage());
                }
            }

            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    log.error("上传文件失败 IOException：{}", e.getMessage());
                }
            }

            if (conn != null) {
                conn.disconnect();
            }
        }
        String mediaUrl = ImageUrlUtils.formatImageUrl(finalFileName, "");//文件访问URL
        params.put("mediaUrl", mediaUrl);
        return params;
    }

    //获取上传服务位置
    private boolean getUploadService(String cosType) {
        if (cosType.equals("qcloud")) {
            //上传到腾讯
            cosService = new QcloudStorageService();
        } else if (cosType.equals("ali")) {
            //上传到阿里
            cosService = new AliOssStorageService();
        } else if (cosType.equals("qiniu")) {
            //上传到七牛
            cosService = new QiniuStorageService();
        } else {
            //上传到本地
            return false;
        }
        return true;
    }

}
