<?php

namespace app\controller\manager\mall;

use app\controller\manager\Base;
use app\repository\CmsRepository;
use app\model\mall\Category as CategoryModel;

use app\validate\MenuValidate;
use Exception;
use think\facade\Db;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\exception\ValidateException;
use think\response\Json;
use think\response\View;

/**
 * 商品分类管理
 *
 * Class Menu
 * @package app\controller\manager\mall
 */
class Category extends Base
{
    /**
     * 删除
     *
     * @return Json
     */
    public function del(): Json
    {
        if ($this->request->isPost()) {
            $ids = input('post.ids/a', []);
            if (empty($ids)) {
                $ids[] = input('post.id/d');
            }
            if (CategoryModel::hasChildrenByIds($ids)) {
                return $this->json(4002, '待删除数据存在子数据');
            }

            if (CategoryModel::hasContentByIds($ids)) {
                return $this->json(4002, '待删除数据存在内容文章');
            }
            CategoryModel::deleteByIds($ids);
            //            Log::write(get_class().'Del', 'del', '涉及到的ID为：'.implode(',', $ids));
            return $this->json();
        }
        return $this->json(4001, '非法请求!');
    }

    /**
     * 编辑
     *
     * @return Json|View
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     * @throws Exception
     */
    public function edit()
    {
        $id = input('id/d', 0);

        if (!$info = CategoryModel::findById($id)) {
            return $this->json(4001, '记录不存在');
        }

        if ($this->request->isPost()) {
            $item     = input('post.');
            $validate = $this->validateByApi($item, [
                'pid|父级分类'       => 'require|number',
                'title|标题'       => 'require|max:100',
               // 'name|标识'        => 'unique:spu_category,name,'.$info['id'] ?? 0,
                'description|描述' => 'max:255',
            ]);

            if ($validate !== true) {
                return $validate;
            }

            Db::startTrans();
            try {
                $oldPath      = $info['path'] ?? '';
                $item['path'] = CategoryModel::getPath($item['pid']);
                $info->save($item);

                //刷新所有路径
                $oldPath = $oldPath.','.$id;
                $newPath = $item['path'].','.$id;
                if ($oldPath != $newPath) {
                    CategoryModel::refreshPath();
                }
                Db::commit();
                return $this->json();
            } catch (ValidateException $e) {
                Db::rollback();
                return $this->json(4001, $e->getError());
            }
        }

        $disabled                = CategoryModel::getAllChildrenIds($id);
        $disabled[]              = $id;
        $this->data['jsonList']  = $this->categoryJson([$info['pid']], $disabled);
        $this->data['item']      = $info;

        return $this->view();
    }

    /**
     * 单个字段编辑
     *
     * @return Json
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function modify(): Json
    {
        if ($this->request->isPost()) {
            $item     = input('post.');
            $validate = new MenuValidate();
            if (!$validate->scene('menu_modify')->check($item)) {
                return $this->json(4002, $validate->getError());
            }

            if (!$info = CategoryModel::findById($item['id'])) {
                return $this->json(4001, '记录不存在');
            }

            $update = [$item['field'] => $item['value']];

            try {
                $info->save($update);
                return $this->json();
            } catch (ValidateException $e) {
                return $this->json(4001, $e->getError());
            }
        }
        return $this->json(4000, '非法请求');
    }

    /**
     * 添加
     *
     * @return Json|View
     * @throws Exception
     */
    public function add()
    {
        if ($this->request->isPost()) {
            $item     = input('post.');
            $validate = $this->validateByApi($item, [
                'pid|父级分类'       => 'require|number',
                'title|标题'       => 'require|max:100',
                //'name|标识'        => 'require|unique:spu_category',
                'description|描述' => 'max:255',
            ]);

            if ($validate !== true) {
                return $validate;
            }
            Db::startTrans();
            try {
                $item['path'] = CategoryModel::getPath($item['pid']);
                (new CategoryModel())->create($item);
                Db::commit();
                return $this->json();
            } catch (ValidateException $e) {
                Db::rollback();
                return $this->json(4001, $e->getError());
            }
        }

        $this->data['jsonList']  = $this->categoryJson();

        return $this->view();
    }

    /**
     * 列表
     *
     * @return Json|View
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function index()
    {
        if ($this->request->isPost()) {
            $menus = CategoryModel::getList();
            $res   = [
                'code'  => 0,
                'msg'   => 'success',
                'count' => $menus->count(),
                'data'  => $menus->toArray(),
            ];
            return json($res);
        }
        return $this->view();
    }

    /**
     * @param  array  $selected
     * @param  array  $disabled
     * @return false|string
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    private function categoryJson(array $selected = [], array $disabled = [])
    {
        $categoryList[] = ['title' => '顶级分类', 'id' => 0, 'disabled' => false, 'selected' => in_array(0, $selected)];
        $menus          = CategoryModel::getList();
        $menus          = $menus->toArray();
        foreach ($menus as $k => $m) {
            $menus[$k]['selected'] = in_array($m['id'], $selected);
            $menus[$k]['disabled'] = in_array($m['id'], $disabled);
        }
        $menus        = CmsRepository::getInstance()->buildMenuChild(0, $menus);
        $categoryList = array_merge($categoryList, CmsRepository::getInstance()->handleSelectedList($menus));
        return json_encode($categoryList, JSON_UNESCAPED_UNICODE);
    }
}