<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

use App\Http\Requests\SiteEdit;
use App\Models\{Account,
	Charge,
	Invoice,
	InvoiceItem,
	Payment,
	PaymentItem,
	Service,
	SiteDetail};

/**
 * The AdminController governs all routes that are prefixed with 'a/'.
 *
 * This is everything about the configuration of the application as a whole, or administration of a site.
 */
class AdminController extends Controller
{
	// @todo Move to reseller
	public function service(Service $o)
	{
		return view('theme.backend.adminlte.a.service')
			->with('o',$o);
	}

	/**
	 * Record payments on an account.
	 *
	 * @param Request $request
	 * @param Payment $o
	 * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
	 */
	// @todo Move to reseller
	public function pay_addedit(Request $request,Payment $o)
	{
		if ($request->post()) {

			$validation = $request->validate([
				'account_id' => 'required|exists:accounts,id',
				'paid_at' => 'required|date',
				'checkout_id' => 'required|exists:checkouts,id',
				'total_amt' => 'required|numeric|min:0.01',
				'fees_amt' => 'nullable|numeric|lt:total_amt',
				'source_id' => 'nullable|exists:accounts,id',
				'pending' => 'nullable|boolean',
				'notes' => 'nullable|string',
				'ip' => 'nullable|ip',
				'invoices' => ['required','array',function ($attribute,$value,$fail) use ($request) {
					if (collect($value)->sum('id') > $request->post('total_amt'))
						$fail('Allocation is greater than payment total.');
				}],
				'invoices.*.id' => ['required',function ($attribute,$value,$fail) {
					if (! Invoice::exists(str_replace(str_replace($attribute,'invoice\.','',),'.id','')))
						$fail('Invoice doesnt exist in DB');
				}],
			]);

			if (! $o->exists) {
				$o->site_id = config('site')->site_id;
				$o->active = TRUE;
			}

			$o->forceFill($request->only(['account_id','paid_at','checkout_id','total_amt','fees_amt','source_id','pending','notes','ip']));
			$o->save();

			foreach ($validation['invoices'] as $id => $amount) {
				// See if we already have a payment item that we need to update
				$items = $o->items->filter(function($item) use ($id) { return $item->invoice_id == $id; });

				if ($items->count() == 1) {
					$oo = $items->pop();
					if ($amount['id'] == 0) {
						$oo->delete();
						continue;
					}

				} else {
					$oo = new PaymentItem;
					$oo->invoice_id = $id;
				}

				$oo->amount = ($oo->invoice->due >= 0) && ($oo->invoice->due-$amount['id'] >= 0) ? $amount['id'] : 0;

				// If the amount is empty, ignore it.
				if (! $oo->amount)
					continue;

				$oo->site_id = config('site')->site_id;
				$oo->active = TRUE;
				$o->items()->save($oo);
			}

			return redirect()
				->back()
				->with('success','Payment recorded: '.$o->id);
		}

		return view('theme.backend.adminlte.a.payment.addedit')
			->with('o',$o);
	}

	/**
	 * List unapplied payments
	 *
	 * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
	 */
	// @todo Move to reseller
	public function pay_unapplied()
	{
		return view('theme.backend.adminlte.a.payment.unapplied');
	}

	/**
	 * Show a list of invoices to apply payments to
	 *
	 * @param Request $request
	 * @param Account $o
	 * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
	 */
	// @todo Move to reseller
	public function pay_invoices(Request $request,Account $o)
	{
		return view('theme.backend.adminlte.a.payment.widgets.invoices')
			->with('pid',$request->pid)
			->with('o',$o);
	}

	/**
	 * Site setup
	 *
	 * @note This method is protected by the routes
	 * @param SiteEdit $request
	 * @return RedirectResponse
	 */
	public function setup(SiteEdit $request)
	{
		$site = config('site');
		$images = ['site_logo','email_logo'];
		$validated = collect($request->validated());

		// Handle the images
		foreach($images as $key)
			if ($x=$request->validated($key))
				$validated->put($key,$x->storeAs('site/'.$site->site_id,$x->getClientOriginalName(),'public'));

		foreach ($site->details as $oo)
			if ($validated->has($oo->key)) {
				// Dont set the following keys to null if they are null
				if (in_array($oo->key,$images) && is_null($validated->get($oo->key)))
					continue;

				$oo->value = $validated->get($oo->key) ?: '';
				$oo->save();

				$validated->forget($oo->key);
			}

		// Left over values to be created.
		foreach ($validated as $k=>$v) {
			$oo = new SiteDetail;
			$oo->key = $k;
			$oo->value = $v ?: '';

			$site->details()->save($oo);
		}

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