package com.fdkankan.scene.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fdkankan.common.constant.ErrorCode;
import com.fdkankan.common.constant.ServerCode;
import com.fdkankan.common.constant.TbStatus;
import com.fdkankan.common.constant.UploadFilePath;
import com.fdkankan.common.exception.BusinessException;
import com.fdkankan.common.response.ResultData;
import com.fdkankan.common.user.SSOLoginHelper;
import com.fdkankan.common.user.SSOUser;
import com.fdkankan.common.util.BASE64DecodedMultipartFile;
import com.fdkankan.common.util.FileUtil;
import com.fdkankan.fyun.oss.UploadToOssUtil;
import com.fdkankan.scene.entity.ScenePro;
import com.fdkankan.scene.entity.SceneUpload;
import com.fdkankan.scene.mapper.ISceneUploadMapper;
import com.fdkankan.scene.service.ISceneProService;
import com.fdkankan.scene.service.ISceneUploadService;
import com.fdkankan.scene.vo.DeleteFileParamVO;
import com.fdkankan.scene.vo.UploadContentParamVO;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 
 * @since 2022-01-19
 */
@Service
public class SceneUploadServiceImpl extends ServiceImpl<ISceneUploadMapper, SceneUpload> implements ISceneUploadService {

    @Resource
    UploadToOssUtil uploadToOssUtil;
    @Value("${oss.point:http://oss-cn-shenzhen-internal.aliyuncs.com}")
    private String point;

    @Value("${oss.key:LTAIUrvuHqj8pvry}")
    private String key;

    @Value("${oss.secrey:JLOVl0k8Ke0aaM8nLMMiUAZ3EiiqI4}")
    private String secrey;

    @Value("${oss.bucket:4dkankan}")
    private String bucket;

    @Value("${oss.prefix.url}")
    private String ossUrlPrefix;

    @Autowired
    private SSOLoginHelper ssoLoginHelper;

    @Override
    public String uploads(String imgData,String fileName,String blzType,MultipartFile[] files,
        String sceneCode,Integer type,String token, String uploadPath) throws Exception{
        SSOUser ssoUser = ssoLoginHelper.loginCheck(token);
        Long userId = ssoUser == null ? null :ssoUser.getId();

        List<MultipartFile> multipartFiles = new ArrayList<>();
        if(StringUtils.isNotBlank(imgData)){
            MultipartFile file = BASE64DecodedMultipartFile.base64ToMultipart(imgData);
            multipartFiles.add(file);
        }
        if(files !=null && files.length >0){
            multipartFiles.addAll(Arrays.asList(files));
        }
        return this.uploadFiles(fileName,blzType,multipartFiles,sceneCode,type,userId,uploadPath);
    }

    @Override
    public ResultData delete(DeleteFileParamVO param) throws Exception {
        String userEditPath = String.format(UploadFilePath.USER_EDIT_PATH, param.getNum());
        List<String> filePaths = new ArrayList<>();
        Set<String> hasDelete = new HashSet<>();
        for (String fileName : param.getFileNames()) {
            if(hasDelete.contains(fileName)){
                continue;
            }
            hasDelete.add(fileName);
            String key = userEditPath + fileName;
            filePaths.add(key);
            uploadToOssUtil.delete(key);
        }

        this.update(new LambdaUpdateWrapper<SceneUpload>()
            .set(SceneUpload::getTbStatus, TbStatus.DELETE.code())
            .eq(SceneUpload::getNum, param.getNum())
            .eq(SceneUpload::getBizType, param.getBizType())
            .in(SceneUpload::getFilePath, filePaths)
            .eq(SceneUpload::getTbStatus, TbStatus.VALID.code()));

        return ResultData.ok();
    }

