<?php
namespace app\adminapi\service\material\storage;

use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
use Qiniu\Storage\BucketManager;

/**
 * 七牛云存储驱动
 * 依赖：composer require qiniu/php-sdk
 */
class QiniuStorage implements StorageInterface
{
    protected string $accessKey;
    protected string $secretKey;
    protected string $bucket;
    protected string $domain;

    public function __construct()
    {
        $cfg = (array)config('material.qiniu', []);
        $this->accessKey = (string)($cfg['access_key'] ?? '');
        $this->secretKey = (string)($cfg['secret_key'] ?? '');
        $this->bucket    = (string)($cfg['bucket'] ?? '');
        $this->domain    = (string)($cfg['domain'] ?? '');
        if (!$this->accessKey || !$this->secretKey || !$this->bucket || !$this->domain) {
            throw new \RuntimeException('七牛云配置不完整，请检查 config/material.php -> qiniu');
        }
    }

    public function put($file, string $keyPrefix = ''): array
    {
        $auth = new Auth($this->accessKey, $this->secretKey);
        $token = $auth->uploadToken($this->bucket);

        $uploadMgr = new UploadManager();
        $tmpPath = $file->getPathname();

        $origin = $file->getOriginalName();
        $ext = strtolower(pathinfo($origin, PATHINFO_EXTENSION));
        $key = trim($keyPrefix ?: 'material', '/') . '/' . date('Ymd') . '/' . uniqid('', true) . ($ext ? ('.' . $ext) : '');

        [$ret, $err] = $uploadMgr->putFile($token, $key, $tmpPath);
        if ($err !== null) {
            throw new \RuntimeException('上传七牛失败：' . $err->message());
        }
        $key = $ret['key'] ?? $key;
        return ['key' => $key, 'url' => $this->url($key)];
    }

    public function delete(string $key): void
    {
        try {
            $auth = new Auth($this->accessKey, $this->secretKey);
            $bucketMgr = new BucketManager($auth);
            $bucketMgr->delete($this->bucket, $key);
        } catch (\Throwable $e) {
            // 忽略物理删除失败
        }
    }

    public function url(string $key): string
    {
        return rtrim($this->domain, '/') . '/' . ltrim($key, '/');
    }
}
