<?php

namespace App\Http\Controllers\Admin\Products;

use App\Models\ProductCategory;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\ProductCategoryStoreRequest;
use App\Http\Requests\Admin\ProductCategoryUpdateRequest;
use App\Services\Admin\Products\ProductCategoriesService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Inertia\Inertia;

class ProductCategoriesController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index(ProductCategoriesService $productCategoriesService)
    {
        return Inertia::render('Admin/Products/Categories/List', [
            'categories' => $productCategoriesService->getCategories(),
        ]);
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(ProductCategoryStoreRequest $request, ProductCategoriesService $productCategoriesService)
    {
        // initialiaze sort id
        $sortID = (ProductCategory::max('sort_id') ?? 0) + 1;

        if ($request->parent_id != 0) {
            if (ProductCategory::where('id', $request->parent_id)->first() == null) {
                return redirect()->back()->withErrors([__('messages.category_parent_not_found')]);
            }
        }

        if ($request->exists('slug') && $request->slug != null && ProductCategory::where('slug', $request->slug)->count() > 0) {
            return redirect()->back()->withErrors([__('messages.slug_is_exists')]);
        }

        // create category
        $category = ProductCategory::create([
            'parent_id' => $request->parent_id,
            'sort_id' => $sortID,
            'title' => $request->title,
            'slug' => $request->exists('slug') ? str_replace('/', '-', str_replace('\\', '-', str_replace('%', '', $request->slug))) : null,
            'content' => $request->exists('content') ? $request->content : null,
            'image' => $request->exists('image') ? $request->image : null,
            'seo_title' => $request->exists('seo_title') ? $request->seo_title : null,
            'seo_description' => $request->exists('seo_description') ? $request->seo_description : null,
            'seo_keywords' => $request->exists('seo_keywords') ? $request->seo_keywords : null,
            'seo_canonical' => $request->exists('seo_canonical') ? urldecode($request->seo_canonical) : null,
            'status' => 'publish',
        ]);

        // create specifications
        $productCategoriesService->createSpecifications($category, $request);

        /** Report Action */
        $this->report(__("messages.report_category_created"), 'category', $category);

        return redirect()->route('admin.product.categories.index')->with('message', [__('messages.category_created')]);
    }

    /**
     * Display the specified resource.
     */
    public function show(ProductCategory $category)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(ProductCategory $category)
    {
        return Inertia::render('Admin/Products/Categories/Edit', [
            'category' => $category,
            'specifications' => $category->get_specifications,
        ]);
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(ProductCategoryUpdateRequest $request, ProductCategory $category, ProductCategoriesService $productCategoriesService)
    {
        if (
            $request->filled('slug') &&
            ProductCategory::where('slug', $request->slug)
            ->where('id', '!=', $category->id)
            ->exists()
        ) {
            return back()->withErrors([__('messages.slug_is_exists')]);
        }

        // update category
        $category->update([
            'title' => $request->title,
            'slug' => $request->exists('slug') ? str_replace('/', '-', str_replace('\\', '-', str_replace('%', '', $request->slug))) : $category->slug,
            'content' => $request->exists('content') ? $request->content : $category->content,
            'image' => $request->exists('image') ? $request->image : $category->image,
            'seo_title' => $request->exists('seo_title') ? $request->seo_title : $category->seo_title,
            'seo_description' => $request->exists('seo_description') ? $request->seo_description : $category->seo_description,
            'seo_keywords' => $request->exists('seo_keywords') ? $request->seo_keywords : $category->seo_keywords,
            'seo_canonical' => $request->exists('seo_canonical') ? urldecode($request->seo_canonical) : $category->seo_canonical,
            'status' => 'publish',
        ]);

        // init specifications for update
        $productCategoriesService->initSpecifications($category, $request);

        /** Report Action */
        $this->report(__("messages.report_category_updated"), 'category', $category);

        return redirect()->route('admin.product.categories.edit', $category->slug)->with('message', [__('messages.category_updated')]);
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(ProductCategory $category)
    {
        if ($category->products()->where(function ($query) {
            $query->where('status', 'publish')->orWhere('status', 'draft')->orWhere('status', 'deleted');
        })->count() > 0)
            return redirect()->route('admin.product.categories.index')->withErrors([__('messages.category_has_product')]);

        if ($category->childs->count() > 0)
            return redirect()->route('admin.product.categories.index')->withErrors([__('messages.category_has_child')]);

        // delete category
        if ($category->products()->count() > 0) {
            $category->update([
                'status' => 'deep_deleted'
            ]);
        } else {
            $category->delete();
        }

        /** Report Action */
        $this->report(__("messages.report_category_deleted"), 'category', $category);

        return redirect()->route('admin.product.categories.index')->with('message', [__('messages.category_deleted')]);
    }

    /**
     * add category
     */
    public function add($category_id = null)
    {
        return Inertia::render('Admin/Products/Categories/Create', [
            'category_id' => $category_id
        ]);
    }

    /**
     * reorder categories
     */
    public function reorder(Request $request)
    {
        $request->validate([
            'categories' => 'required|array',
            'categories.*.id' => 'required|exists:product_categories,id',
            'categories.*.parent_id' => 'required|integer|min:0',
            'categories.*.sort_id' => 'required|integer|min:0',
        ]);

        $categoriesData = $request->categories;

        foreach ($categoriesData as $data) {
            $parentId = $data['parent_id'];
            if ($parentId != 0) {
                $parent = ProductCategory::find($parentId);
                if (!$parent) {
                    return back()->withErrors([__('messages.category_parent_not_found')]);
                }
                $grandParent = ProductCategory::where('id', $parent->parent_id)->first();
                if ($grandParent && $grandParent->parent_id != 0) {
                    return back()->withErrors([__('messages.category_max_level_is_three')]);
                }
            }

            $category = ProductCategory::find($data['id']);
            if ($parentId == $category->id) {
                return back()->withErrors([__('messages.category_cannot_be_its_own_parent')]);
            }
            if ($parentId != 0 && $category->getAllChildrenIds() && in_array($parentId, $category->getAllChildrenIds())) {
                return back()->withErrors([__('messages.category_cannot_be_a_subcategory_of_its_own_children')]);
            }
        }

        foreach ($categoriesData as $data) {
            ProductCategory::where('id', $data['id'])->update([
                'parent_id' => $data['parent_id'],
                'sort_id' => $data['sort_id'],
            ]);
        }

        // clear cache
        Cache::forget('main_categories');

        return redirect()->route('admin.product.categories.index')->with('message', [__('messages.changes_saved')]);
    }
}
