<?php

namespace App\Models;

use Awobaz\Compoships\Compoships;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Leenooks\Traits\ScopeActive;

use App\Models\Scopes\SiteScope;
use App\Interfaces\IDs;
use App\Traits\SiteID;

/**
 * Class Account
 * Service Accounts
 *
 * Attributes for accounts:
 * + lid				: Local ID for account
 * + sid				: System ID for account
 * + name				: Account Name
 * + taxes				: Taxes Applicable to this account
 *
 * @package App\Models
 */
class Account extends Model implements IDs
{
	use Compoships,HasFactory,ScopeActive,SiteID;

	/* INTERFACES */

	public function getLIDAttribute(): string
	{
		return sprintf('%04s',$this->id);
	}

	public function getSIDAttribute(): string
	{
		return sprintf('%02s-%s',$this->site_id,$this->getLIDAttribute());
	}

	/* RELATIONS */

	public function charges()
	{
		return $this->hasMany(Charge::class);
	}

	/**
	 * Return the country the user belongs to
	 */
	public function country()
	{
		return $this->belongsTo(Country::class);
	}

	public function external()
	{
		return $this->belongsToMany(External\Integrations::class,'external_account',NULL,'external_integration_id');
	}

	public function group()
	{
		return $this->hasOneThrough(Group::class,AccountGroup::class,'account_id','id','id','group_id');
	}

	public function invoices()
	{
		return $this->hasMany(Invoice::class);
	}

	public function language()
	{
		return $this->belongsTo(Language::class);
	}

	public function payments()
	{
		return $this->hasMany(Payment::class);
	}

	public function providers()
	{
		return $this->belongsToMany(ProviderOauth::class,'account_provider')
			->where('account_provider.site_id',$this->site_id)
			->withPivot('ref','synctoken','created_at','updated_at');
	}

	public function services($active=FALSE)
	{
		$query = $this->hasMany(Service::class,['account_id','site_id'],['id','site_id'])
			->withoutGlobalScope(SiteScope::class);

		return $active ? $query->active() : $query;
	}

	public function site()
	{
		return $this->belongsTo(Site::class);
	}

	public function taxes()
	{
		return $this->hasMany(Tax::class,'country_id','country_id');
	}

	public function user()
	{
		return $this->belongsTo(User::class);
	}

	/* SCOPES */

	/**
	 * Search for a record
	 *
	 * @param        $query
	 * @param string $term
	 * @return mixed
	 */
	public function scopeSearch($query,string $term)
	{
		// Build our where clause
		if (is_numeric($term)) {
			$query->where('id','like','%'.$term.'%');

		} else {
			$query->where('company','like','%'.$term.'%')
				->orWhere('address1','like','%'.$term.'%')
				->orWhere('address2','like','%'.$term.'%')
				->orWhere('city','like','%'.$term.'%');
		}

		return $query;
	}

	/* ATTRIBUTES */

	/**
	 * Get the address for the account
	 *
	 * @return array
	 */
	public function getAddressAttribute(): array
	{
		return [
			$this->address1,
			$this->address2,
			sprintf('%s %s  %s',$this->city.(($this->state OR $this->zip) ? ',' : ''),$this->state,$this->zip)
		];
	}

	/**
	 * Account breadcrumb to render on pages
	 *
	 * @return array
	 */
	public function getBreadcrumbAttribute(): array
	{
		return [$this->name => url('u/home',$this->user_id)];
	}

	/**
	 * Return the account name
	 *
	 * @return mixed|string
	 */
	public function getNameAttribute(): string
	{
		return $this->company ?: ($this->user_id ? $this->user->getSurFirstNameAttribute() : 'LID:'.$this->id);
	}

	/**
	 * Return the type of account this is - if it has a company name, then its a business account.
	 *
	 * @return string
	 */
	public function getTypeAttribute()
	{
		return $this->company ? 'Business' : 'Private';
	}

	/* METHODS */

	/**
	 * Get the due invoices on an account
	 *
	 * @return mixed
	 */
	public function dueInvoices()
	{
		return $this->invoices->filter(function($item) {
			return $item->active AND $item->due > 0;
		});
	}

	/**
	 * Return the taxed value of a value
	 *
	 * @param float $value
	 * @return float
	 */
	public function taxed(float $value): float
	{
		return Tax::calc($value,$this->taxes);
	}
}