<?php

namespace App\Http\Controllers\Admin;

use App\Enums\DbStatusFieldEnum;
use App\Http\Controllers\Controller;
use App\Models\ProductGroup;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Validation\Rule;
use Kalnoy\Nestedset\Collection;
use LaravelJsonApi\Core\Document\Error;

class ProductGroupController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        /*
                $error=Error::make()->setStatus(202);
                ['code'=>202,
                    'detail'=>'ez a hiba leirasa',
                    'status'=>202,
                    'title'=>'van baj'
                ]
        return $error;
        */
        return view('admin.productGroup.index');
    }

    public function treeNodeAdd(Request $request): JsonResponse
    {
        return response()->json(['id' => 'tmp_'.time()]);
    }

    private function nodeRename($nodeId, $name) {}

    private function nodeAdd(array $data, ?int $parentId = null)
    {
        $parent = ProductGroup::findOrFail($parentId);
        if (! isset($data['type']) || $data['type'] == null) {
            $data['type'] = $this->getParentType($parentId);
        }
        $node = $parent->children()->create($data);

        return $node;
    }

    private function getParentType(int $parentId, $defaultType = null)
    {
        $returnType = $defaultType;
        $nodes = ProductGroup::ancestorsAndSelf($parentId);
        $nodes = $nodes->toArray();
        rsort($nodes);
        foreach ($nodes as $node) {
            if ($node['type'] !== null) {
                return $node['type'];
            }
        }

        return $returnType;
    }

    public function treeNodeRename(Request $request, $id)
    {
        $rules = [];
        //        \Log::channel('chromePHP')->info(basename(__FILE__).':'.__LINE__,$request->all());

        if (substr($id, 0, 4) == 'tmp_') {
            $rules['name'] = Rule::unique('product_groups', 'name');
            $ProductGroup = new ProductGroup;
            $ProductGroup->canSee = true;
            $ProductGroup->status = DbStatusFieldEnum::active;
        } else {
            $ProductGroup = ProductGroup::findOrFail($id);
            $rules['name'] = Rule::unique('product_groups', 'name')->ignore($ProductGroup->name, 'name');
        }
        $validated = \Validator::make($request->all(), $rules);

        \Log::channel('chromePHP')->info(basename(__FILE__).':'.__LINE__);
        if ($validated->fails()) {
            $error = Error::make();
            $error->setStatus(500);
            $error->setDetail('Már létezik "'.$request->input('name').'"');
            $error->setTitle('Nem lehet átnevezni');

            return $error;
        }
        $ProductGroup->name = $request->input('name');
        if (! $ProductGroup->id) {
            \Log::channel('chromePHP')->debug('ujat kell letrehozni');
            $ProductGroup = $this->nodeAdd($ProductGroup->toArray(), $request->get('parents')[0]);
        } else {
            $ProductGroup->save();
        }

        return response()->json(['id' => $ProductGroup->id]);
    }

    public function treeNodeMove(Request $request, $id): JsonResponse
    {
        $ProductGroup = ProductGroup::findOrFail($id);
        $ProductGroupParent = ProductGroup::findOrFail($request->get('parent'));
        // moveNode($position)
        $ProductGroup->appendToNode($ProductGroupParent)->save();

        return response()->json(['id' => $ProductGroup->id]);
    }

    public function treeNodeDelete(Request $request, $id): JsonResponse
    {
        $ProductGroup = ProductGroup::findOrFail($id);
        $ProductGroup->delete();

        return response()->json(['id' => $ProductGroup->id]);
    }

    public function treeNodeGetContent($id): Response|JsonResponse
    {
        $item = ProductGroup::find($id);

        return response($item->name);
    }

    protected function getTreeRootChildren()
    {
        $root = ProductGroup::find(1);
        $nodes = ProductGroup::where('id', 1)->withDepth()->get();

        return $nodes;
    }

    protected function convertToTreeArray(Collection $nodes)
    {
        $treeArray = [];
        foreach ($nodes as $node) {
            $tmpNodeArray = [
                'text' => $node->name,
                'id' => $node->id,
            ];
            if ($node->depth < 3) {
                $tmpNodeArray['icon'] = 'jstree-folder';
                $tmpNodeArray['type'] = 'folder';
                if (ProductGroup::descendantsOf($node)->count() > 0) {
                    $tmpNodeArray['children'] = true;
                }
            } else {
                $tmpNodeArray['icon'] = 'jstree-file';
                $tmpNodeArray['type'] = 'file';
            }
            if (isset($node->depth)) {
                $tmpNodeArray['depth'] = $node->depth;
            }
            $treeArray[] = $tmpNodeArray;
        }

        return $treeArray;
    }

    public function treeNodeGet(Request $request): Response|JsonResponse|array
    {
        if (is_numeric($request->input('id'))) {
            $nodeDepth = ProductGroup::where('id', $request->input('id'))->withDepth()->first()->depth;
            $nodes = ProductGroup::find($request->input('id'))->descendants()->withDepth()->having('depth', '=', $nodeDepth + 1)->get();

            return $this->convertToTreeArray($nodes);
        } else {
            return $this->convertToTreeArray($this->getTreeRootChildren());
        }
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function show(ProductGroup $productGroup)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function edit(ProductGroup $productGroup)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, ProductGroup $productGroup)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @return \Illuminate\Http\Response
     */
    public function destroy(ProductGroup $productGroup)
    {
        //
    }
}
