<?php

namespace App\Repositories\Core;

use App\Models\Shop\Category;

class Categories
{
    public static function getFancyTree()
    {
        $categories = self::getTree(true);
        $categories = Arrays::changeKeyName($categories, 'title', 'name');

        return Arrays::changeKeyName($categories, 'key', 'id');
    }

    public static function getTreeVisibles($withFolder = false)
    {
        $categories = self::getCategoryTreeVisibles()->toArray();

        return $categories ? self::getChildren($categories[0]['children'], $withFolder) : [];
    }

    public static function getTree($withFolder = false)
    {
        $categories = self::getCategoryTree()->toArray();

        return self::getChildren($categories[0]['children'], $withFolder);
    }

    public static function getCategoryTree()
    {
        return self::getModel()->defaultOrder()->get()->toTree();
    }

    public static function getCategoryTreeVisibles($sale_channel_id = false)
    {
        return self::getModel()->defaultOrder()
            ->hasAvailableOffersByCategoryParent($sale_channel_id)->visible()->get()->toTree();
    }

    public static function getChildren($data, $withFolder = false)
    {
        $tree = [];
        foreach ($data as $item) {
            $leaf = [];
            $leaf['name'] = $item['name'];
            $leaf['id'] = $item['id'];
            $children = $item['children'] ?? false ? self::getChildren($item['children']) : false;
            if ($children) {
                $leaf['children'] = $children;
                if ($withFolder) {
                    $leaf['folder'] = true;
                }
            } else {
                $leaf['children'] = [];
            }
            $tree[] = $leaf;
        }

        return collect($tree)->toArray();
    }

    public static function moveTree($node_id, $target_id, $type)
    {
        $category = self::getNode($node_id);
        $category_target = self::getNode($target_id);

        switch ($type) {
            case 'before':
                return $category->insertBeforeNode($category_target);
            case 'after':
                return $category->insertAfterNode($category_target);
            case 'inside':
                return $category_target->prependNode($category);
            default:
                return $category->insertAfterNode($category_target);
        }
    }

    public static function create($data)
    {
        $parent = $data['parent_id'] ?? false ? self::getNode($data['parent_id']) : self::getRoot();
        $category = self::getModel()->create(['name' => $data['name']]);
        $category->appendToNode($parent)->save();

        return $category;
    }

    public static function update($data, $id = false)
    {
        $id = $id ? $id : $data['id'];
        $item = self::getNode($id);
        $item->update($data);

        return $item;
    }

    public static function getRoot()
    {
        return self::getNode(1);
    }

    public static function getNode($id)
    {
        return self::getModel()->find($id);
    }

    public static function getModel()
    {
        return app(Category::class);
    }
}
