<?php

namespace App\Helpers;

use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Request; // 引入 Request 类
use App\Models\DistAdminDistributor;
use App\Models\DistAppearance;
use App\Models\DistAppearancePublishList;
use App\Services\MenuService;

class SiteCache
{
    /**
     * 获取或缓存商店信息
     *
     * @param string|null $domain
     * @param int $seconds 缓存时间(秒)
     * @return Dist|null
     */
    public static function getDist(?string $domain = null, int $seconds = 300): ?string
    {
        if (is_null($domain)) {
            return null; // 如果未传入域名,返回 null
        }

        self::checkAndClearCache($domain, 'dist'); // 检查是否需要清缓存

        return Cache::tags([$domain, 'dist'])->remember("dist_{$domain}", $seconds, function () use ($domain) {
            $dist= DistAdminDistributor::findByDomain($domain);

            // 检查 $dist 是否为 null
            if (!$dist)
            {
                // 如果找不到 $dist,返回 null 或其他默认值
                return null;
            }

            if (!empty($dist['appearance_id']))
            {
                $appearance = DistAppearance::getTemplateById($dist['appearance_id']);
                $publishList = DistAppearancePublishList::findByDistAndAppearance($dist['id'], $dist['appearance_id']);

                if ($appearance && $publishList) {
                    $dist['appearance'] = $appearance;
                    $dist['publishList'] = $publishList;
                    $dist['template_name'] = $appearance['folder'];
                } else {
                    return null; // 如果 appearance 或 publishList 加载失败,返回 null
                }
            }
            else
            {
                return null;
            }

            // 序列化存储
            return serialize($dist);
        });
    }

    /**
     * 清除商店信息缓存
     *
     * @param string|null $domain
     * @return void
     */
    public static function clearDistCache(?string $domain = null): void
    {
        if (is_null($domain)) {
            return; // 如果未传入域名,不执行清除操作
        }

        Cache::tags([$domain, 'dist'])->forget("dist_{$domain}");
    }

    /**
     * 获取或缓存商品信息
     *
     * @param string|null $domain
     * @param int|null $productId
     * @param int $seconds 缓存时间(秒)
     * @return Product|null
     */
    public static function getProduct(?string $domain = null, ?int $productId = null, int $seconds = 300): ?Product
    {
        if (is_null($domain) || is_null($productId)) {
            return null; // 如果未传入 domain 或 productId,返回 null
        }

        return Cache::tags([$domain, 'product'])->remember("product_{$productId}", $seconds, function () use ($productId) {
            return Product::find($productId);
        });
    }

    /**
     * 清除商品信息缓存
     *
     * @param string|null $domain
     * @param int|null $productId
     * @return void
     */
    public static function clearProductCache(?string $domain = null, ?int $productId = null): void
    {
        if (is_null($domain) || is_null($productId)) {
            return; // 如果未传入 domain 或 productId,不执行清除操作
        }

        Cache::tags([$domain, 'product'])->forget("product_{$productId}");
    }

    /**
     * 获取或缓存文章信息
     *
     * @param string|null $domain
     * @param int|null $articleId
     * @param int $seconds 缓存时间(秒)
     * @return Article|null
     */
    public static function getArticle(?string $domain = null, ?int $articleId = null, int $seconds = 300): ?Article
    {
        if (is_null($domain) || is_null($articleId)) {
            return null; // 如果未传入 domain 或 articleId,返回 null
        }

        return Cache::tags([$domain, 'article'])->remember("article_{$articleId}", $seconds, function () use ($articleId) {
            return Article::find($articleId);
        });
    }

    /**
     * 清除文章信息缓存
     *
     * @param string|null $domain
     * @param int|null $articleId
     * @return void
     */
    public static function clearArticleCache(?string $domain = null, ?int $articleId = null): void
    {
        if (is_null($domain) || is_null($articleId)) {
            return; // 如果未传入 domain 或 articleId,不执行清除操作
        }

        Cache::tags([$domain, 'article'])->forget("article_{$articleId}");
    }

    /**
     * 清除某一域名下的所有缓存
     *
     * @param string $domain
     * @return void
     */
    public static function clearAllDomainCache(string $domain): void
    {
        Cache::tags([$domain])->flush(); // 清除该域名标签下的所有缓存
    }

    /**
     * 清除某一域名下特定类型的缓存
     *
     * @param string $domain
     * @param string $type
     * @return void
     */
    public static function clearSpecificTypeCache(string $domain, string $type): void
    {
        //找出域名下的所有域名后再清除缓存

        if(!empty($domain)) {

            $dist= DistAdminDistributor::findByDomain($domain);

            if($dist?->secondary_domain) {
                Cache::tags([$dist?->secondary_domain, $type])->flush(); // 清除该域名下特定类型的缓存
            }

            if($dist?->custom_domain) {
                Cache::tags([$dist?->custom_domain, $type])->flush(); // 清除该域名下特定类型的缓存
            }

        }
    }


    /**
     * 获取多级菜单(支持缓存)
     *
     * @param int $seconds 缓存时间(秒)
     * @return array
     */
    public static function getMenu(string $domain,int $menu_location=0, int $dist_id=0,int $seconds = 300): array
    {
        // 检查 URL 是否需要清除菜单缓存
        self::checkAndClearCache($domain, 'menu'); // 检查是否需要清缓存

        // 使用缓存存储和获取多级菜单
        return  Cache::tags([$domain, "menu_{$menu_location}"])->remember('menu', $seconds, function () use ($menu_location,$dist_id) {
            $menuService = new MenuService();
            return $menuService->getMultiLevelMenu($menu_location,$dist_id);
        });
    }

    /**
     * 清除多级菜单缓存
     *
     * @return void
     */
    public static function clearMenuCache(?string $domain = null): void
    {
        Cache::tags([$domain,'menu'])->forget(); // 清除该域名下特定类型的缓存
    }
    /**
     * 检查 URL 是否包含清缓存参数并执行清除操作
     *
     * @param string|null $domain
     * @param string $type 缓存类型(如 'dist', 'product', 'article' 等)
     * @param int|null $id 相关 ID(可选)
     * @return void
     */
    public static function checkAndClearCache(?string $domain, string $type, ?int $id = null): void
    {
        if (Request::has('__clear_cache') && Request::input('__clear_cache') == 1) {
            if ($id) {
                self::clearSpecificTypeCache($domain, "{$type}_{$id}");
            } else {
                self::clearSpecificTypeCache($domain, $type);
            }
        }
    }
}