<?php

namespace Kylin\Dictionary\Services;

use Illuminate\Support\Facades\Cache;
use Kylin\Dictionary\Models\DictItem;
use Kylin\Dictionary\Models\DictType;
use Kylin\Dictionary\Traits\DictAudit;

/**
 * 字典服务
 *
 * 提供字典数据的缓存查询，支持按编码获取字典项列表。
 *
 * 合规要求：
 *  - 依据等保 2.0 (GB/T 22239) 8.1.4.6，字典增删改操作需记录审计日志
 */
class DictionaryService
{
    use DictAudit;

    public function getItemsByCode(string $code): array
    {
        $cacheKey = config('kylin-dictionary.cache.key', 'kylin.dictionary') . ".{$code}";
        $ttl = config('kylin-dictionary.cache.ttl', 86400);

        if (config('kylin-dictionary.cache.enabled', true)) {
            return Cache::remember($cacheKey, $ttl, fn () => $this->resolveItems($code));
        }

        return $this->resolveItems($code);
    }

    public function createType(string $code, string $name, ?string $description = null): DictType
    {
        $type = DictType::create(compact('code', 'name', 'description'));

        // 审计日志：字典类型创建
        $this->auditDict('dict_type_created', $type->id, [
            'code' => $code,
            'name' => $name,
        ]);

        return $type;
    }

    public function createItem(int $typeId, string $label, string $value, int $sort = 0, ?string $description = null): DictItem
    {
        $item = DictItem::create(compact('typeId', 'label', 'value', 'sort', 'description'));
        $this->clearCache($typeId);

        // 审计日志：字典项创建
        $this->auditDict('dict_item_created', $item->id, [
            'type_id' => $typeId,
            'label' => $label,
            'value' => $value,
        ]);

        return $item;
    }

    public function clearCache(?int $typeId = null): void
    {
        if ($typeId) {
            $type = DictType::find($typeId);
            if ($type) {
                Cache::forget(config('kylin-dictionary.cache.key', 'kylin.dictionary') . ".{$type->code}");
            }
        } else {
            $types = DictType::all();
            foreach ($types as $type) {
                Cache::forget(config('kylin-dictionary.cache.key', 'kylin.dictionary') . ".{$type->code}");
            }
        }
    }

    private function resolveItems(string $code): array
    {
        $type = DictType::where('code', $code)->first();
        if (! $type) {
            return [];
        }
        return $type->items()
            ->where('status', 1)
            ->orderBy('sort')
            ->get(['label', 'value'])
            ->toArray();
    }
}