<?php

namespace app\modules\operational\models;

use app\components\Utils;
use Yii;
use yii\db\Expression;
use yii\web\UploadedFile;
use yii\behaviors\BlameableBehavior;
use yii\behaviors\TimestampBehavior;
use app\modules\operational\base\Model;
use app\modules\operational\models\Status;

/**
 * This is the model class for table "co_ocorrencia_anexo".
 *
 * @property int $id
 * @property int $co_ocorrencia_id
 * @property string $descricao
 * @property string $arquivo
 * @property string $extensao
 * @property int $created_by
 * @property int $updated_by
 * @property string $created_at
 * @property string $updated_at
 * @property int $isDeleted
 *
 * @property CoOcorrencia $coOcorrencia
 */
class OcorrenciaAnexo extends Model
{

    const FILES_MAX_SIZE = 1024 * 1024 * 150; //O tamanho do upload precisa ser configurado no servidor
    const FILES_REPOSITORY = "@app/modules/operational/uploads/ocorrencias";
    const FILES_MIME_TYPES_ACCEPT = 'image/*,text/*,application/*,audio/*,video/*';

    public $files;

    public function behaviors()
    {
        return [
            BlameableBehavior::className(),
            [
                'class' => TimestampBehavior::className(),
                'value' => new Expression('NOW()'),
            ]
        ];
    }

