package com.org.oss.service;

import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.org.oss.entity.SysOss;
import com.org.oss.mapper.SysOssMapper;
import com.org.system.enums.YesOrNoState;
import com.org.utils.AjaxResult;
import com.org.utils.SecurityUtil;
import com.org.utils.StringUtils;
import com.org.utils.exception.CustomException;
import com.org.utils.upload.UpLoadUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class SysOssService extends ServiceImpl<SysOssMapper, SysOss> {

    /**
     * 分页查询
     *
     * @param sysOss
     * @return
     */
    public List<SysOss> queryList(SysOss sysOss){
        log.info("SysOssService - queryList sysOss:{}", sysOss);
        LambdaQueryWrapper<SysOss> queryWrapper = new LambdaQueryWrapper<>();
        if(StringUtils.isNotEmpty(sysOss.getFileName())) queryWrapper.like(SysOss::getFileName, sysOss.getFileName());

        return list(queryWrapper);
    }

    /**
     * 文件上传
     *
     * @param file
     * @param sourceId
     * @param fileType
     * @return
     * @throws IOException
     */
    public AjaxResult upload(MultipartFile file, String sourceId, String fileType) throws IOException {
        log.info("SysOssService - upload file:{}", file);
        log.info("SysOssService - upload sourceId:{}", sourceId);
        log.info("SysOssService - upload fileType:{}", fileType);

        // 上传文件
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        String url = UpLoadUtil.uploadSuffix(file.getBytes(), suffix);
        String[] urlArr = url.split("/");
        String fileName = urlArr[urlArr.length - 1];

        // String realPath = url.replace(UpLoadUtil.domain, "");
        String realPath = url.replace(UpLoadUtil.proxyServer, "");
        realPath = UpLoadUtil.diskPath + realPath;

        // 保存文件信息
        SysOss sysOss = new SysOss();
        sysOss.setSourceId(sourceId);
        sysOss.setFileName(file.getOriginalFilename());
        sysOss.setNewName(fileName);
        sysOss.setFileType(fileType);
        sysOss.setRealPath(realPath);
        sysOss.setUrl(url);
        // 富文本上传图片 没带token 增加是否登录判断
        if (SecurityUtil.isLogin()) sysOss.setCreateBy(SecurityUtil.getUserId());
        sysOss.setCreateTime(new Date());
        sysOss.setIsDelete(YesOrNoState.NO.getState());

        save(sysOss);
        // 返回兼容UEditor的参数
        return AjaxResult.success().put("url", url)
                .put("name", sysOss.getFileName())
                .put("id", sysOss.getId())
                .put("uid", sysOss.getId())
                .put("createTime", sysOss.getCreateTime());
    }

    /**
     * 删除文件上传记录
     *
     * @param ids
     */
    public void delete(Integer[] ids){
        log.info("SysOssService - delete ids:{}", ids);

        for (Integer id : ids) {
            try {
                SysOss oss = getById(id);
                log.info("SysOssService - delete oss:{}", oss);

                FileUtil.del(oss.getRealPath());
            } catch (Exception err) {
                log.error("删除文件出现错误:" + id, err);
            }
        }
        removeByIds(Arrays.asList(ids));
    }

    /**
     * 根据文件全路径数组删除上传文件
     *
     * @param urls
     */
    public void deleteByUrl(String[] urls){
        log.info("SysOssService - deleteByUrl urls:{}", urls);

        for (String url : urls) {
            try {
                LambdaQueryWrapper<SysOss> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(SysOss::getUrl, url);

                SysOss sysOss = getOne(queryWrapper);
                log.info("SysOssService - deleteByUrl sysOss:{}", sysOss);

                FileUtil.del(sysOss.getRealPath());
                removeById(sysOss.getId());
            } catch (Exception err) {
                log.error("删除文件出现错误:" + url, err);
            }
        }
    }

    public void show(String dateDir, String fileName){
        log.info("SysOssService - show dateDir:{}", dateDir);
        log.info("SysOssService - show fileName:{}", fileName);

        fileName = UpLoadUtil.diskPath + "/" + dateDir + "/" + fileName;
        log.info("SysOssService - show fileName:{}", fileName);

        SysOss oss = findByRealPath(fileName);

        // 如果是视频文件 则走视频文件方法
        if(fileName.toLowerCase().endsWith("mp4") || fileName.toLowerCase().endsWith("flv")
                || fileName.toLowerCase().endsWith("avi") || fileName.toLowerCase().endsWith("rm")
                || fileName.toLowerCase().endsWith("rmvb") || fileName.toLowerCase().endsWith("wmv")
                || fileName.toLowerCase().endsWith("m3u8")) {
            UpLoadUtil.getVideo(fileName);
            return;
        }

        UpLoadUtil.getFile(fileName, oss.getFileName());
    }

    public void show(String id){
        log.info("SysOssService - show id:{}", id);

        SysOss oss = getById(id);
        if(oss == null || StringUtils.isEmpty(oss.getId())) return ;

        String fileName = oss.getRealPath();
        log.info("SysOssService - show fileName:{}", fileName);

        // 如果是视频文件 则走视频文件方法
        if(fileName.toLowerCase().endsWith("mp4") || fileName.toLowerCase().endsWith("flv")
                || fileName.toLowerCase().endsWith("avi") || fileName.toLowerCase().endsWith("rm")
                ||fileName.toLowerCase().endsWith("rmvb") || fileName.toLowerCase().endsWith("wmv")) {
            UpLoadUtil.getVideo(fileName);
            return;
        }

        UpLoadUtil.getFile(fileName, oss.getFileName());
    }


    /**
     * 通过url获取sysOss
     * @param fileUrl
     */
    public SysOss findByUrl(String fileUrl) {
        log.info("SysOssService - findByUrl fileUrl:{}", fileUrl);
        SysOss sysOss = baseMapper.findByUrl(fileUrl);
        log.info("SysOssService - findByUrl sysOss:{}", sysOss);

        if (sysOss == null || StringUtils.isNull(sysOss.getId())) throw new CustomException("文件未找到！");

        return sysOss;
    }

    /**
     * 通过url获取sysOss
     * @param realPath
     */
    public SysOss findByRealPath(String realPath) {
        log.info("SysOssService - findByRealPath realPath:{}", realPath);
        SysOss sysOss = baseMapper.findByRealPath(realPath);
        log.info("SysOssService - findByRealPath sysOss:{}", sysOss);

        if (sysOss == null || StringUtils.isNull(sysOss.getId())) throw new CustomException("文件未找到！");

        return sysOss;
    }


    public AjaxResult uploadImg(MultipartFile file, String sourceId, String fileType, long fileSize) throws IOException {
        log.info("SysOssService - uploadImg file:{}", file);
        log.info("SysOssService - uploadImg sourceId:{}", sourceId);
        log.info("SysOssService - uploadImg fileType:{}", fileType);
        log.info("SysOssService - uploadImg fileSize:{}", fileSize);

        // 上传文件
        /*//压缩图片到指定大小以内
        byte[] bytes = PicUtils.compressPicForScale(file.getBytes(), fileSize);
        ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
        String suffix = ".jpg";*/
        // 上传文件
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        String url = UpLoadUtil.uploadSuffix(file.getBytes(), suffix);
        String[] urlArr = url.split("/");
        String fileName = urlArr[urlArr.length - 1];

        String realPath = url.replace(UpLoadUtil.proxyServer, "");
        realPath = UpLoadUtil.diskPath + realPath;
        // String realPath = url.replace(UpLoadUtil.domain, "");

        String originalFilename = file.getOriginalFilename();
        String suffix1 = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
        originalFilename = originalFilename.substring(0, originalFilename.lastIndexOf(".")) + suffix1;

        // 保存文件信息
        SysOss sysOss = new SysOss();
        sysOss.setSourceId(sourceId);
        sysOss.setFileName(originalFilename);
        sysOss.setNewName(fileName);
        sysOss.setFileType(fileType);
        sysOss.setRealPath(realPath);
        sysOss.setUrl(url);
        sysOss.setCreateBy(SecurityUtil.getUserId());
        sysOss.setCreateTime(new Date());
        sysOss.setIsDelete(YesOrNoState.NO.getState());

        save(sysOss);
        // 返回兼容UEditor的参数
        return AjaxResult.success().put("url", url)
                .put("name", sysOss.getFileName())
                .put("id", sysOss.getId())
                .put("uid", sysOss.getId())
                .put("createTime", sysOss.getCreateTime());
    }



    /**
     * COS工作流回调
     * @param callbackStr

    public void cosCallback(String callbackStr) {
        log.info("SysOssService - cosCallback callbackStr:{}", callbackStr);

        JSONObject jsonObject = JSONUtil.parseObj(callbackStr);
        JSONObject workflowExecution = jsonObject.getJSONObject("WorkflowExecution");

        String state = workflowExecution.getStr("State");
        log.info("SysOssService - cosCallback state:{}", state);

        if(!"Success".equals(state)) return;

        String object = workflowExecution.getStr("Object");
        log.info("SysOssService - cosCallback object:{}", object);

        if(Validator.isNotEmpty(object)){
            String url = object;
            String bakUrl = String.format("%s_bak%s", object.substring(0, object.lastIndexOf(".")), object.substring(object.lastIndexOf(".")));
            String transcodingUrl = String.format("%s_transcoding%s", object.substring(0, object.lastIndexOf(".")), object.substring(object.lastIndexOf(".")));

            log.info("SysOssService - cosCallback url:{}", url);
            log.info("SysOssService - cosCallback bakUrl:{}", bakUrl);
            log.info("SysOssService - cosCallback transcodingUrl:{}", transcodingUrl);

            // 备份源视频文件
            UpLoadUtil.copyObject(url, bakUrl);
            UpLoadUtil.deleteObject(url);

            // 转移转码后的视频文件
            UpLoadUtil.copyObject(transcodingUrl, url);
            UpLoadUtil.deleteObject(transcodingUrl);
        }
    }
     */
}
