<?php

/**
 * 文件功能：婚姻参数配置服务
 *
 * 提供带缓存的婚姻系统参数读取与写入接口。
 * 管理员修改参数后自动清除缓存，所有婚姻相关 Service 均通过此类读取配置，
 * 不在代码中硬编码任何奖惩数值。
 *
 * @author  ChatRoom Laravel
 *
 * @version 1.0.0
 */

namespace App\Services;

use App\Models\MarriageConfig;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;

class MarriageConfigService
{
    /** 缓存 KEY 前缀 */
    private const CACHE_PREFIX = 'marriage_config:';

    /** 缓存 TTL（分钟） */
    private const CACHE_TTL = 60;

    /** 全量缓存 KEY（分组展示用） */
    private const ALL_CACHE_KEY = 'marriage_config:__all__';

    /**
     * 读取单个配置值（带缓存）。
     *
     * @param  string  $key  配置键名
     * @param  int  $default  找不到时的默认值
     */
    public function get(string $key, int $default = 0): int
    {
        return Cache::remember(
            self::CACHE_PREFIX.$key,
            now()->addMinutes(self::CACHE_TTL),
            fn () => MarriageConfig::where('key', $key)->value('value') ?? $default
        );
    }

    /**
     * 批量读取同一分组所有配置（后台页面用）。
     *
     * @param  string  $group  分组名
     * @return Collection<int, MarriageConfig>
     */
    public function getGroup(string $group): Collection
    {
        return MarriageConfig::where('group', $group)->orderBy('id')->get();
    }

    /**
     * 按分组名返回所有配置（后台页面用）。
     *
     * @return Collection<string, Collection<int, MarriageConfig>>
     */
    public function allGrouped(): Collection
    {
        return Cache::remember(
            self::ALL_CACHE_KEY,
            now()->addMinutes(self::CACHE_TTL),
            fn () => MarriageConfig::orderBy('id')->get()->groupBy('group')
        );
    }

    /**
     * 写入单个配置值，并清除相关缓存。
     *
     * @param  string  $key  配置键名
     * @param  int  $value  新值
     */
    public function set(string $key, int $value): bool
    {
        $rows = MarriageConfig::where('key', $key)->update(['value' => $value]);

        // 清除单项缓存及全量缓存
        Cache::forget(self::CACHE_PREFIX.$key);
        Cache::forget(self::ALL_CACHE_KEY);

        return $rows > 0;
    }

    /**
     * 批量写入配置（后台表单批量保存，接受 ['key' => value] 格式）。
     *
     * @param  array<string, int>  $data  键值对
     */
    public function batchSet(array $data): void
    {
        foreach ($data as $key => $value) {
            $this->set($key, (int) $value);
        }
    }

    /**
     * 清除全部婚姻配置缓存（迁移/重新 Seed 后调用）。
     */
    public function clearAll(): void
    {
        $keys = MarriageConfig::pluck('key');
        foreach ($keys as $key) {
            Cache::forget(self::CACHE_PREFIX.$key);
        }
        Cache::forget(self::ALL_CACHE_KEY);
    }
}
