<?php
// Última atualização: 23/05/2024 / Juliano santana
// atualizado a função copyFile (copiar arquivo de um bucket para outro bucket)

require_once(__DIR__.'/../../../_vendors/aws/aws-autoloader.php');
use Aws\S3\S3Client;

class S3 {

  // Geral
  private $Client;

  // Arquivo para envio
  private $file;
  public $file_name;

  // Tipo de Arquivo
  private $file_type = null;

  // Imagem
  private $image;
  private $width;
  private $height;

  public $result;

  public function __construct(){
    $this->Client  = new S3Client([
      'credentials' => [
        'key' => GLOBAL_AWS_S3_ACCESS_KEY,
        'secret' => GLOBAL_AWS_S3_SECRET_KEY,
      ],
      'region' => 'us-east-1',
      'version' => 'latest'
    ]);
  }

  // Configurações Iniciais
  public function config($dds){
    $this->file = $dds['file'];
    $this->file_name = $dds['file_name'];

    return $this;
  }

  // Cria imagem
  public function setImage($dds=array()){

    // IMAGEM ATRAVÉS DO CÓDIGO BASE64
    if(isset($dds['decode']) && $dds['decode']=="img_base64"){
      $this->file = $this->file_body = base64_decode($this->file);
      $size = getImageSizeFromString($this->file);
      $ext = substr($size['mime'], 6);
      $this->file_name .= '.'.$ext;
    }

    // IMAGEM ATRAVÉS DO INPUT FILE
    else{

      $this->png = ((isset($dds['ext']) && $dds['ext']=="png") || !isset($dds['ext']) && $this->file['type']=='image/png');
      $this->file_name .= $this->png ? '.png' : (isset($dds['ext']) ? '.'.$dds['ext'] : '.jpeg');

      // Cria a imagem
      $img = imagecreatefromstring(file_get_contents($this->file['tmp_name']));

      // Proporcionar as medidas da imagem
      $x_img = imagesx($img);
      $y_img = imagesy($img);
      $prop = isset($dds['max_px']) ? $dds['max_px'] : 320; // Medida máxima
      // Redimensionar somente se alguma das medidas, for maior do que a max definida
      if($y_img>$prop or $x_img>$prop){
        $y_prop = ($y_img>$x_img) ? $prop : $prop * $y_img / $x_img;
        $x_prop = ($x_img>$y_img) ? $prop : $prop * $x_img / $y_img;
      }else{
        $y_prop = $y_img;
        $x_prop = $x_img;
      }
      $x = isset($dds['width']) ? $dds['width'] : $x_prop;
      $y = isset($dds['height']) ? $dds['height'] : $y_prop;

      $file_new = imagecreatetruecolor($x, $y);
      imagecopyresampled($file_new, $img, 0, 0, 0, 0, $x, $y, $x_img, $y_img);

      // Salva a imagem redimensionada em um arquivo temporário
      $tmp_name = tempnam(sys_get_temp_dir(), 'img');
      if($this->png){
        imagepng($file_new, $tmp_name);
      }else{
        imagejpeg($file_new, $tmp_name);
      }
      $this->file_body = file_get_contents($tmp_name);

      // Limpa a memória
      imagedestroy($img);
      imagedestroy($file_new);
      unlink($tmp_name);
    }

    return $this;
  }

  // Prepara arquivo
  public function setFile(){
    $this->file_body = fopen($this->file['tmp_name'], 'r');
  }

  // Envia arquivo para a pasta no S3
  public function sendFile($bucket, $folder_destiny){
    if(!isset($this->file_body) || !$this->file_body){$this->setFile();}
    if($this->file_body) {
      $this->result = $this->Client->putObject([
        'Bucket' => $bucket,
        'Key'    => $folder_destiny.'/'.$this->file_name,
        'Body'   => $this->file_body,
        'ACL'    => 'private',
      ]);
    }
    $this->reset();
  }

  // Copiar arquivo de um bucket para outro bucket
  public function copyFile($bucket_destino, $folder_destino, $file, $file_origem){
    if($file){$this->file_name = $file;}
    try{
      $this->Client->copyObject([
        'Bucket'     => $bucket_destino,                          // Nome do bucket de destino
        'Key'        => "{$folder_destino}/{$this->file_name}",   // Nome do arquivo de destino
        'CopySource' => $file_origem                              // Nome do bucket de origem e nome do arquivo de origem
      ]);
    }catch (S3Exception $e) {}
  }

  // Pega o arquivo
  public function getFile($bucket, $folder_file){
    try{
      $tmpPath = '/tmp/'.uuid();
      $this->result = $this->Client->getObject([
        'Bucket' => $bucket,
        'Key'    => $folder_file,
        'SaveAs' => $tmpPath
      ]);
      return $tmpPath;
    }catch(\Exception $e){
      return false;
    }
  }
  // Deleta arquivo
  public function deleteFile($bucket, $folder, $file=null){
    if($file){$this->file_name = $file;}
    try{
      $result = $this->Client->deleteObject([
        'Bucket' => $bucket,
        'Key'    => $folder."/{$this->file_name}",
      ]);
    }catch (S3Exception $e) {}
  }

  public function reset(){
    $this->file_body = null;
  }
}