<?php

namespace Kylin\Storage\Adapters;

use Kylin\Storage\Contracts\StorageAdapterInterface;
use Kylin\Storage\Qiniu\Auth;
use Kylin\Storage\Qiniu\Storage\UploadManager;
use Kylin\Storage\Qiniu\Storage\BucketManager;
use Kylin\Storage\Qiniu\Cdn\CdnManager;

class QiniuAdapter implements StorageAdapterInterface
{
    private Auth $auth;
    private string $bucket;
    private string $domain;
    private UploadManager $uploadManager;
    private BucketManager $bucketManager;

    public function __construct(array $config)
    {
        $this->auth = new Auth($config['access_key'], $config['secret_key']);
        $this->bucket = $config['bucket'];
        $this->domain = rtrim($config['domain'], '/');
        $this->uploadManager = new UploadManager();
        $this->bucketManager = new BucketManager($this->auth);
    }

    public function upload(string $localPath, string $remotePath, array $options = []): string
    {
        $token = $this->auth->uploadToken($this->bucket, $remotePath);
        $this->uploadManager->putFile($token, $remotePath, $localPath, $options);
        return $remotePath;
    }

    public function download(string $remotePath, ?string $localPath = null): string
    {
        $url = $this->getSignedUrl($remotePath);
        $content = file_get_contents($url);

        if ($localPath) {
            file_put_contents($localPath, $content);
            return $localPath;
        }

        $tmpPath = tempnam(sys_get_temp_dir(), 'qiniu_');
        file_put_contents($tmpPath, $content);
        return $tmpPath;
    }

    public function delete(string $remotePath): bool
    {
        $this->bucketManager->delete($this->bucket, $remotePath);
        return true;
    }

    public function getUrl(string $remotePath): string
    {
        return "{$this->domain}/{$remotePath}";
    }

    public function getSignedUrl(string $remotePath, int $expires = 3600): string
    {
        $cdnManager = new CdnManager($this->auth);
        $url = $this->getUrl($remotePath);
        $signedUrl = $cdnManager->createPrivateDownloadUrl($url, $expires);
        return $signedUrl;
    }

    public function exists(string $remotePath): bool
    {
        list(, $error) = $this->bucketManager->stat($this->bucket, $remotePath);
        return $error === null;
    }

    public function getSize(string $remotePath): int
    {
        list($stat, $error) = $this->bucketManager->stat($this->bucket, $remotePath);
        return $error === null ? (int) ($stat['fsize'] ?? 0) : 0;
    }

    public function getMimeType(string $remotePath): string
    {
        list($stat, $error) = $this->bucketManager->stat($this->bucket, $remotePath);
        return $error === null ? ($stat['mimeType'] ?? 'application/octet-stream') : 'application/octet-stream';
    }
}
