<?php

namespace App\Http\Controllers;

use App\Http\ViewHelpers\ViewFeeder;
use App\Manufacturer;
use App\Permission;
use Carbon\Carbon;
use DB;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Lang;
use Redirect;
use Session;

/**
 * Class ManufacturerController
 * @package App\Http\Controllers
 */
class ManufacturerController extends Controller implements ViewFeederAwareController
{
    const COLUMNS = [
        'id',
        'name',
        'created_at',
        'updated_at'
    ];

    /**
     * Create a new controller instance.
     */
    public function __construct()
    {
        $this->middleware('auth');
    }

    /**
     * Display a listing of the resource.
     *
     * @param Request $request
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $this->validate($request, [
            'sort' => Rule::in(self::COLUMNS),
            'ordering' => 'in:asc,desc',
            'count' => 'integer|min:5|max:100'
        ]);

        $sort = $request->get('sort', 'name');
        $ordering = $request->get('ordering', 'asc');
        $count = intval($request->get('count', 10));;

        $filter = $request->get('name', null);

        $where = [];
        if ($filter) {
            $where[] = ['name', 'LIKE', str_replace('*', '%', $filter)];
        }

        $entityClasses = DB::table('manufacturers as m')
            ->select([
                'm.id as id',
                'm.name as name',
                'm.created_at as created_at',
                'm.updated_at as updated_at'
            ])
            ->where($where)
            ->orderBy($sort, $ordering)
            ->orderBy('id', 'desc')
            ->paginate($count);

        $viewFeeder = new ViewFeeder($this, ViewFeeder::LIST);

        return view('results.list', $viewFeeder
            ->results($entityClasses)
            ->sorting($sort, $ordering)
            ->permissions([
                'canEdit' => Permission::EDIT_MANUFACTURER,
                'canDelete' => Permission::DELETE_MANUFACTURER
            ])
            ->feed()
        );
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        $viewFeeder = new ViewFeeder($this, ViewFeeder::CREATE);

        return view('non-device.create', $viewFeeder->feed());
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function store(Request $request)
    {
        $this->validate($request, [
            'name' => 'bail|required|unique:manufacturers|max:255'
        ]);

        $manufacturer = new Manufacturer([
            'name' => $request->name
        ]);
        $manufacturer->save();

        Session::flash('success', Lang::get('manufacturer.create_success'));

        return Redirect::route(self::getRouterName() . '.show', $manufacturer->id);
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Manufacturer $manufacturer
     * @return \Illuminate\Http\Response
     */
    public function show(Manufacturer $manufacturer)
    {
        $viewFeeder = new ViewFeeder($this, ViewFeeder::SHOW);

        $manufacturer->children_ids = DB::table('manufacturers as m')
            ->where('m.id', '=', $manufacturer->id)
            ->join('entities as d', 'm.id', '=', 'd.manufacturer_id')
            ->join('entity_classes as dc', 'd.entity_class_id', '=', 'dc.id')
            ->select([
                'dc.id as class_id',
                'dc.name as class_name',
                'dc.is_type as is_type',
                DB::raw('COUNT(*) as entities_count')
            ])
            ->groupBy('dc.id')
            ->get();

        return view('non-device.show', $viewFeeder
            ->result($manufacturer)
            ->permissions([
                'canEdit' => Permission::EDIT_MANUFACTURER,
                'canDelete' => Permission::DELETE_MANUFACTURER
            ])
            ->size(6)
            ->feed());
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Manufacturer $manufacturer
     * @return \Illuminate\Http\Response
     */
    public function edit(Manufacturer $manufacturer)
    {
        $viewFeeder = new ViewFeeder($this, ViewFeeder::EDIT);

        return view('non-device.edit', $viewFeeder
            ->result($manufacturer)
            ->size(6)
            ->feed());
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \App\Manufacturer $manufacturer
     * @return \Illuminate\Http\RedirectResponse
     */
    public function update(Request $request, Manufacturer $manufacturer)
    {
        if ($manufacturer->name === $request->get('name')) {
            Session::flash('error', Lang::get('validation.unchanged'));
            return Redirect::back();
        }

        if ($request->has('id')) {
            Session::flash('error', Lang::get('validation.id_change_forbidden'));
            return Redirect::back();
        }

        $this->validate($request, [
            'name' => 'bail|required|unique:manufacturers|max:255'
        ]);

        $manufacturer->name = $request->name;

        $manufacturer->updated_at = Carbon::now();
        $manufacturer->save();

        Session::flash('success', Lang::get('manufacturer.update_success'));

        return Redirect::route(self::getRouterName() . '.show', $manufacturer->id);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param Manufacturer $manufacturer
     * @return \Illuminate\Http\RedirectResponse
     * @internal param int $id
     */
    public function destroy(Manufacturer $manufacturer)
    {
        $deleted = $manufacturer->delete();

        if ($deleted)
            Session::flash('success', Lang::trans('manufacturer.delete_success', ['id' => $manufacturer->id]));
        else
            Session::flash('error', Lang::trans('manufacturer.delete_failed', ['id' => $manufacturer->id]));

        return Redirect::route(self::getRouterName() . '.index');
    }

    /**
     * Gets the name of the router to be used from the view.
     *
     * @return string
     */
    public static function getRouterName(): string
    {
        return 'manufacturers';
    }

    /**
     * Returns singular of object controller is working with.
     *
     * @return string
     */
    public function getSingular(): string
    {
        return 'Manufacturer';
    }

    /**
     * Returns plural of object controller is working with.
     *
     * @return string
     */
    public function getPlural(): string
    {
        return 'Manufacturers';
    }

    /**
     * Returns array of columns to be shown when listing objects controller is working with.
     *
     * @return array
     */
    public function getColumns(): array
    {
        return self::COLUMNS;
    }
}