    /**
     * {@inheritdoc}
     */
    public static function tableName()
    {
        return 'co_ocorrencia_anexo';
    }

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            [['co_ocorrencia_id', 'created_by', 'updated_by', 'isDeleted', 'status'], 'integer'],
            [['created_at', 'updated_at', 'files'], 'safe'],
            [['descricao', 'arquivo', 'extensao'], 'string', 'max' => 255],
            [['co_ocorrencia_id'], 'exist', 'skipOnError' => true, 'targetClass' => Ocorrencia::className(), 'targetAttribute' => ['co_ocorrencia_id' => 'id']],
            [
                ['files'], 'file', 'skipOnEmpty' => true,
                'mimeTypes' => self::FILES_MIME_TYPES_ACCEPT,
                'maxFiles' => 5,
                'tooMany' => 'Você pode anexar até 5 arquivos por vez!',
                'maxSize' => self::FILES_MAX_SIZE,
                'tooBig' => "O tamanho máximo de anexos é de " . self::FILES_MAX_SIZE . 'mb',
                'wrongMimeType' => 'Você está tentando anexar um arquivo não permitido!'
            ]
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'co_ocorrencia_id' => 'Co Ocorrencia ID',
            'descricao' => 'Descricao',
            'arquivo' => 'Arquivo',
            'extensao' => 'Extensao',
            'created_by' => 'Created By',
            'updated_by' => 'Updated By',
            'created_at' => 'Created At',
            'updated_at' => 'Updated At',
            'isDeleted' => 'Is Deleted',
        ];
    }

    /**
     * Gets query for [[CoOcorrencia]].
     *
     * @return \yii\db\ActiveQuery
     */
    public function getOcorrencia()
    {
        return $this->hasOne(Ocorrencia::className(), ['id' => 'co_ocorrencia_id']);
    }

    /**
     * Checa se o repositorio para receber os uploads das ocorrencias existe
     * @return string | Exception
     * @throws Exception
     * @author Rafael Fernando Fiedler <rafaelfernandofiedler@hotmail.com> <48 988313637>
     */
    private function checkFileRepository()
    {
        $path = Yii::getAlias(self::FILES_REPOSITORY);
        if (!file_exists($path)) {
            if (!mkdir($path, 0777, true)) {
                return false;
            }
        }

        return $path;
    }

    /**
     * Retorna a pasta absoluta do repositorio de uploads
     * @return string | boolean
     * @author Rafael Fernando Fiedler <rafaelfernandofiedler@hotmail.com> <48 988313637>
     */
    private function getAbsoluteFilePathRepository()
    {
        return $this->checkFileRepository();
    }

    /**
     * Gera o nome do arquivo que será salvo fisicamente
     * Lembre que o upload de arquivos deve ser feito após o salvamento do model
     * @author Rafael Fernando Fiedler <rafaelfernandofiedler@hotmail.com> <48 988313637>
     * @return String 
     */
    private function generateFilename(UploadedFile $file, Ocorrencia $model)
    {
        return implode("", ['ocorrencia', '-', $model->id, '-', uniqid(), '-', date('Ymd')]) . '.' . $file->extension;
    }

    /**
     * Retorna o path do arquivo físico que será salvo no disco
     * @param UploadedFile $file
     * @author Rafael Fernando Fiedler <rafaelfernandofiedler@hotmail.com> <48 988313637>
     */
    private function generateFullPath($filename)
    {
        return implode(DIRECTORY_SEPARATOR, [$this->getAbsoluteFilePathRepository(), $filename]);
    }

    /**
     * Retorna o path absoluto do arquivo para fazer download
     * @return boolean
     * @author Rafael Fernando Fiedler <rafaelfernandofiedler@hotmail.com> <48 988313637>
     */
    public function getDownloadPath()
    {
        $file = implode(DIRECTORY_SEPARATOR, [$this->getAbsoluteFilePathRepository(), $this->arquivo]);
        if (file_exists($file)) {
            return $file;
        }
        return false;
    }

    /**
     * Faz o upload de todos os arquivos enviados
     * @return void 
     * @author Rafael Fernando Fiedler <rafaelfernandofiedler@hotmail.com> <48 988313637>
     */
    public function upload(Ocorrencia $model)
    {
        $this->files = UploadedFile::getInstances($this, 'files');

        if (
            isset($_FILES) &&
            is_array($_FILES) &&
            empty($this->files)
        ) {
            foreach ($_FILES as $k => $_FILE) {
                if ($k != 'OcorrenciaAnexo') {
                    $this->files[] = new UploadedFile([
                        'tempName' => $_FILES[$k]['tmp_name'],
                        'name' => $_FILES[$k]['name'],
                        'type' => $_FILES[$k]['type'],
                        'size' => $_FILES[$k]['size'],
                    ]);
                }
            }
        }

        $files = [];
        if ($this->checkFileRepository()) {
            foreach ($this->files as $file) {
                $filename = $this->generateFilename($file, $model);
                $inThispath = $this->generateFullPath($filename);

                if ($file->saveAs($inThispath)) {
                    $files[] = ['file' => $file, 'arquivo' => $filename];
                }

                self::geraThumbnail($inThispath);
            }
        }


        foreach ($files as $file) {
            $anexo = new OcorrenciaAnexo();
            $anexo->co_ocorrencia_id = $model->id;
            $anexo->descricao = $file['file']->name;
            $anexo->arquivo = $file['arquivo'];
            $anexo->extensao = $file['file']->extension;
            $anexo->isDeleted = Status::IS_NOT_DELETED;
            $anexo->status = 1;
            $anexo->save();
        }
    }

    public static function geraThumbnail($pathFile)
    {

        $info = getimagesize($pathFile);

        if (!$info) {
            return true;
        }

        $largura = $info[0];
        $altura = $info[1];


        $imagick = new \Imagick(realpath($pathFile));
        $imagick->scaleImage(800, 0);

        /*
        $fator = $largura / 175;

        $alturaCorrigida = round($altura / $fator);

        $exp = explode(".", $pathFile);        

        $imagick = new \Imagick(realpath($pathFile));
        $imagick->setImageFormat(end($exp));
        $imagick->setImageCompression(\Imagick::COMPRESSION_JPEG);
        $imagick->setImageCompressionQuality(85);
        $imagick->thumbnailImage(175, $alturaCorrigida, false, false); */

        if (file_put_contents($pathFile, $imagick) === false) {
            throw new Exception("Could not put contents.");
        }

        return true;
    }
}
