<?php

namespace App\Http\Controllers\Frontend;

use App\Exceptions\ResourseNotFoundException;
use Facades\Repositories\DeviceRepo;
use Facades\Validators\DeviceExpensesFormValidator;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Tobuli\Entities\Device;
use Tobuli\Entities\DeviceExpense;
use App\Http\Controllers\Controller;
use Tobuli\Entities\DeviceExpensesType;

class DeviceExpensesController extends Controller
{

    public function index()
    {
        return view('front::DeviceExpenses.index', [
            'expenses' => $this->paginatedUserExpenses(),
        ]);
    }

    public function indexTable()
    {
        return view('front::DeviceExpenses.index_table', [
            'expenses' => $this->paginatedUserExpenses(),
        ]);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        $expense_types = DeviceExpensesType::all()->pluck('name', 'id');

        if ( ! request()->has('device_id'))
            return view('front::DeviceExpenses.create', [
                'devices'        => $this->user->devices->pluck('name', 'id'),
                'expenses_types' => $expense_types,
            ]);

        if (is_null($device = Device::find(request('device_id'))))
            throw new ResourseNotFoundException(trans('global.device'));

        $this->checkException('devices', 'edit', $device);

        return view('front::DeviceExpenses.create', [
            'device_id'      => $device->id,
            'expenses_types' => $expense_types,
        ]);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        DeviceExpensesFormValidator::validate('create', $this->data);

        $device = Device::find($request->device_id);

        if (is_null($device))
            throw new ResourseNotFoundException(trans('global.device'));

        $this->checkException('devices', 'edit', $device);

        $device->expenses()->create($request->all() + ['user_id' => $this->user->id]);

        return response()->json(['status' => 1]);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        if (is_null($expense = DeviceExpense::find($id)))
            throw new ResourseNotFoundException(trans('front.expenses'));

        $this->checkException('devices', 'edit', $expense->device);

        return view('front::DeviceExpenses.edit', [
            'device_id'      => request('device_id'),
            'expense'        => $expense,
            'expenses_types' => DeviceExpensesType::all()->pluck('name', 'id'),
        ]);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  int $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        DeviceExpensesFormValidator::validate('update', $this->data);

        if (is_null($expense = DeviceExpense::find($id)))
            throw new ResourseNotFoundException('front.expenses');

        $this->checkException('devices', 'edit', $expense->device);

        $expense->update($request->all());

        return response()->json(['status' => 1]);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        if (is_null($expense = DeviceExpense::find($id)))
            throw new ResourseNotFoundException('front.expenses');

        $this->checkException('devices', 'edit', $expense->device);

        $expense->delete();

        return response()->json(['status' => 1]);
    }

    public function table()
    {
        if (is_null($device = Device::find(request('device_id'))))
            throw new ResourseNotFoundException(trans('global.device'));

        $this->checkException('devices', 'show', $device);

        return view('front::DeviceExpenses.table', [
            'expenses'  => $device->expenses()->orderBy('date')->paginate(15),
            'total'     => $device->expenses()->sum(DB::raw('`quantity`*`unit_cost`')),
            'device_id' => $device->id,
        ]);
    }

    public function suppliers()
    {
        $suppliers = DeviceExpense::groupBy('supplier')
            ->select(['supplier', DB::raw('count(*) as total')])
            ->orderBy('total', 'desc')
            ->limit(10)
            ->get()->toArray();

        $suggestions = [];

        foreach ($suppliers as $supplier) {
            $suggestions[]['value'] = $supplier['supplier'];
        }

        return json_encode(['suggestions' => $suggestions]);
    }

    private function paginatedUserExpenses()
    {
        return DeviceExpense::join('user_device_pivot', 'device_expenses.device_id', '=', 'user_device_pivot.device_id')
            ->where('user_device_pivot.user_id', $this->user->id)
            ->select('device_expenses.*')
            ->orderBy('device_expenses.date')
            ->paginate(15);
    }
}
