<?php

namespace App\Models;

use Illuminate\Support\Facades\Log;

use App\Jobs\CatalogMove;
use App\Media\{Base,Factory};

class Video extends Abstracted\Catalog
{
	public const config = 'video';

	protected $casts = [
		'created'=>'datetime:Y-m-d H:i:s',
	];

	// Media Object
	private ?Base $_o;
	protected array $init = [
		'creation_date',
		'gps',
		'heightwidth',
		'signature',
		'software',
	];

	public static function boot()
	{
		parent::boot();

		// Any video saved, queue it to be moved.
		self::saved(function($item) {
			if ($item->scanned && (! $item->duplicate) && (! $item->remove) && ($x=$item->shouldMove()) === TRUE) {
				Log::info(sprintf('%s: Need to Move [%s]',__METHOD__,$item->id.'|'.serialize($x)));

				CatalogMove::dispatch($item)
					->onQueue('move');
			}
		});
	}

	public function __get($key): mixed
	{
		if ($key === 'o') {
			if (isset($this->_o))
				return $this->_o;

			if ((! file_exists($this->file_name(FALSE))) || (! is_readable($this->file_name(FALSE))))
				return $this->_o = NULL;

			if (! isset($this->_o)) {
				$this->_o = Factory::create($this->file_name(FALSE));

				return $this->_o;
			}
		}

		return parent::__get($key);
	}

	/* METHODS */

	public function custom_init()
	{
		$this->audio_channels = $this->getObjectOriginal('audio_channels');
		$this->audio_codec = $this->getObjectOriginal('audio_codec');
		$this->audio_samplerate = $this->getObjectOriginal('audio_samplerate');
		$this->gps_altitude = $this->getObjectOriginal('gps_altitude');
		$this->length = round($this->getObjectOriginal('length'),2);
		$this->type = $this->getObjectOriginal('type');
		$this->video_codec = $this->getObjectOriginal('video_codec');
		$this->video_framerate = $this->getObjectOriginal('video_framerate');

		/*
		$x = new \getID3;
		$x->analyze($this->file_name(FALSE));
		dump(['id3'=>$x]);
		*/
	}

	public function getObjectOriginal(string $property): mixed
	{
		switch ($property) {
			case 'file_signature':
				return md5_file($this->file_name(FALSE));

			case 'length':
				return $this->o?->duration;

			case 'audio_channels':
			case 'audio_codec':
			case 'audio_samplerate':
			case 'creation_date':
			case 'gps_altitude':
			case 'gps_lat':
			case 'gps_lon':
			case 'height':
			case 'make':
			case 'model':
			case 'signature':
			case 'software':
			case 'type':
			case 'width':
			case 'video_codec':
			case 'video_framerate':
				return $this->o?->{$property};

			default:
				throw new \Exception('To implement: '.$property);
		}
	}

	/**
	 * Return the extension of the video
	 */
	public function type($mime=FALSE): string
	{
		return strtolower($mime ? File::mime_by_ext(pathinfo($this->filename,PATHINFO_EXTENSION)) : pathinfo($this->filename,PATHINFO_EXTENSION));
	}
}