<?php

namespace App\Http\Controllers;

use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;

use App\Http\Requests\{SupplierAddEdit,SupplierProductAddEdit};
use App\Jobs\ImportCosts;
use App\Models\{Supplier,SupplierDetail};

class SupplierController extends Controller
{
	/**
	 * Update a suppliers details
	 *
	 * @param SupplierAddEdit $request
	 * @param Supplier $o
	 * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
	 */
	public function addedit(SupplierAddEdit $request,Supplier $o)
	{
		foreach (Arr::except($request->validated(),['supplier_details','api_key','api_secret','submit']) as $key => $item)
			$o->{$key} = $item;

		$o->active = (bool)$request->validated('active');

		try {
			$o->save();

		} catch (\Exception $e) {
			return redirect()
				->back()
				->withErrors($e->getMessage())->withInput();
		}

		$o->load(['detail']);
		$oo = $o->detail ?: new SupplierDetail;

		foreach ($request->get('supplier_details',[]) as $key => $item)
			$oo->{$key} = $item;

		$oo->connections = $oo->connections->merge([
			'api_key'=>$request->get('api_key'),
			'api_secret'=>$request->get('api_secret'),
		])->filter();
		$o->detail()->save($oo);

		return redirect()
			->back()
			->with('success','Supplier Saved');
	}

	public function cost_submit(Request $request,Supplier $o)
	{
		$request->validate([
			'file' => 'required|filled',
			'billed_at' => 'required|date',
		]);

		$filename = $request->file('file')->store('cost_import');

		ImportCosts::dispatch(
			config('site'),
			$o,
			Carbon::create($request->billed_at),
			$filename,
		)->onQueue('low');

		return redirect()
			->back()
			->with('success','File uploaded');
	}

	public function product_new(SupplierProductAddEdit $request)
	{
		$o = Supplier::offeringTypeClass($request->validated('offering_type'));

		foreach (Arr::except($request->validated(),['id','offering_type']) as $key => $value)
			$o->{$key} = $value;

		$o->save();

		return redirect()
			->back()
			->with('success','Saved');
	}

	public function product_addedit(SupplierProductAddEdit $request,Supplier $o,int $id,string $type)
	{
		// Quick validation
		if ($type !== $request->offering_type)
			abort(500,'Type and offering type do not match');
		if ($o->exists && ($o->detail->id !== (int)$request->supplier_detail_id))
			abort(500,sprintf('Supplier [%d] and supplier_detail_id [%d] do not match',$o->detail->id,$request->supplier_detail_id));

		switch ($request->offering_type) {
			case 'broadband':
				$oo = Supplier\Broadband::findOrNew($id);

				// @todo these are broadband requirements - get them from the broadband class.
				foreach (Arr::only($request->validated(),[
					'supplier_detail_id',
					'product_id',
					'product_desc',
					'base_cost',
					'setup_cost',
					'contract_term',
					'metric',
					'speed',
					'technology',
					'offpeak_start',
					'offpeak_end',
					'base_down_peak',
					'base_up_peak',
					'base_down_offpeak',
					'base_up_offpeak',
					'extra_down_peak',
					'extra_up_peak',
					'extra_down_offpeak',
					'extra_up_offpeak',
				]) as $key => $value)
					$oo->{$key} = $value;

				// Our boolean values
				foreach (Arr::only($request->validated(),['active','extra_shaped','extra_charged']) as $key => $value)
					$oo->{$key} = ($value == 'on' ? 1 : 0);

				break;

			case 'phone':
				$oo = Supplier\Phone::findOrNew($id);

				foreach (Arr::except($oo->validation(),[
					'id',
					'offering_type',
				]) as $key => $value)
					$oo->{$key} = $request->validated($key);

				break;

			default:
				throw new \Exception('Unknown offering type:'.$request->offering_type);
		}

		$oo->save();

		return redirect()
			->back()
			->with('success','Saved');
	}

	/**
	 * Return the form for a specific product type
	 *
	 * @param Request $request
	 * @param string $type
	 * @param int|null $id
	 * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
	 */
	public function product_view_type(Request $request,string $type,?int $id=NULL)
	{
		$o = $id ? Supplier::offeringTypeClass($type)->findOrFail($id) : NULL;

		if ($request->old)
			$request->session()->flashInput($request->old);

		if ($o)
			$o->load(['products.products.services']);

		return view('theme.backend.adminlte.supplier.product.widget.'.$type)
			->with('o',$id ? $o : NULL)
			->withErrors($request->errors);
	}
}