<?php

namespace Modules\Category\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Modules\Category\Entities\Category;
use Modules\Category\Http\Requests\CategoryRequest;
use Maatwebsite\Excel\Facades\Excel;
use Modules\Category\Exports\CategoriesExport;
use Modules\Document\Entities\Document;
use Modules\Marketing\Entities\Marketing;
use Modules\Training\Entities\Training;

class AdminController extends Controller
{
    public function __construct()
    {
        $this->authorizeResource(Category::class, 'category');
    }

    /**
     * Display a listing of the resource.
     * @return Renderable
     */
    public function index(Request $request)
    {
        if ($request->ajax()) {
            $data = Category::query()
                ->filters($request);

            return Category::makeDataTable($data);
        }

        return view('category::admin.index', [
            // 'groups' => Category::has('filteredChildren')->orderBy('name')->pluck('name', 'id')
        ]);
    }

    public function trashed(Request $request)
    {
        $this->authorize('restore', Category::class);

        if ($request->ajax()) {
            $data = Category::onlyTrashed();

            return Category::makeDataTable($data, trash: true);
        }

        return view('category::admin.trashed');
    }

    /**
     * Show the form for creating a new resource.
     * @return Renderable
     */
    public function create()
    {
        return view('category::admin.create', [
            'category' => new Category(),
            // 'groups' => Category::active()->orderBy('name')->pluck('name', 'id')
        ]);
    }

    /**
     * Store a newly created category in storage
     *
     * @param  \Modules\Category\Http\Requests\CategoryRequest $request
     * @param  \Modules\Category\Entities\Category $category
     * @return \Illuminate\Http\RedirectResponse
     */
    public function store(CategoryRequest $request, Category $category)
    {
        switch ($request->input('module')) {
            case 'document':
                $entity = Document::class;
                $route = 'document.categories';
                break;

            case 'training':
                $entity = Training::class;
                $route = 'training.categories';
                break;

            default:
                $entity = Marketing::class;
                $route = 'marketing.categories';
                break;
        }

        $category->create(array_merge($request->validated(), [
            'entity_type' => $entity,
            'is_active' => $request->boolean('is_active'),
        ]));

        return redirect()->route($route)->withStatus(__('New category successfully created.'));
    }

    /**
     * Show the form for editing the specified category
     *
     * @param  \Modules\Category\Entities\Category $category
     * @return \Illuminate\View\View
     */
    public function edit(Request $request, Category $category)
    {
        if ($request->boolean('redirect')) {
            if ($redirect = $this->editShouldRedirect($category)) {
                return $redirect;
            }
        }

        return view('category::admin.edit', [
            'category' => $category,
            // 'groups' => Category::active()->orderBy('name')->pluck('name', 'id')
        ]);
    }

    /**
     * Update the specified category in storage
     *
     * @param  \Modules\Category\Http\Requests\CategoryRequest $request
     * @param  \Modules\Category\Entities\Category $category
     * @return \Illuminate\Http\RedirectResponse
     */
    public function update(CategoryRequest $request, Category $category)
    {
        $category->update(array_merge($request->validated(), [
            'is_active' => $request->boolean('is_active'),
        ]));

        $message = __("Category #$category->id successfully updated.");

        if ($redirect = $this->editShouldRedirect($category)) {
            return $redirect->withStatus($message);
        }

        return redirect()->route('category.index')->withStatus($message);
    }

    public function reorder(Request $request)
    {
        $this->authorize('update', Category::class);

        $processed_ids = [];

        foreach (json_decode($request->get('categories', '[]')) as $obj) {
            $array = (array) $obj;
            $id = $array['id'];

            if (!in_array($id, $processed_ids)) {
                if ($array['parent_id'] === 0) {
                    $array['parent_id'] = null;
                }

                if (empty($array['name'])) {
                    unset($array['name']);
                }

                Category::where('id', $id)->update($array);

                array_push($processed_ids, $id);
            }
        }

        return back()->withStatus(__('All categories are successfully updated.'));
    }

    /**
     * Remove the specified category from storage
     *
     * @param  \Modules\Category\Entities\Category $category
     * @return \Illuminate\Http\RedirectResponse
     */
    public function destroy(Category $category)
    {
        $category->delete();

        return back()->withStatus(__("Category #$category->id successfully deleted."));
    }

    public function restore($id)
    {
        $category = Category::onlyTrashed()->findOrFail($id);

        $this->authorize('restore', $category);

        if ($category->trashed()) {
            $category->restore();

            return redirect()->route('category.trashed')->withStatus(__("Category #$category->id successfully restored."));
        }

        return redirect()->route('category.trashed')->withErrors(__("Category #$category->id cannot be restored."));
    }

    public function export(Request $request)
    {
        $this->authorize('export', Category::class);

        return Excel::download(new CategoriesExport($request), 'categories-' . now()->format('dmY_His') . '.xlsx');
    }

    private function editShouldRedirect(Category $category)
    {
        if (!is_null($category->entity_type)) {
            switch ($category->entity_type) {
                case Marketing::class:
                    return redirect()->route('marketing.category.edit', $category);
                    break;

                case Training::class:
                    return redirect()->route('training.category.edit', $category);
                    break;

                case Document::class:
                    return redirect()->route('document.category.edit', $category);
                    break;
            }
        }

        return null;
    }
}
