<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Kalnoy\Nestedset\NodeTrait;

class Menu extends Model
{
    use NodeTrait;

    protected $table = 'tb_menu';
    protected $primaryKey = 'id';

    public $keyType = 'int';
    public $incrementing = true;
    public $timestamps = true;

    public string $cacheName_1 = 'menu-config';
    public string $cacheName_2 = 'menu-front';
    public int $cacheTime = 31536000;

    const CREATED_AT = 'created_at';
    const UPDATED_AT = 'updated_at';
    const DELETED_AT = null;

    protected $guarded = [];

    public function getLftName(): string
    {
        return 'lft';
    }

    public function getRgtName(): string
    {
        return 'rgt';
    }

    public function getParentIdName(): string
    {
        return 'parent_id';
    }

   /**
    * 메뉴 DB 조회
    */
    public function data(): ?object
    {
        if (!$ret = Cache::get($this->cacheName_1)) {
            $list = DB::select("CALL SP_MENU_LIST();");
            $rows = count($list);
            $total = $this->count();

            $ret = (object)[
                'total' => $total,
                'rows' => $rows,
                'list' => $list
            ];

            Cache::put($this->cacheName_1, $ret, $this->cacheTime);
        }
        return $ret;
    }

    /**
     * 메뉴 저장
     */
    public function register(array $insertData): int
    {
        $insertData = [
            $insertData['menu_id'],
            $insertData['board_id'],
            $insertData['name'],
            $insertData['link'],
            $insertData['target'],
            $insertData['desktop'],
            $insertData['mobile'],
            $insertData['custom'],
            $insertData['icon'],
            $insertData['depth']
        ];

        $menuID = DB::selectOne("CALL SP_MENU_SAVE(?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", $insertData)->id;

        $this->reload();
        return $menuID;
    }

    /**
     * 메뉴 수정
     */
    public function updater(array $updateData): void
    {
        DB::select("CALL SP_MENU_UPDATE(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", [
            $updateData['menu_id'],
            $updateData['parent_id'],
            $updateData['board_id'],
            $updateData['name'],
            $updateData['link'],
            $updateData['target'],
            $updateData['desktop'],
            $updateData['mobile'],
            $updateData['custom'],
            $updateData['icon'],
            $updateData['depth']
        ]);
        $this->reload();
    }

    /**
     * 메뉴 삭제
     */
    public function remove(int $menuID): void
    {
        DB::select("CALL SP_MENU_DELETE(?);", [$menuID]);
        $this->reload();
    }

    /**
     * 메뉴 캐시 생성
     */
    private function reload(): void
    {
        Cache::forget($this->cacheName_1);
        Cache::forget($this->cacheName_2);
        $this->data();
    }

    /**
     * 메뉴 한 단계 위로
     */
    public function orderUp(int $menuID): void
    {
        $this->findCategory($menuID)->up();
        $this->reload();
    }

    /**
     * 메뉴 한 단계 아래로
     */
    public function orderDown(int $menuID): void
    {
        $this->findCategory($menuID)->down();
        $this->reload();
    }

    /**
     * 메뉴 조회
     */
    public function findCategory(int $menuID): Menu
    {
        return (new Menu)->newQuery()->findOrNew($menuID);
    }
}

