<?php

namespace App\Models\Service;

use Illuminate\Database\Eloquent\Model;
use Leenooks\Carbon as LeenooksCarbon;

use App\Interfaces\ServiceItem;
use App\Models\{Account,Service};
use App\Models\Supplier\Type as SupplierType;
use App\Traits\{ScopeServiceActive,ScopeServiceUserAuthorised};

abstract class Type extends Model implements ServiceItem
{
	use ScopeServiceActive,ScopeServiceUserAuthorised;

	protected $casts = [
		'connect_at' => 'datetime:Y-m-d',
		'expire_at' => 'datetime:Y-m-d',
	];

	public $timestamps = FALSE;

	/* RELATIONS */

	/**
	 * Account this service belongs to
	 * @return \Illuminate\Database\Eloquent\Relations\HasOneThrough
	 */
	public function account()
	{
		return $this->hasOneThrough(Account::class,Service::class);
	}

	/**
	 * @NOTE: The service_id column could be discarded, if the id column=service_id
	 * @return \Illuminate\Database\Eloquent\Relations\MorphOne
	 */
	public function service()
	{
		return $this->morphOne(Service::class,'type','model','id','service_id');
	}

	/* INTERFACE */

	public function getContractTermAttribute(): int
	{
		return $this->service->offering->contract_term;
	}

	public function getServiceExpireAttribute(): ?LeenooksCarbon
	{
		return $this->expire_at ?: $this->service->invoice_next_at;
	}

	public function hasExpired(): bool
	{
		return (! $this->inContract()) && ($this->service->invoice_next_at && $this->service->invoice_next_at->isPast());
	}

	public function inContract(): bool
	{
		return $this->expire_at && $this->expire_at->isFuture();
	}

	/* ATTRIBUTES */

	/**
	 * We need to cast some dates to LeenooksCarbon to get access to startOfHalf()/endOfHalf() methods
	 *
	 * @param $value
	 * @return LeenooksCarbon
	 */
	public function getExpireAtAttribute($value): ?LeenooksCarbon
	{
		return $value ? LeenooksCarbon::create($value) : NULL;
	}

	/* METHODS */

	/**
	 * Validation used to accept form input
	 *
	 * @return mixed
	 */
	public function validation(): array
	{
		return [];
	}

	/**
	 * The supplier's service that we provide
	 *
	 * @return SupplierType
	 */
	public function supplied(): SupplierType
	{
		return $this->service->offering->supplied ?: new \App\Models\Supplier\Generic();
	}
}