<?php

namespace App\Services;

use App\Enums\Status;
use App\Http\Responses\ApiResponse;
use App\Models\Content;
use App\Models\ContentCategory;
use App\Traits\HasTree;

class ContentCategoryService
{
    public function index(array $params): array
    {
        $query = ContentCategory::with('model')->orderBy('sort', 'asc')->orderBy('id', 'desc');

        if (! empty($params['keyword'])) {
            $query->where('name', 'like', "%{$params['keyword']}%");
        }

        if (isset($params['status']) && $params['status'] !== '') {
            $query->where('status', $params['status']);
        }

        $categories = $query->get();
        $tree = HasTree::buildTree($categories->toArray());

        return ApiResponse::success($tree);
    }

    public function tree(): array
    {
        $categories = ContentCategory::where('status', Status::ENABLED)
            ->with('model:id,name,alias')
            ->orderBy('sort', 'asc')
            ->get();

        $tree = HasTree::buildTree($categories->toArray());

        $this->appendModelInfo($tree);

        return ApiResponse::success($tree);
    }

    private function appendModelInfo(array &$items): void
    {
        foreach ($items as &$item) {
            if (! empty($item['model'])) {
                $item['model_name'] = $item['model']['name'] ?? '';
                $item['model_alias'] = $item['model']['alias'] ?? '';
            } else {
                $item['model_name'] = '';
                $item['model_alias'] = '';
            }
            unset($item['model']);
            if (! empty($item['children'])) {
                $this->appendModelInfo($item['children']);
            }
        }
    }

    public function store(array $data): array
    {
        $parentId = $data['parent_id'] ?? 0;

        if ($parentId > 0) {
            $parent = ContentCategory::find($parentId);
            if (! $parent) {
                return ApiResponse::error(40100, '父级分类不存在');
            }
            if ($parent->model_id) {
                return ApiResponse::error(40101, '已绑定模型的分类不允许添加子分类');
            }
        }

        $category = ContentCategory::create([
            'parent_id' => $parentId,
            'model_id' => $data['model_id'] ?? null,
            'name' => $data['name'],
            'icon' => $data['icon'] ?? null,
            'image' => $data['image'] ?? null,
            'description' => $data['description'] ?? null,
            'sort' => $data['sort'] ?? 0,
            'status' => $data['status'] ?? Status::ENABLED->value,
        ]);

        return ApiResponse::success($category, '创建成功');
    }

    public function show(int $id): array
    {
        $category = ContentCategory::with('model')->find($id);

        if (! $category) {
            return ApiResponse::error(40100, '分类不存在');
        }

        return ApiResponse::success($category);
    }

    public function update(int $id, array $data): array
    {
        $category = ContentCategory::find($id);

        if (! $category) {
            return ApiResponse::error(40100, '分类不存在');
        }

        $oldModelId = $category->model_id;
        $newModelId = array_key_exists('model_id', $data) ? $data['model_id'] : $oldModelId;

        if ($oldModelId && $newModelId != $oldModelId && Content::where('category_id', $id)->exists()) {
            return ApiResponse::error(40104, '该分类下已有内容数据，请先移动或删除内容后再更换/解绑模型');
        }

        $category->update([
            'parent_id' => array_key_exists('parent_id', $data) ? $data['parent_id'] : $category->parent_id,
            'model_id' => $newModelId,
            'name' => array_key_exists('name', $data) ? $data['name'] : $category->name,
            'icon' => array_key_exists('icon', $data) ? $data['icon'] : $category->icon,
            'image' => array_key_exists('image', $data) ? $data['image'] : $category->image,
            'description' => array_key_exists('description', $data) ? $data['description'] : $category->description,
            'sort' => array_key_exists('sort', $data) ? $data['sort'] : $category->sort,
            'status' => array_key_exists('status', $data) ? $data['status'] : $category->status,
        ]);

        return ApiResponse::success($category, '更新成功');
    }

    public function destroy(int $id): array
    {
        $category = ContentCategory::find($id);

        if (! $category) {
            return ApiResponse::error(40100, '分类不存在');
        }

        if (ContentCategory::where('parent_id', $id)->exists()) {
            return ApiResponse::error(40102, '该分类下有子分类，不可删除');
        }

        if (Content::where('category_id', $id)->exists()) {
            return ApiResponse::error(40103, '该分类下有内容，不可删除');
        }

        $category->delete();

        return ApiResponse::success(null, '删除成功');
    }

    public function updateStatus(int $id, int $status): array
    {
        $category = ContentCategory::find($id);

        if (! $category) {
            return ApiResponse::error(40100, '分类不存在');
        }

        $category->update(['status' => $status]);

        return ApiResponse::success($category, $status === Status::ENABLED->value ? '启用成功' : '禁用成功');
    }

    public function saveSort(array $ids, array $sorts): array
    {
        foreach ($ids as $index => $id) {
            ContentCategory::where('id', $id)->update([
                'sort' => isset($sorts[$index]) ? intval($sorts[$index]) : 0,
            ]);
        }

        return ApiResponse::success(null, '排序保存成功');
    }
}
