<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;

use App\Traits\NextKey;

class Product extends Model
{
	use NextKey;

	const RECORD_ID = 'product';

	protected $table = 'ab_product';
	protected $with = ['descriptions'];

	const CREATED_AT = 'date_orig';
	const UPDATED_AT = 'date_last';
	public $incrementing = FALSE;
	public $dateFormat = 'U';

	public function descriptions()
	{
		return $this->hasMany(ProductTranslate::class);
	}

	public function services()
	{
		return $this->hasMany(Service::class);
	}

	/**
	 * Return a child model with details of the service
	 *
	 * @return \Illuminate\Database\Eloquent\Relations\MorphTo
	 */
	public function type()
	{
		return $this->morphTo(null,'model','prod_plugin_data');
	}

	/**
	 * Get the service category (from the product)
	 *
	 * @return string
	 */
	public function getCategoryAttribute()
	{
		return $this->prod_plugin_file ?: 'Other';
	}

	public function getContractTermAttribute()
	{
		switch ($this->prod_plugin_file) {
			case 'ADSL': return $this->plugin()->contract_term;
			// @todo Incorporate into DB
			case 'VOIP': return 12;

			// @todo Change this after contracts implemented.
			default:
				return 'TBA';
		}
	}

	public function getDefaultBillingAttribute()
	{
		return array_get($this->PricePeriods(),$this->price_recurr_default);
	}

	public function getDefaultCostAttribute()
	{
		// @todo Integrate this into a Tax::class
		return array_get($this->price_array,sprintf('%s.1.price_base',$this->price_recurr_default))*1.1;
	}

	private function getDefaultLanguage()
	{
		return config('SITE_SETUP')->language;
	}

	public function getDescriptionAttribute()
	{
		// @todo If the user has selected a specific language.
		return $this->description($this->getDefaultLanguage());
	}

	public function getMinimumCostAttribute()
	{
		$table = [
			0=>4,
			1=>1,
			2=>1/3,
			3=>1/6,
			4=>1/12,
			5=>1/24,
			6=>1/36,
			7=>1/48,
			8=>1/60,
		];

		return $this->setup_cost + ( $this->default_cost * array_get($table,$this->price_recurr_default) * $this->contract_term);
	}

	public function getNameAttribute(Language $lo=NULL)
	{
		if (is_null($lo))
			$lo = $this->getDefaultLanguage();

		return $this->descriptions->where('language_id',$lo->id)->first()->description_short;
	}

	public function getNameShortAttribute(Language $lo=NULL)
	{
		if (is_null($lo))
			$lo = $this->getDefaultLanguage();

		return $this->descriptions->where('language_id',$lo->id)->first()->name;
	}

	public function getProductTypeAttribute()
	{
		return $this->plugin()->product->name;
	}

	public function getPriceArrayAttribute()
	{
		return unserialize($this->price_group);
	}

	public function getPriceTypeAttribute()
	{
		$table = [
			0=>_('One-time Charge'),
			1=>_('Recurring Membership/Subscription'),
			2=>_('Trial for Membership/Subscription'),
		];
	}

	public function getProductIdAttribute()
	{
		return sprintf('#%04s',$this->id);
	}

	public function getSetupCostAttribute()
	{
		// @todo Integrate this into a Tax::class
		return array_get($this->price_array,sprintf('%s.1.price_setup',$this->price_recurr_default))*1.1;
	}

	public function scopeActive()
	{
		return $this->where('active',TRUE);
	}

	public function description(Language $lo=NULL)
	{
		if (is_null($lo))
			$lo = $this->getDefaultLanguage();

		return $this->descriptions->where('language_id',$lo->id)->first()->description_full;
	}

	public function orderValidation(Request $request)
	{
		return $this->plugin()->orderValidation($request);
	}

	private function plugin()
	{
		switch ($this->prod_plugin_file) {
			case 'ADSL':
				return AdslPlan::findOrFail($this->prod_plugin_data);
			case 'VOIP':
				return new PlanVoip;
		}
	}

	/**
	 * Get the price for this product based on the period being requested.
	 *
	 * If the price period doesnt exist, we'll take the default period (0) which should.
	 *
	 * @param int $period
	 * @return mixed
	 */
	public function price(int $period)
	{
		return Arr::get(
			$this->price_array,
			sprintf('%s.1.price_base',$period),
			Arr::get($this->price_array,sprintf('%s.0.price_base',$period))
		);
	}

	public function PricePeriods()
	{
		return [
			0=>_('Weekly'),
			1=>_('Monthly'),
			2=>_('Quarterly'),
			3=>_('Semi-Annually'),
			4=>_('Annually'),
			5=>_('Two years'),
			6=>_('Three Years'),
			7=>_('Four Years'),
			8=>_('Five Years'),
		];
	}

	/**
	 * Get the product name
	 *
	 * @param Language $lo
	 * @return string Product Name
	 */
	public function name(Language $lo=NULL)
	{
		if (is_null($lo))
			$lo = $this->getDefaultLanguage();

		return $this->descriptions->where('language_id',$lo->id)->first()->name;
	}
}