<?php
declare (strict_types = 1);

namespace app\admin\controller\v1;

use app\admin\model\v1\ProductCategoryModel;
use app\admin\validate\v1\ProductCategoryValidate;

/**
 * 产品分类管理控制器
 */
class ProductCategory
{
    /**
     * 获取商品分类列表
     */
    public function index()
    {
        $params = request()->param([
            'is_show',
            'keywords' => '',
        ]);
        
        $ret = ProductCategoryModel::field([
                'id',
                'pid',
                'name',
                'level',
                'sort',
                'is_show'
            ])
            ->language(request()->lang_id)
            ->withSearch(['name_nullable'], [
                'name_nullable' => $params['keywords']??null
            ])
            ->where(function($query) use($params) {
                if (isset($params['is_show'])) {
                    $query->where('is_show', '=', $params['is_show']);
                }
            })
            ->select();
        if ($ret->isEmpty()) {
            return success('获取成功');
        }
        
        return success('获取成功', array_to_tree($ret->toArray(), 0, 'pid', 1));
    }

    /**
     * 获取商品分类详情
     */
    public function read()
    {
        $category = ProductCategoryModel::withoutField([
                'language_id',
                'created_at',
                'updated_at',
                'deleted_at',
            ])
            ->bypk(request()->param('id'))
            ->find();
        if (empty($category)) {
            return error('分类不存在');
        }

        return success('获取成功', $category);
    }

    /**
     * 新增商品分类
     */
    public function save()
    {
        $post = request()->post([
            'unique_id',
            'pid' => 0,
            'name',
            'icon',
            'desc',
            'related_tco_category',
            'sort',
            'level' => 1,
            'is_show' => 1
        ]);
        if (empty($post['unique_id'])) {
            $post['unique_id'] = uniqid('PRO_CATE_');
        }
        $data = array_merge($post, ['language_id' => request()->lang_id]);

        $validate = new ProductCategoryValidate;
        if (!$validate->scene('add')->check($data)) {
            return error($validate->getError());
        }

        $category = new ProductCategoryModel;

        // 处理层级
        if ($data['pid'] > 0) {
            $parent = $category->bypk($data['pid'])->find();
            if (!empty($parent)) {
                if (!empty($parent->path)) {
                    $data['path']  = $parent->path . ',' . $parent->id;
                }
                $data['level'] = $parent->level + 1;
            }
        }

        if (!$category->save($data)) {
            return error('操作失败');
        }
        return success('操作成功');
    }

    /**
     * 更新商品分类
     */
    public function update()
    {
        $id = request()->param('id');
        $put = request()->put([
            'unique_id',
            'pid' => 0,
            'name',
            'icon',
            'desc',
            'related_tco_category',
            'sort',
            'level' => 1,
            'is_show' => 1
        ]);
        $data = array_merge($put, [
            'id'          => $id,
            'language_id' => request()->lang_id
        ]);

        $validate = new ProductCategoryValidate;
        if (!$validate->check($data)) {
            return error($validate->getError());
        }

        $category = ProductCategoryModel::bypk($id)->find();
        if (empty($category)) {
            return error('请确认操作对对象是否存在');
        }

        // 处理层级
        $updated_level = false;
        if ($data['pid'] != $category->pid) {
            $parent = ProductCategoryModel::bypk($data['pid'])->find();
            if (!empty($parent)) {
                $data['path']  = $parent->id;
                if (!empty($parent->path)) {
                    $data['path']  = $parent->path . ',' . $data['path'];
                }
                $data['level'] = $parent->level + 1;
                $updated_level = true;
            }
        }

        if (!$category->save($data)) {
            return error('操作失败');
        }

        // 处理子分类层级
        if ($updated_level) {
            $this->handle_children($category->id, $data['path'], $data['level']);
        }

        return success('操作成功');
    }
    private function handle_children($pid, $path, $level)
    {
        $children = ProductCategoryModel::pid($pid)->select();
        if ($children->isEmpty()) {
            return;
        }
        foreach ($children as $child) {
            if (!empty($path)) {
                $child->path = $path. ','. $child->pid;
            }
            $child->level = $level + 1;
            if ($child->save()) {
                $this->handle_children($child->id, $child->path, $child->level);
            }
        }
    }

    /**
     * 设置排序值
     */
    public function sort()
    {
        $id   = request()->param('id');
        $sort = request()->post('sort');

        $category = ProductCategoryModel::bypk($id)->find();
        if (empty($category)) {
            return error('请确认操作对对象是否存在');
        }
        if ($sort != $category->sort) {
            $category->sort = $sort;
            if (!$category->save()) {
                return error('操作失败');
            }
        }
        return success('操作成功');
    }

    /**
     * 设置是否显示
     */
    public function show()
    {
        $id = request()->param('id');

        $category = ProductCategoryModel::bypk($id)->find();
        if (empty($category)) {
            return error('请确认操作对对象是否存在');
        }

        $category->is_show = (int)!$category->is_show;
        if (!$category->save()) {
            return error('操作失败');
        }
        return success('操作成功');
    }

    /**
     * 删除商品分类
     */
    public function delete()
    {
        $id = request()->param('id');
        $category = ProductCategoryModel::bypk($id)->find();
        if (empty($category)) {
            return error('请确认操作对对象是否存在');
        }

        if (!$category->delete()) {
            return error('操作失败');
        }
        return success('操作成功');
    }
}
