<?php

declare(strict_types=1);


namespace App\Blog\Support;

use App\Models\Setting;
use Illuminate\Support\Facades\File;

class ThemeManager
{
    public function path(?string $theme = null): string
    {
        return config('themes.path').($theme ? '/'.$theme : '');
    }

    public function active(): string
    {
        $active = Setting::get('active_theme', config('themes.default'));

        return $this->exists($active) ? $active : config('themes.default');
    }

    public function exists(string $theme): bool
    {
        return is_dir($this->path($theme)) && File::exists($this->path($theme).'/theme.json');
    }

    public function manifest(string $theme): array
    {
        $file = $this->path($theme).'/theme.json';
        if (! File::exists($file)) {
            return [];
        }

        return json_decode(File::get($file), true) ?? [];
    }

    /**
     * 扫描主题目录，返回所有主题 manifest。
     */
    public function all(): array
    {
        $themes = [];

        foreach (File::directories(config('themes.path')) as $dir) {
            $name = basename($dir);
            if (! File::exists($dir.'/theme.json')) {
                continue;
            }

            $manifest = $this->manifest($name);
            $themes[$name] = [
                'name' => $name,
                'title' => $manifest['title'] ?? $name,
                'version' => $manifest['version'] ?? '0.0.0',
                'description' => $manifest['description'] ?? '',
                'author' => $manifest['author'] ?? '',
                'screenshot' => $manifest['screenshot'] ?? null,
                'inject_points' => $manifest['inject_points'] ?? null,
                'active' => $name === $this->active(),
            ];
        }

        return $themes;
    }

    public function activate(string $theme): void
    {
        if (! $this->exists($theme)) {
            throw new \InvalidArgumentException("主题不存在: {$theme}");
        }

        Setting::set('active_theme', $theme);
        $this->prependViews();
    }

    /**
     * 把激活主题的 views 目录前置到全局视图路径。
     * 在 Provider boot 与运行时切换主题时调用。
     */
    public function prependViews(): void
    {
        // 迁移尚未执行（migrate:fresh 首轮）时跳过 DB 查询，使用默认主题
        $active = \Illuminate\Support\Facades\Schema::hasTable('settings')
            ? $this->active()
            : config('themes.default');

        $views = $this->path($active).'/views';

        if (! is_dir($views)) {
            return;
        }

        $paths = config('view.paths');
        array_unshift($paths, $views);
        config(['view.paths' => $paths]);
        app('view')->getFinder()->setPaths($paths);
    }

    /**
     * 解析主题下的一个视图名。
     * 优先使用激活主题的视图，缺失时回退到内置兜底视图（blog-default）。
     */
    public function view(string $view): string
    {
        $active = $this->active();

        if (view()->exists("theme.{$active}.{$view}")) {
            return "theme.{$active}.{$view}";
        }

        return "blog-default::{$view}";
    }

    public function assetUrl(string $path, ?string $theme = null): string
    {
        $theme = $theme ?? $this->active();

        return url('/themes/'.$theme.'/assets/'.ltrim($path, '/'));
    }

    /**
     * 主题变量（原 sablog stylevars 的现代化替代：主题级自定义配置）。
     */
    public function variables(?string $theme = null): array
    {
        $theme = $theme ?? $this->active();

        $vars = Setting::get('theme_vars_'.$theme, []);

        return is_array($vars) ? $vars : (json_decode((string) $vars, true) ?: []);
    }

    public function variable(string $key, mixed $default = null, ?string $theme = null): mixed
    {
        return $this->variables($theme)[$key] ?? $default;
    }
}
