<?php

namespace App\Models\Product;

use Illuminate\Support\Collection;
use Leenooks\Traits\ScopeActive;

use App\Interfaces\ProductItem;
use App\Models\Invoice;
use App\Models\Service\Broadband as ServiceBroadband;
use App\Models\Supplier\Broadband as SupplierBroadband;

final class Broadband extends Type implements ProductItem
{
	use ScopeActive;

	protected $table = 'product_broadband';

	// Information required during the order process
	protected array $order_attributes = [
		'options.address'=>[
			'request'=>'options.address',
			'key'=>'service_address',
			'validation'=>'required|string:10|unique:service_broadband,service_address',
			'validation_message'=>'Address is a required field.',
		],
		'options.notes'=>[
			'request'=>'options.notes',
			'key'=>'order_info.notes',
			'validation'=>'present',
			'validation_message'=>'Special Instructions here.',
		],
	];

	// The model that is referenced when this product is ordered
	protected string $order_model = ServiceBroadband::class;

	// When comparing billing/pricing/charging, what metric to normalise to
	const DefaultBill = Invoice::BILL_MONTHLY;
	// The model that the supplier supplies
	const SupplierModel = SupplierBroadband::class;

	/* INTERFACES */

	/**
	 * Calculate the allowance array or traffic used array
	 *
	 * @param array Traffic Used in each metric.
	 * @param bool $ceil Round the numbers to integers
	 * @return array|string
	 */
	public function allowance(array $data=[],bool $ceil=TRUE): Collection
	{
		$config = collect();

		foreach (array_keys(SupplierBroadband::traffic_map) as $k => $v) {
			// Base Config
			$config->put($k,$this->{$k});
			// Excess Config
			$config->put($v,$this->{$v});
		}

		// Shaped or Charge
		$config->put('shaped',$this->extra_shaped);
		$config->put('charged',$this->extra_charged);

		// Metric - used to round down data in $data.
		$config->put('metric',$this->metric);

		return $this->supplied->allowance($config,$data,$ceil);
	}

	/* ATTRIBUTES */

	/**
	 * Return the suppliers cost for this service
	 *
	 * @return float
	 */
	// @todo To check
	public function allowance_cost(): float
	{
		$result = 0;
		foreach ($this->supplied->allowance(NULL,$this->allowance([])->toArray()) as $k=>$v) {
			$result += -$v*$this->supplied->{SupplierBroadband::traffic_map[$k]};
		}

		return $result;
	}

	/**
	 * Render the allowance as a string
	 * eg: 50/100
	 *
	 * @return string
	 */
	// @todo To check
	public function allowance_string(): string
	{
		$result = '';
		$data = $this->allowance();

		foreach ([
			'base_down_peak',
			'base_up_peak',
			'base_down_offpeak',
			'base_up_offpeak',
	         ] as $k)
		{
			if ($data->has($k)) {
				if ($result)
					$result .= '/';

				$result .= $data->get($k);
			}
		}

		return $result;
	}

	public function hasUsage(): bool
	{
		return TRUE;
	}
}