<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Collection;

use App\Http\Requests\ProductAddEdit;
use App\Models\{Product,ProductTranslate};

class ProductController extends Controller
{
	/**
	 * Get a list of products that meet a type
	 *
	 * @param Request $request
	 * @return Collection
	 * @throws \Exception
	 */
	public function api_supplier_products(Request $request): Collection
	{
		switch ($request->type) {
			case Product\Broadband::class:
				return Product\Broadband::select(['id','supplier_item_id'])
					->with(['supplied.supplier_detail.supplier'])
					->get()
					->map(function($item) { return ['id'=>$item->id,'name'=>sprintf('%s: %s',$item->supplied->supplier->name,$item->supplied->name)]; })
					->sortBy('name')
					->values();

			case Product\Domain::class:
				return Product\Domain::select(['id','supplier_item_id'])
					->with(['supplied.supplier_detail.supplier'])
					->get()
					->map(function($item) { return ['id'=>$item->id,'name'=>sprintf('%s: %s',$item->supplied->supplier->name,$item->supplied->name)]; })
					->sortBy('name')
					->values();

			case Product\Email::class:
				return Product\Email::select(['id','supplier_item_id'])
					->with(['supplied.supplier_detail.supplier'])
					->get()
					->map(function($item) { return ['id'=>$item->id,'name'=>sprintf('%s: %s',$item->supplied->supplier->name,$item->supplied->name)]; })
					->sortBy('name')
					->values();

			case Product\Generic::class:
				return Product\Generic::select(['id','supplier_item_id'])
					->with(['supplied.supplier_detail.supplier'])
					->get()
					->map(function($item) { return ['id'=>$item->id,'name'=>sprintf('%s: %s',$item->supplied->supplier->name,$item->supplied->name)]; })
					->sortBy('name')
					->values();

			case Product\Host::class:
				return Product\Host::select(['id','supplier_item_id'])
					->with(['supplied.supplier_detail.supplier'])
					->get()
					->map(function($item) { return ['id'=>$item->id,'name'=>sprintf('%s: %s',$item->supplied->supplier->name,$item->supplied->name)]; })
					->sortBy('name')
					->values();

			case Product\Phone::class:
				return Product\Phone::select(['id','supplier_item_id'])
					->with(['supplied.supplier_detail.supplier'])
					->get()
					->map(function($item) { return ['id'=>$item->id,'name'=>sprintf('%s: %s',$item->supplied->supplier->name,$item->supplied->name)]; })
					->sortBy('name')
					->values();

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

	/**
	 * Update a suppliers details
	 *
	 * @param Request $request
	 * @param Product $o
	 * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
	 */
	public function details(Request $request,Product $o)
	{
		if (! $o->exists && $request->name)
			$o = Product::where('name',$request->name)->firstOrNew();

		return view('theme.backend.adminlte.product.details')
			->with('breadcrumb',collect(['Products'=>url('a/product')]))
			->with('o',$o);
	}

	public function details_addedit(ProductAddEdit $request,Product $o)
	{
		foreach ($request->except(['_token','submit','translate','accounting']) as $key => $item)
			$o->{$key} = $item;

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

		// Trim down the pricing array, remove null values
		$o->pricing = $o->pricing->map(function($item) {
			foreach ($item as $k=>$v) {
				if (is_array($v)) {
					$v = array_filter($v);
					$item[$k] = $v;
				}
			}

			return $item;
		});

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

		$o->load(['translate']);
		$oo = $o->translate ?: new ProductTranslate;
		foreach ($request->get('translate',[]) as $key => $item)
			$oo->{$key} = $item;

		$o->translate()->save($oo);

		if ($request->accounting)
			foreach ($request->accounting as $k=>$v)
				$o->providers()->syncWithoutDetaching([
					$k => [
						'ref' => $v,
						'site_id'=>$o->site_id,
					],
				]);

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

	/**
	 * Manage products for a site
	 *
	 * @note This method is protected by the routes
	 * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
	 */
	public function home()
	{
		return view('theme.backend.adminlte.product.home');
	}
}