<?php

namespace App\Models;

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

use App\Interfaces\IDs;

/**
 * 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 HasFactory,ScopeActive;

	const CREATED_AT = 'date_orig';
	const UPDATED_AT = 'date_last';

	protected $appends = [
		'active_display',
		'name',
		'services_count_html',
		'switch_url',
	];

	public $dateFormat = 'U';

	protected $visible = [
		'id',
		'active_display',
		'name',
		'services_count_html',
		'switch_url',
	];

	/* 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 services($active=FALSE)
	{
		$query = $this->hasMany(Service::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 */

	public function getActiveDisplayAttribute($value)
	{
		return sprintf('<span class="btn-sm btn-block btn-%s text-center">%s</span>',$this->active ? 'success' : 'danger',$this->active ? 'Active' : 'Inactive');
	}

	/**
	 * @deprecated use getAIDAttribute()
	 */
	public function getAccountIdAttribute()
	{
		return $this->getAIDAttribute();
	}

	/**
	 * @deprecated use getUrlAdminAttribute()
	 */
	public function getAccountIdUrlAttribute()
	{
		return $this->getUrlAdminAttribute();
	}

	/**
	 * 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)
		];
	}

	/**
	 * Return the Account Unique Identifier
	 * @return string
	 * @deprecated use getSIDAttribute()
	 */
	public function getAIDAttribute()
	{
		return $this->getSIDAttribute();
	}

	/**
	 * Account Local ID
	 *
	 * @return string
	 */
	public function getLIDAttribute(): string
	{
		return sprintf('%04s',$this->id);
	}

	public function getNameAttribute()
	{
		return $this->company ?: ($this->user_id ? $this->user->SurFirstName : 'AID:'.$this->id);
	}

	public function getServicesCountHtmlAttribute()
	{
		return sprintf('%s <small>/%s</small>',$this->services()->noEagerLoads()->where('active',TRUE)->count(),$this->services()->noEagerLoads()->count());
	}

	/**
	 * Account System ID
	 *
	 * @return string
	 */
	public function getSIDAttribute(): string
	{
		return sprintf('%02s-%s',$this->site_id,$this->getLIDAttribute());
	}

	public function getSwitchUrlAttribute()
	{
		return sprintf('<a href="/r/switch/start/%s"><i class="fas fa-external-link-alt"></i></a>',$this->user_id);
	}

	public function getTypeAttribute()
	{
		return $this->company ? 'Business' : 'Private';
	}

	/**
	 * Return the Admin URL to manage the account
	 *
	 * @return string
	 */
	public function getUrlAdminAttribute(): string
	{
		return sprintf('<a href="/r/account/view/%s">%s</a>',$this->id,$this->account_id);
	}

	/**
	 * Return the User URL to manage the account
	 *
	 * @return string
	 */
	public function getUrlUserAttribute(): string
	{
		return sprintf('<a href="/u/account/view/%s">%s</a>',$this->id,$this->account_id);
	}

	/* GENERAL 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;
		});
	}

	/**
	 * Get the external account ID for a specific integration
	 *
	 * @param External\Integrations $o
	 * @return mixed
	 */
	public function ExternalAccounting(External\Integrations $o)
	{
		return $this
			->external()
			->where('id','=',$o->id)
			->where('site_id','=',$this->site_id)
			->first();
	}
}