<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\MenuSlider;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use App\Menu;
use App\Helpers\Helper;
use App\Http\Resources\Admin\MenuResource;
use Validator;

/**
 * Class MenuController
 *
 * @package App\Http\Controllers
 */
class MenuController extends Controller
{
    const ITEM_PER_PAGE = 100;
    private $_startOrder = 0;

    public function index(Request $request)
    {
        $searchParams = $request->all();
        $list = Menu::notDeleted()->orderBy('order')->orderBy('id', 'DESC');
        $limit = Arr::get($searchParams, 'limit', static::ITEM_PER_PAGE);
        $keyword = Arr::get($searchParams, 'keyword', '');
        $status = Arr::get($searchParams, 'status', '');

        if (!empty($keyword)) {
            $list->where('name', 'LIKE', '%' . $keyword . '%');
        }
        if ($status != '') {
            $list->where('is_activated', $status);
        }
        $list->orderBy('id', 'DESC');

        return MenuResource::collection($list->paginate($limit));
    }

    public function all()
    {
        $list = Menu::select('id', 'name', 'slug', 'position')->notDeleted()->orderBy('order')->orderBy('id', 'DESC');

        return MenuResource::collection($list->get());
    }

    public function allNested()
    {
        $list = Menu::with('slider')->select('id', 'name', 'type', 'link', 'category_id', 'parent_id', 'position', 'is_activated')->notDeleted()->orderBy('id')->get();
        $rs = $this->getChildItems($list, 0);

        return response()->json(['data' => $rs], 200);
    }

    public function getChildItems($list, $parent = 0)
    {
        $rs = [];
        foreach ($list as $item) {
            if ($item->parent_id == $parent) {
                $item['is_new_item'] = false;
                $item['is_deleted'] = false;
                $item['elements'] = $this->getChildItems($list, $item->id);
                $rs[] = $item;
            }
        }

        return $rs;
    }

    public function show($id = 0)
    {
        $menu = Menu::notDeleted()->where('id', $id)->first();
        if (!isset($menu)) return response()->json(['errors' => 'Menu is not valid'], 403);

        return new MenuResource($menu);
    }

    private function importMenuItem($items = [], $parentId = 0)
    {
        foreach ($items as $item) {
            if ($item['is_deleted'] == true) continue;
            $this->_startOrder += 1;
            $link = trim($item['link']);
            if ($item['type'] == 'text') {
                $link = "/" . $link;
                $link = str_replace("//", "/", $link);
            }
            $menu = Menu::create([
                'name'         => $item['name'],
                'slug'         => Helper::slug($item['name']),
                'type'         => $item['type'],
                'link'         => $link,
                'category_id'  => $item['category_id'],
                'parent_id'    => $parentId,
                'position'     => $item['position'],
                'order'        => $this->_startOrder,
                'is_activated' => $item['is_activated'],
                'created_at'   => date('Y-m-d H:i:s'),
                'updated_at'   => date('Y-m-d H:i:s')
            ]);
            if (isset($item['slider']) && count($item['slider']) > 0) {
                $sliderImport = [];
                foreach ($item['slider'] as $sIt) {
                    $sliderImport[] = [
                        'menu_id'     => $menu->id,
                        'image'       => $sIt['image'],
                        'title'       => $sIt['title'],
                        'description' => $sIt['description'],
                        'link'        => $sIt['link'],
                        'created_at'  => date('Y-m-d H:i:s'),
                        'updated_at'  => date('Y-m-d H:i:s')
                    ];
                }
                if (count($sliderImport) > 0) MenuSlider::insert($sliderImport);
            }
            $this->importMenuItem($item['elements'], $menu->id);
        }
    }

    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), ['items' => ['required']]);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $params = $request->all();
        Menu::truncate();
        MenuSlider::truncate();
        $this->importMenuItem($params['items'], 0);

        return response()->json(null, 200);
    }

    public function update($id = 0, Request $request)
    {
        $validator = Validator::make($request->all(), ['name' => ['required'], 'is_activated' => ['required']]);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $menu = Menu::notDeleted()->where('id', $id)->first();
        if (!isset($menu)) return response()->json(['errors' => 'Menu is not valid'], 403);
        $params = $request->all();
        $menu->update([
            'name'         => $params['name'],
            'slug'         => $params['name'],
            'type'         => $params['type'],
            'link'         => $params['link'],
            'category_id'  => $params['category_id'],
            'parent_id'    => $params['parent_id'],
            'position'     => $params['position'],
            'is_activated' => ($params['is_activated'] === true) ? 1 : 0,
            'updated_at'   => date('Y-m-d H:i:s')
        ]);

        return response()->json(null, 204);
    }

    public function destroy($id = 0)
    {
        $menu = Menu::notDeleted()->where('id', $id)->first();
        if (!isset($menu)) response()->json(['error' => 'Ehhh! Can not delete this category'], 403);

        try {
            $menu->update(['is_deleted' => true]);
        } catch (\Exception $ex) {
            response()->json(['error' => $ex->getMessage()], 403);
        }

        return response()->json(null, 204);
    }

    public function destroyMultiple(Request $request)
    {
        $validator = Validator::make($request->all(), ['ids' => 'required']);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $listIds = $request->get('ids', []);
        $menuList = Menu::notDeleted()->whereIn('id', $listIds)->get();
        if ($menuList->count() <= 0) response()->json(['error' => 'Menu is not valid.'], 403);
        try {
            Menu::notDeleted()->whereIn('id', $listIds)->update(['is_deleted' => true]);
        } catch (\Exception $ex) {
            response()->json(['error' => $ex->getMessage()], 403);
        }

        return response()->json(null, 204);
    }

    public function activateMultiple(Request $request)
    {
        $validator = Validator::make($request->all(), ['ids' => 'required']);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $listIds = $request->get('ids', []);
        $menuList = Menu::notDeleted()->whereIn('id', $listIds)->get();
        if ($menuList->count() <= 0) response()->json(['error' => 'Menu is not valid.'], 403);
        try {
            Menu::notDeleted()->whereIn('id', $listIds)->update(['is_activated' => true]);
        } catch (\Exception $ex) {
            response()->json(['error' => $ex->getMessage()], 403);
        }

        return response()->json(null, 204);
    }

    public function deactivateMultiple(Request $request)
    {
        $validator = Validator::make($request->all(), ['ids' => 'required']);
        if ($validator->fails()) return response()->json(['errors' => $validator->errors()], 403);
        $listIds = $request->get('ids', []);
        $menuList = Menu::notDeleted()->whereIn('id', $listIds)->get();
        if ($menuList->count() <= 0) response()->json(['error' => 'Menu is not valid.'], 403);
        try {
            Menu::notDeleted()->whereIn('id', $listIds)->update(['is_activated' => false]);
        } catch (\Exception $ex) {
            response()->json(['error' => $ex->getMessage()], 403);
        }

        return response()->json(null, 204);
    }

    public function position(Request $request)
    {
        if (!$request->has('position')) return response()->json(['errors' => 'Data is invalid'], 403);
        $newIndexes = $request->position;
        if (is_array($newIndexes)) {
            foreach ($newIndexes as $item) {
                Menu::where('id', $item['id'])->update(['order' => $item['order']]);
            }
        }

        return response()->json(null, 204);
    }
}
