<?php

namespace Kylin\Modules;

use Illuminate\Support\Collection;

/**
 * 模块集合
 *
 * 继承自 Laravel 的 Collection 类，用于管理模块集合
 */
class ModuleCollection extends Collection
{
    /**
     * 通过名称获取模块
     *
     * @param  string  $name  模块名称
     * @param  mixed  $default  默认值
     */
    public function get($name, mixed $default = null): mixed
    {
        return $this->first(fn (Module $module) => $module->getName() === $name, $default);
    }

    /**
     * 检查模块是否存在
     *
     * @param  string  $name  模块名称
     */
    public function has($name): bool
    {
        return !is_null($this->get($name));
    }

    /**
     * 获取启用的模块
     */
    public function enabled(): ModuleCollection
    {
        return $this->filter(fn (Module $module) => $module->isEnabled());
    }

    /**
     * 获取禁用的模块
     */
    public function disabled(): ModuleCollection
    {
        return $this->filter(fn (Module $module) => !$module->isEnabled());
    }

    /**
     * 按名称排序模块
     *
     * @param  int  $options  排序选项
     */
    public function sortByName(int $options = SORT_REGULAR): ModuleCollection
    {
        return $this->sortBy(fn (Module $module) => $module->getName(), $options);
    }

    /**
     * 按状态排序模块
     */
    public function sortByStatus(): ModuleCollection
    {
        return $this->sortBy(fn (Module $module) => $module->isEnabled() ? 0 : 1);
    }

    /**
     * 获取模块名称
     */
    public function names(): array
    {
        return $this->pluck('name')->all();
    }

    /**
     * 获取模块路径
     */
    public function paths(): array
    {
        return $this->pluck('path')->all();
    }

    /**
     * 通过路径查找模块
     *
     * @param  string  $path  路径
     */
    public function findByPath(string $path): ?Module
    {
        $realPath = realpath($path);
        return $this->first(fn (Module $module) => $module->getPath() === $realPath);
    }

    /**
     * 通过命名空间查找模块
     *
     * @param  string  $namespace  命名空间
     */
    public function findByNamespace(string $namespace): ?Module
    {
        return $this->first(fn (Module $module) => $module->getNamespace() === $namespace);
    }

    /**
     * 与另一个集合合并
     *
     * @param  Collection|array  $items  项目
     */
    public function merge($items): ModuleCollection
    {
        return new static(array_merge($this->items, $this->getArrayableItems($items)));
    }

    /**
     * 排序集合
     *
     * @param  callable|null  $callback  回调函数
     */
    public function sort($callback = null)
    {
        return parent::sort($callback);
    }

    /**
     * 过滤集合
     *
     * @param  callable|null  $callback  回调函数
     */
    public function filter(?callable $callback = null): ModuleCollection
    {
        return parent::filter($callback);
    }

    /**
     * 映射集合
     *
     * @param  callable  $callback  回调函数
     */
    public function map(callable $callback): ModuleCollection
    {
        return parent::map($callback);
    }

    /**
     * 排序并返回新集合
     *
     * @param  callable|string|null  $callback  回调函数
     * @param  int  $options  排序选项
     * @param  bool  $descending  是否降序
     */
    public function sortBy($callback, $options = SORT_REGULAR, $descending = false)
    {
        return parent::sortBy($callback, $options, $descending);
    }
}