package com.gxwebsoft.common.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxwebsoft.common.core.utils.CommonUtil;
import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.system.entity.Company;
import com.gxwebsoft.common.system.entity.FileRecord;
import com.gxwebsoft.common.system.mapper.FileRecordMapper;
import com.gxwebsoft.common.system.param.FileRecordParam;
import com.gxwebsoft.common.system.service.CompanyService;
import com.gxwebsoft.common.system.service.FileRecordService;
import com.gxwebsoft.common.system.service.SettingService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.Arrays;
import java.util.List;

/**
 * 文件上传记录Service实现
 *
 * @author WebSoft
 * @since 2021-08-30 11:21:01
 */
@Service
public class FileRecordServiceImpl extends ServiceImpl<FileRecordMapper, FileRecord> implements FileRecordService {
  @Resource
  private CompanyService companyService;
  @Resource
  private SettingService settingService;

  @Override
  public PageResult<FileRecord> pageRel(FileRecordParam param) {
    PageParam<FileRecord, FileRecordParam> page = new PageParam<>(param);
    page.setDefaultOrder("create_time desc");
    return new PageResult<>(baseMapper.selectPageRel(page, param), page.getTotal());
  }

  @Override
  public List<FileRecord> listRel(FileRecordParam param) {
    PageParam<FileRecord, FileRecordParam> page = new PageParam<>(param);
    page.setDefaultOrder("create_time desc");
    return page.sortRecords(baseMapper.selectListRel(param));
  }

  @Override
  public FileRecord getByIdRel(Integer id) {
    FileRecordParam param = new FileRecordParam();
    param.setId(id);
    return param.getOne(baseMapper.selectListRel(param));
  }

  @Override
  public FileRecord getByIdPath(String path) {
    return CommonUtil.listGetOne(baseMapper.getByIdPath(path));
  }


  @Async
  @Override
  public void deleteFileAsync(List<File> files) {
    for (File file : files) {
      try {
        file.delete();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }

  }

  @Override
  public void deleteOssFileAsync(List<FileRecord> fileRecords) {
    // 读取云存储配置信息
    final FileRecord record = fileRecords.get(0);
    System.out.println("record = " + record);
    final JSONObject uploadConfig = settingService.getUploadConfig(record.getTenantId());
    String endpoint = uploadConfig.getString("bucketEndpoint");
    String bucketDomain = uploadConfig.getString("bucketDomain");
    String bucketName = uploadConfig.getString("bucketName");
    String accessKeyId = uploadConfig.getString("accessKeyId");
    String accessKeySecret = uploadConfig.getString("accessKeySecret");
    String uploadMethod = uploadConfig.getString("uploadMethod");
    CredentialsProvider credentialsProvider = new DefaultCredentialProvider(accessKeyId, accessKeySecret);
    // MinIO 兼容 S3 协议，需开启 PathStyle 访问 + V4 签名
    OSS ossClient;
    if ("minio".equals(uploadMethod)) {
      ClientBuilderConfiguration minioConfig = new ClientBuilderConfiguration();
      // 3.17 已移除 setPathStyleAccess；用 setExtractSettingFromEndpoint 让 SDK 对 MinIO 这类
      // 非阿里云 endpoint 自动按 path-style 访问，并从 endpoint 推导 region
      minioConfig.setSignatureVersion(SignVersion.V4);
      minioConfig.setExtractSettingFromEndpoint(true);
      ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider, minioConfig);
    } else {
      ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
    }
    for (FileRecord fileRecord : fileRecords) {
      fileRecord.setPath(StrUtil.replace(fileRecord.getPath(), bucketDomain.concat("/"), ""));
      try {
        // 删除远程文件
        ossClient.deleteObject(bucketName, fileRecord.getPath());
        // 释放空间大小
        if (fileRecord.getCompanyId() > 0) {
          Company company = companyService.getById(fileRecord.getCompanyId());
          company.setStorage(company.getStorage() - fileRecord.getLength());
          companyService.updateById(company);
        }
      }  catch (Exception e) {
        e.printStackTrace();
      }
    }
  }
}
