package com.yunfeiyun.agmp.common.framework.manager;

import com.yunfeiyun.agmp.common.constant.ErrorCode;
import com.yunfeiyun.agmp.common.constant.ResConstants;
import com.yunfeiyun.agmp.common.exception.BizException;
import com.yunfeiyun.agmp.common.framework.oss.cloud.OSSFactory;
import com.yunfeiyun.agmp.common.framework.web.service.PolicyService;
import com.yunfeiyun.agmp.common.web.system.domain.ResBuilder;
import com.yunfeiyun.agmp.common.web.system.domain.SysRes;
import com.yunfeiyun.agmp.common.web.system.service.ISysResService;
import com.yunfeiyun.agmp.common.core.domain.model.LoginUser;
import com.yunfeiyun.agmp.common.utils.DateUtils;
import com.yunfeiyun.agmp.common.utils.file.FileUploadUtils;
import com.yunfeiyun.agmp.common.utils.file.FileUtils;
import com.yunfeiyun.agmp.common.utils.spring.SpringUtils;
import com.yunfeiyun.agmp.common.utils.uuid.IdUtils;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class ResManager {

    private static final Logger sys_res_logger = LoggerFactory.getLogger("sys-res");

    @Resource
    private ISysResService sysResService;


    /**
     查询资源
     */
    public SysRes queryRes(String resId){
        if(SysRes.empty(resId)) return SysRes.build();
        return sysResService.selectSysResByResId(resId);
    }

    /**
     查询资源
     */
    public  List<SysRes> queryRes(String resId,int n){
        SysRes sysRes = new SysRes();
        sysRes.setResId( resId );
        if(SysRes.empty(resId)) return SysRes.builds();
        return sysResService.selectSysResList(sysRes);
    }


    /**
     查询资源
     */
    public  List<SysRes> queryRes(String resBusid, String resBiztype){
        if(SysRes.empty(resBusid)) return SysRes.builds();
        return sysResService.selectResByBusId(resBusid,resBiztype);
    }

    /**
     查询资源
     */
    public  SysRes queryRes(String resBusid, String resBiztype,int type){
        if(SysRes.empty(resBusid)) return SysRes.build();
        List<SysRes> sysResList = sysResService.selectResByBusId(resBusid,resBiztype);
        SysRes sysRes = sysResList !=null && sysResList.size() > 0 ? sysResList.get(0): new SysRes();
        return sysRes;
    }

    /**
     查询资源
     */
    public  List<SysRes> queryRes(String resBusid, ResConstants.BizType bizType, ResConstants.mediaType mediaType ){
        if(SysRes.empty(resBusid)) return SysRes.builds();
        return sysResService.selectResByBusId(resBusid, bizType.getKey(),mediaType.getValue());
    }




    /**
     查询资源
     */
    public  List<SysRes> queryRes(String[] resBusids,String resBiztype){
        if(SysRes.empty(Arrays.asList(resBusids))) return SysRes.builds();
        //return sysResService.selectResByBusIdes(resBusids,resBiztype);
        return sysResService.selectResByBusIds(Arrays.asList(resBusids),resBiztype);
    }

    /**
     查询资源
     */
    public  List<SysRes> queryRes(List<String> resBusids,String resBiztype) {
        if(SysRes.empty(resBusids)) return SysRes.builds();
        return sysResService.selectResByBusIds(resBusids,resBiztype);
    }

    /**
     查询资源
     */
    public  List<SysRes> queryRes(String[] resids){
            if(SysRes.empty(Arrays.asList(resids))) return SysRes.builds();
            //return sysResService.selectResByResIdes(resids);
            return sysResService.selectResByResIds(Arrays.asList(resids));
    }

    /**
     查询资源
     */
    public  List<SysRes> queryRes(List<String> resids){
        if(SysRes.empty(resids)) return SysRes.builds();
        return sysResService.selectResByResIds(resids);
    }


    /**
     查询资源版本2
     */
    public  List<SysRes> queryResV2(List<String> resids){
        if(SysRes.empty(resids)) return SysRes.builds();
        return sysResService.selectResByResIdsV2(resids);
    }

    /**
     单个资源上传
     */
    public synchronized SysRes uploadRes(ResConstants.BizType bizType, ResConstants.mediaType mediaType, String resBusid ,  MultipartFile file, LoginUser user) throws  Exception{
       try{
            SysRes sysRes = new ResBuilder()
                    .setResMediatype(mediaType)
                    .setResBiztype(bizType)
                    .setResBusId(resBusid)
                    .setFile(file)
                    .setResCreator(user.getUserId())
                    .setResCreatorname(user.getUsername())
                    .setResCreateddate(DateUtils.dateTimeNow())
                    .build();
            sysResService.insertSysRes(sysRes);
            if(SpringUtils.getBean(PolicyService.class).isOssCloudPolicy()){
                sysRes.setResUrl( sysRes.getResOssUrl() );
            }
            return sysRes;
        }catch (Exception e){
           throw new BizException(ErrorCode.UPLOAD_RESID_FAIL.getCode(),ErrorCode.UPLOAD_RESID_FAIL.getMessage());
       }

    }



    /**
     批量资源上传
     */
    public synchronized List<SysRes> uploadRes(ResConstants.BizType bizType, ResConstants.mediaType mediaType, String resBusid , List<MultipartFile> files , LoginUser user) throws  Exception{
        try{
            List<SysRes> sysReses = new ResBuilder()
                    .setResMediatype(mediaType)
                    .setResBiztype(bizType)
                    .setResBusId(resBusid)
                    .setFiles(files)
                    .setResCreator(user.getUserId())
                    .setResCreatorname(user.getUsername())
                    .setResCreateddate(DateUtils.dateTimeNow())
                    .build(files,1);
            sysResService.insertSysReses(sysReses);
            if(SpringUtils.getBean(PolicyService.class).isOssCloudPolicy()){
                List<SysRes> sysResNew = sysReses.stream().map(m -> {
                    m.setResUrl( m.getResOssUrl() );
                    return m;
                }).collect(Collectors.toList());
                return sysResNew;
            }
            return sysReses;
        }catch (Exception e){
            throw new BizException(ErrorCode.UPLOAD_RESID_FAIL.getCode(),ErrorCode.UPLOAD_RESID_FAIL.getMessage());
        }
    }



    /**
     单个资源上传-OSS服务
     */
    public synchronized String uploadOssRes(MultipartFile file,ResConstants.BizType bizType) throws  Exception{
        try{
            if(SpringUtils.getBean(PolicyService.class).isOssCloudPolicy()){
                String ossCloudUrl = OSSFactory.build().uploadSuffix(file.getBytes(), FileUploadUtils.getExtension(file) , bizType.getPath(),FilenameUtils.getBaseName(file.getOriginalFilename()));
                return ossCloudUrl;
            }
            return "-1";
        }catch (Exception e){
            throw new BizException(ErrorCode.UPLOAD_OSS_FAIL.getCode(),ErrorCode.UPLOAD_OSS_FAIL.getMessage());
        }

    }


    /**
     单个资源更新单个业务Id
     */
    public synchronized int updateRes(String resId ,String resBusid){
        if(SysRes.empty(resId)) return 0;
        try{
            SysRes sysRes = new ResBuilder()
                    .setResId(resId)
                    .setResBusId(resBusid)
                    .build();
            return sysResService.updateSysRes(sysRes);
        }catch (Exception e){
            throw new BizException(ErrorCode.RES_SAVE_FAIL.getCode(),ErrorCode.RES_SAVE_FAIL.getMessage());
        }
    }


    /**
     多个资源更新同一个业务Id
     */
    public synchronized int updateRes(List<String> resIds , String resBusid) {
        if(SysRes.empty(resIds)) return 0;
        try{
            List<SysRes> sysRess = new ResBuilder()
                    .setResIds(resIds)
                    .setResBusId(resBusid)
                    .build(resIds);
            return sysResService.updateSysResByResIds(sysRess);
        }catch (Exception e){
            throw new BizException(ErrorCode.RES_SAVE_FAIL.getCode(),ErrorCode.RES_SAVE_FAIL.getMessage());
        }
    }


    /**
     多个资源更新同一个业务Id
     */
    public synchronized int updateRes(List<String> resIds , String resBusid,int type){
        if(SysRes.empty(resBusid) || SysRes.empty(resIds)) return 0;
        try{
            return sysResService.updateSysResByResIdls(resIds , resBusid);
        }catch (Exception e){
            throw new BizException(ErrorCode.RES_SAVE_FAIL.getCode(),ErrorCode.RES_SAVE_FAIL.getMessage());
        }
    }


    /**
     多个资源更新同一个业务Id
     */
    public synchronized int updateRes(String[] resIds , String resBusid) {
        if(SysRes.empty(Arrays.asList(resIds)) || SysRes.empty(resBusid)) return 0;
        try{
            List<SysRes> sysRess = new ResBuilder()
                    .setResIdes(resIds)
                    .setResBusId(resBusid)
                    .build(resIds);
            return sysResService.updateSysResByResIds(sysRess);
        }catch (Exception e){
            throw new BizException(ErrorCode.RES_SAVE_FAIL.getCode(),ErrorCode.RES_SAVE_FAIL.getMessage());
        }
    }


    /**
     多个资源更新同一个业务Id
     */
    public synchronized int updateRes(String[] resIds , String resBusid,int type){
        if(SysRes.empty(Arrays.asList(resIds)) || SysRes.empty(resBusid)) return 0;
        try{
            return sysResService.updateSysResByResIdes(resIds,resBusid);
        }catch (Exception e){
            throw new BizException(ErrorCode.RES_SAVE_FAIL.getCode(),ErrorCode.RES_SAVE_FAIL.getMessage());
        }
    }


    /**
     单个资源删除
     */
    /**
     单个资源更新单个业务Id
     */
    public synchronized int deleteRes(String resId,String resOssUrl){

        try{
            if(SpringUtils.getBean(PolicyService.class).isOssCloudPolicy()){
                if(!SysRes.empty(resOssUrl)){
                    OSSFactory.build().delete(Arrays.asList(resOssUrl));
                }
            }
            if(SysRes.empty(resId)) return 0;
            SysRes res = queryRes(resId);
            FileUtils.deleteFile(res.getResLocalUrl(),1);
            return sysResService.deleteSysResByResId(resId);
        }catch (Exception e){
            throw new BizException(ErrorCode.RES_DEL_FAIL.getCode(),ErrorCode.RES_DEL_FAIL.getMessage());
        }
    }


    /**
     批量资源删除
     */
    /**
     单个资源更新单个业务Id
     */
    public synchronized int deleteRes(String[] resBusIds,String[] resOssUrl){
        try{
            if(SpringUtils.getBean(PolicyService.class).isOssCloudPolicy()){
                if(!SysRes.empty(Arrays.asList(resOssUrl))) {
                    OSSFactory.build().delete(Arrays.asList(resOssUrl));
                }
            }
            if(SysRes.empty(Arrays.asList(resBusIds))) return 0;
            List<SysRes> resList = queryRes(resBusIds,null);
            FileUtils.deleteFiles(SysRes.from(resList,2));
            return sysResService.deleteSysResbs(resBusIds);
        }catch (Exception e){
            throw new BizException(ErrorCode.RES_DEL_FAIL.getCode(),ErrorCode.RES_DEL_FAIL.getMessage());
        }
    }


    /**
     批量资源删除
     */
    /**
     单个资源更新单个业务Id
     */
    public synchronized int deleteRes(String[] resBusIds){
        if(SysRes.empty(Arrays.asList(resBusIds))) return 0;
        try{
            List<SysRes> resList = queryRes(resBusIds,null);
            if(SpringUtils.getBean(PolicyService.class).isOssCloudPolicy()){
                List<String> resOssUrl= new ArrayList<>();
                resList.forEach(v->{
                    resOssUrl.add(v.getResOssUrl());
                });
                OSSFactory.build().delete(resOssUrl);
            } FileUtils.deleteFiles(resList);
            return sysResService.deleteSysResbs(resBusIds);
        }catch (Exception e){
            throw new BizException(ErrorCode.RES_DEL_FAIL.getCode(),ErrorCode.RES_DEL_FAIL.getMessage());
        }
    }


    /**
     批量资源删除
     */
    /**
     单个资源更新单个业务Id
     */
    public synchronized int deleteRes(List<String> resBusIds , String[] resOssUrl,int type){

        try{
            if(SpringUtils.getBean(PolicyService.class).isOssCloudPolicy()){
                if(!SysRes.empty(Arrays.asList(resOssUrl))) {
                    OSSFactory.build().delete(Arrays.asList(resOssUrl));
                }
            }
            if(SysRes.empty(resBusIds)) return 0;
            List<SysRes> resList = queryRes(resBusIds,null);
            FileUtils.deleteFiles(resList);
            return sysResService.deleteSysResbs(SysRes.from(resBusIds));
        }catch (Exception e){
            throw new BizException(ErrorCode.RES_DEL_FAIL.getCode(),ErrorCode.RES_DEL_FAIL.getMessage());
        }
    }



    /**
     批量资源删除
     */
    public synchronized int deleteRes(SysRes[] res){
        try{
            List<String> resOssUrl= new ArrayList<>();
            if(SpringUtils.getBean(PolicyService.class).isOssCloudPolicy()){
                Arrays.stream(res).collect(Collectors.toList()).forEach(v->{
                    resOssUrl.add(v.getResOssUrl());
                });
                OSSFactory.build().delete(resOssUrl);
            }
            List<SysRes> resList = queryRes(SysRes.from(Arrays.asList(res),2).stream().map(SysRes::getResId).collect(Collectors.toList()));
            FileUtils.deleteFiles(resList);
            return sysResService.deleteSysResList(res);
        }catch (Exception e){
            throw new BizException(ErrorCode.RES_DEL_FAIL.getCode(),ErrorCode.RES_DEL_FAIL.getMessage());
        }
    }


    /**
     批量资源删除
     */
    public synchronized int deleteRes(List<SysRes> res){
        try{
            List<String> resOssUrl = new ArrayList<>();
            if(SpringUtils.getBean(PolicyService.class).isOssCloudPolicy()){
                res.forEach(v->{
                    resOssUrl.add(v.getResOssUrl());
                });
                OSSFactory.build().delete(resOssUrl);
            }
            List<SysRes> resList = queryRes(SysRes.from(res.stream().map(SysRes::getResId).collect(Collectors.toList())));
            FileUtils.deleteFiles(resList);
            return sysResService.deleteSysResList(res);
        }catch (Exception e){
            throw new BizException(ErrorCode.RES_DEL_FAIL.getCode(),ErrorCode.RES_DEL_FAIL.getMessage());
        }
    }


    /**
     批量资源删除
     */
    public synchronized int clearRes(List<SysRes> res){
        try{
            return sysResService.cleanSysRes(res);
        }catch (Exception e){
            throw new BizException(ErrorCode.RES_DEL_FAIL.getCode(),ErrorCode.RES_DEL_FAIL.getMessage());
        }
    }

    /**
     批量资源删除
     */
    public synchronized int deleteRes(String[] resIds,int type ){
        try{
            List<String> resOssUrl = new ArrayList<>();
            List<SysRes> resList = queryRes(SysRes.from(Arrays.asList(resIds)).stream().collect(Collectors.toList()));
            if(SpringUtils.getBean(PolicyService.class).isOssCloudPolicy()){
                resList.forEach(v->{
                    resOssUrl.add(v.getResOssUrl());
                });
                OSSFactory.build().delete(resOssUrl);
            }
            FileUtils.deleteFiles(resList);
            return sysResService.deleteSysResByResIds(resIds);
        }catch (Exception e){
            throw new BizException(ErrorCode.RES_DEL_FAIL.getCode(),ErrorCode.RES_DEL_FAIL.getMessage());
        }
    }


    /**
     批量资源删除
     */
    public synchronized int deleteRes(List<String> resIds,String type ){
        try{
            List<SysRes> resList = queryRes(SysRes.from(resIds).stream().collect(Collectors.toList()));
            return sysResService.deleteSysResls(resIds);
        }catch (Exception e){
            throw new BizException(ErrorCode.RES_DEL_FAIL.getCode(),ErrorCode.RES_DEL_FAIL.getMessage());
        }
    }



    /**
     清理资源
     */
    /**
     */
    public synchronized int cleanRes(List<String> resIds){
        String IdDeq = IdUtils.fastUUID().toString().replaceAll("-", "");
        Date startDate = new Date();
        String remarkStart   = String.format("=====清理文件批次=[%s]  开始时间=[%s]  文件个数=[%d]  资源详情=[%s]=====", IdDeq, DateUtils.dateTimeNow() , resIds.size(), String.join(",", resIds) );
        sys_res_logger.info(remarkStart);
        if(resIds.size() == 0){
            Date endDate = new Date();
            String  timeSpan = DateUtils.timeOffset(endDate,startDate);
            String remarkEnd   = String.format("=====清理文件批次=[%s]  结束时间=[%s]  文件个数=[%d]  耗时=[%s]=====", IdDeq, DateUtils.dateTimeNow() , resIds.size(),timeSpan );
            sys_res_logger.info(remarkEnd);
            return -1;
        }
        List<SysRes> sysResList = queryResV2(resIds);
        if(sysResList.size()  == 0) {
            Date endDate = new Date();
            String  timeSpan = DateUtils.timeOffset(endDate,startDate);
            String remarkEnd   = String.format("=====清理文件批次=[%s]  结束时间=[%s]  文件个数=[%d]  耗时=[%s]=====", IdDeq, DateUtils.dateTimeNow() , resIds.size(),timeSpan );
            sys_res_logger.info(remarkEnd);
            return -1;
        }
        List<String> localFiles = sysResList.stream().map(sysRes -> {
            return FileUploadUtils.getDefaultBaseDir() + sysRes.getResUrl();
        }).collect(Collectors.toList());
        List<String> cloudFiles = sysResList.stream().map(sysRes -> {
            return sysRes.getResOssUrl();
        }).collect(Collectors.toList());
        String remarkStep1   = String.format(" 清理文件批次=[%s]  开始清理本地文件,文件个数=[%d]", IdDeq,cloudFiles.size() );
        sys_res_logger.info(remarkStep1);
        List<String> localDeleteFiles = localFiles.stream().map(file -> {
            if(FileUtils.deleteFile(file)){
                return  file;
            }
            return "";
        }).collect(Collectors.toList());
        String remarkStep2   = String.format(" 清理文件批次=[%s]  开始清理Cloud文件,文件个数=[%d]", IdDeq,cloudFiles.size() );
        sys_res_logger.info(remarkStep2);
//        if(SpringUtils.getBean(PolicyService.class).isOssCloudPolicy()){
//            OSSFactory.build().delete(cloudFiles);
//        }
        String remarkStep3   = String.format(" 清理文件批次=[%s]  开始清理数据库文件 ,文件个数=[%d] ", IdDeq ,sysResList.size());
        sys_res_logger.info(remarkStep3);
        int n = 0;
        if(sysResList.size() > 0){
            n = clearRes(sysResList);
        }
        Date endDate = new Date();
        String  timeSpan = DateUtils.timeOffset(endDate,startDate);
        String remarkEnd   = String.format("=====清理文件批次=[%s]  结束时间=[%s]  文件个数=[%d]  耗时=[%s]=====", IdDeq, DateUtils.dateTimeNow() , resIds.size(),timeSpan );
        sys_res_logger.info(remarkEnd);
        return n;
    }

}
