<?php

namespace App\Models;

use App\Http\Controllers\Api\Platform\StorageFileController;
use App\Services\RealtimeMessageAttachmentService;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\File;

class RealtimeMessageAttachment extends Model
{
   use HasFactory;
   use SoftDeletes;
   use RealtimeMessageAttachmentService;

   /**
    * The database table used by the model.
    *
    * @var string
    */
   protected $table = 'realtime_message_attachments';

   /**
    * Attributes that should be mass-assignable.
    *
    * @var array
    */
   protected $fillable = [
      'uuid',
      'path',
      'attachment_type',
      'original_name',

      'realtime_message_id',
   ];

   /**
    * The attributes excluded from the model's JSON form.
    *
    * @var array
    */
   protected $hidden = [
      'realtime_message_id',
   ];

   /**
    * The attributes that should be casted to native types.
    *
    * @var array
    */
   protected $casts = [];

   /**
    * The attributes that should be mutated to dates.
    *
    * @var array
    */
   protected $dates = ['created_at', 'updated_at', 'deleted_at'];

   /**
    * The "booting" method of the model.
    *
    * @return void
    */
   public static function boot(): void
   {
      parent::boot();
   }

   /**
    * The accessors to append to the model's array form.
    *
    * @var array
    */
   protected $appends = ['attachment_url'];

   /** Attributes used outside the class to create modify the resource */

   /**
    * Compute attachment url
    *
    * @return string|null
    */
   public function getAttachmentUrlAttribute(): ?string
   {
      return $this->buildAttachmentUrl();
   }

   /**
    * Compute attachment url
    *
    * @return string|null
    */
   public function buildAttachmentUrl(): ?string
   {
      if (filled($this->{'path'})) {
         return route('serve.doc', [
            'resourceId' => $this->{'id'},
            'q' => StorageFileController::realtimeMessageAttachment,
            'file' => $this->{'path'}
         ]);
      }

      return null;
   }

   /**
    * Compute attachment thumbnail url
    *
    * @return string|null
    */
   public function buildAttachmentThumbnailUrl(): ?string
   {
      if (filled($this->buildAttachmentThumbnailPath())) {
         return route('serve.doc', [
            'resourceId' => $this->{'id'},
            'q' => StorageFileController::thumbnailFlag,
            'file' => replace_file_extension($this->{'path'}, config('torryme.constants.default_image_extension'))
         ]);
      }

      return null;
   }

   /**
    * Build attachment directory file path
    *
    * @param string|null $path
    * @return string
    */
   public function buildAttachmentFilePath(string $path = null): string
   {
      return sprintf(
         config('torryme.paths.docs'),
         sprintf(
            '%s%s/%s',
            Chat::$prefixDir,
            $this->{'realtimeMessage'}->{'chat_id'},
            $path ?? $this->{'path'}
         )
      );
   }

   /**
    * Build attachment directory for thumbnail path
    *
    * @return string|null
    */
   public function buildAttachmentThumbnailPath(): ?string
   {
      $path = sprintf(
         config('torryme.paths.thumbnails'),
         replace_file_extension($this->{'path'}, config('torryme.constants.default_image_extension'))
      );

      if(Storage::disk(config('torryme.storage_option'))->exists($path)) {
         return $path;
      }

      return null;
   }

   /**
    * Get media size
    *
    * @return int
    */
   public function mediaSize(): int
   {
      $storageOption = config('torryme.storage_option');
      $path = $this->buildAttachmentFilePath();

      if(filled($path)) {
         if(Storage::disk($storageOption)->exists($path)) {
            return File::size(storage_path('app/' . $path));
         }
      }

      return 0;
   }

   /** Relations */

   public function realtimeMessage(): \Illuminate\Database\Eloquent\Relations\BelongsTo
   {
      return $this->belongsTo(RealtimeMessage::class, 'realtime_message_id');
   }
}
