<?php

namespace App\Models;

use App\User;
use Illuminate\Database\Eloquent\Model;

use App\Traits\NextKey;

class Account extends Model
{
	use NextKey;

	const RECORD_ID = 'account';

	public $incrementing = FALSE;

	protected $table = 'ab_account';
	public $timestamps = FALSE;

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

	/**
	 * 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 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->where('active','=',TRUE) : $query;
	}

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

	/** SCOPES */

	/**
	 * Search for a record
	 *
	 * @param        $query
	 * @param string $term
	 * @return
	 */
	public function scopeSearch($query,string $term)
	{
		// Build our where clause
		// First Name, Last name
		if (preg_match('/\ /',$term)) {
			list($fn,$ln) = explode(' ',$term,2);

			$query->where(function($query1) use ($fn,$ln,$term) {
				$query1->where(function($query2) use ($fn,$ln) {
					return $query2
						->where('first_name','like','%'.$fn.'%')
						->where('last_name','like','%'.$ln.'%');
				})
				->orWhere('company','like','%'.$term.'%');
			});

		} elseif (is_numeric($term)) {
			$query->where('id','like','%'.$term.'%');

		} elseif (preg_match('/\@/',$term)) {
			$query->where('email','like','%'.$term.'%');

		} else {
			$query
				->where('company','like','%'.$term.'%')
				->orWhere('first_name','like','%'.$term.'%')
				->orWhere('last_name','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();
	}

	/**
	 * Return the Account Unique Identifier
	 * @return string
	 */
	public function getAIDAttribute()
	{
		return sprintf('%02s-%04s',$this->site_id,$this->id);
	}

	public function getNameAttribute()
	{
		return $this->company ?: $this->user->SurFirstName;
	}

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

	public function getSwitchUrlAttribute()
	{
		return sprintf('<a href="/r/switch/start/%s"><i class="fa fa-external-link"></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);
	}

	/** FUNCTIONS **/

	private function _address()
	{
		$return = [];

		if ($this->address1)
			array_push($return,$this->address1);
		if ($this->address2)
			array_push($return,$this->address2);
		if ($this->city)
			array_push($return,sprintf('%s %s  %s',$this->city.(($this->state OR $this->zip) ? ',' : ''),$this->state,$this->zip));

		if (! $return)
			$return = ['No Address'];

		return $return;
	}

	public function address($type='plain')
	{
		switch ($type)
		{
			case 'html' : return join('<br>',$this->_address());
			case 'newline': return join("\m",$this->_address());

			default:
				return join("\n",$this->_address());
		}
	}

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