    public String uploadFiles(String sendFileName,String bizType,List<MultipartFile> files,
        String sceneCode, Integer type,Long userId, String uploadPath) throws Exception{
        if (StrUtil.isEmpty(sceneCode))
            throw new BusinessException(ServerCode.PARAM_REQUIRED, "num");
        if(CollUtil.isEmpty(files))
            throw new BusinessException(ServerCode.PARAM_REQUIRED, "files");
        if(StrUtil.isEmpty(bizType))
            throw new BusinessException(ServerCode.PARAM_REQUIRED, "bizType");

        List<String> urlList = new ArrayList<>();
        if(type != null && 1 == type){
            this.updateFileByPreFix(sceneCode,bizType);
        }
        for (MultipartFile file : files) {
            String fileName = file.getOriginalFilename();
            // 获取文件后缀
            String prefix = fileName.substring(fileName.lastIndexOf("."));
            File newFile = File.createTempFile(UUID.randomUUID().toString() ,prefix);
            file.transferTo(newFile);
            String realFileName = fileName;
            if(files.size() ==1 && StringUtils.isNotBlank(sendFileName)){
                realFileName = sendFileName ;
            }
            String ossPath = StrUtil.isNotBlank(uploadPath) ? uploadPath : (String.format(UploadFilePath.USER_EDIT_PATH ,sceneCode) + realFileName);
            try {
                uploadToOssUtil.upload2(newFile.getPath(),ossPath);
            }catch (Exception e){
                log.error(ossPath+"上传文件失败"+e);
                throw new BusinessException(ErrorCode.FAILURE_CODE_7013);
            }
            //String url =String.format("http://%s.%s/%s", bucket, point.replace("http://",""), ossPath);
            urlList.add(realFileName);

            FileUtil.delFile(newFile.getPath());
            //添加记录
            this.saveData(sceneCode,ossPath,bizType,userId);
        }
        StringBuilder returnString = new StringBuilder();
        for (String res : urlList) {
            if(StringUtils.isNotBlank(returnString)){
                returnString.append(",");
            }
            returnString.append(res);
        }
        return returnString.toString();
    }

    private void updateFileByPreFix(String sceneCode, String blzType) {
        LambdaQueryWrapper<SceneUpload> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SceneUpload::getNum,sceneCode)
                .eq(SceneUpload::getBizType,blzType)
                .eq(SceneUpload::getTbStatus,0);
        List<SceneUpload> list = this.list(queryWrapper);

        if(list != null && list.size() >0){
            for (SceneUpload sceneUpload : list) {
                try {
                    uploadToOssUtil.delete(sceneUpload.getFilePath());
                    this.removeEntity(sceneUpload);
                }catch (Exception e){
                    log.error(sceneUpload.getFilePath()+"删除oss文件失败",e);
                }
            }
        }
    }

    private void removeEntity(SceneUpload sceneUpload) {
        sceneUpload.setTbStatus(1);
        this.updateById(sceneUpload);
    }

    private void saveData(String sceneCode, String ossPath, String bizType,Long userId) {
        SceneUpload sceneUpload = new SceneUpload();
        sceneUpload.setNum(sceneCode);
        sceneUpload.setFilePath(ossPath);
        sceneUpload.setBizType(bizType);
        sceneUpload.setUploadUser(userId);
        this.save(sceneUpload);
    }

    @Override
    public String uploadContent(UploadContentParamVO param) throws Exception {

        String ossPath = param.getOssPath();
        String fileName = ossPath.substring(ossPath.lastIndexOf("/") + 1);
        if(StrUtil.isEmpty(fileName)){
            throw new BusinessException(ErrorCode.FAILURE_CODE_7012);
        }
        String suffix = fileName.substring(fileName.lastIndexOf("."));
        if(StrUtil.isEmpty(suffix)){
            throw new BusinessException(ErrorCode.FAILURE_CODE_7012);
        }

        File tempFile = File.createTempFile(UUID.randomUUID().toString(), suffix);
        cn.hutool.core.io.FileUtil.writeString(param.getContent(), tempFile, StandardCharsets.UTF_8);
        uploadToOssUtil.upload(tempFile.getPath(), param.getOssPath());
        tempFile.deleteOnExit();

        return this.ossUrlPrefix + param.getOssPath();
    }
}
