<?php

namespace Kylin\Storage\Adapters;

use Kylin\Storage\Contracts\StorageAdapterInterface;
use Kylin\Storage\Kingsoft\Ks3Client;

class KingsoftAdapter implements StorageAdapterInterface
{
    private Ks3Client $client;
    private string $bucket;
    private string $domain;

    public function __construct(array $config)
    {
        $this->bucket = $config['bucket'];
        $this->domain = rtrim($config['domain'] ?? '', '/');

        $this->client = new Ks3Client(
            $config['access_key'],
            $config['secret_key'],
            $config['endpoint']
        );
    }

    public function upload(string $localPath, string $remotePath, array $options = []): string
    {
        $this->client->putObjectByFile(
            $this->bucket,
            $remotePath,
            $localPath
        );

        return $remotePath;
    }

    public function download(string $remotePath, ?string $localPath = null): string
    {
        $localPath = $localPath ?? tempnam(sys_get_temp_dir(), 'kylin_ks_');

        $this->client->getObject(
            $this->bucket,
            $remotePath,
            [],
            ['SaveAs' => $localPath]
        );

        return $localPath;
    }

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

    public function getUrl(string $remotePath): string
    {
        if ($this->domain) {
            return $this->domain . '/' . ltrim($remotePath, '/');
        }

        return $this->getSignedUrl($remotePath, 3600);
    }

    public function getSignedUrl(string $remotePath, int $expires = 3600): string
    {
        return $this->client->generatePresignedUrl(
            $this->bucket,
            $remotePath,
            $expires
        );
    }

    public function exists(string $remotePath): bool
    {
        try {
            $this->client->objectExists($this->bucket, $remotePath);
            return true;
        } catch (\Throwable) {
            return false;
        }
    }

    public function getSize(string $remotePath): int
    {
        $result = $this->client->getObjectMeta($this->bucket, $remotePath);
        return (int) ($result['ContentLength'] ?? 0);
    }

    public function getMimeType(string $remotePath): string
    {
        $result = $this->client->getObjectMeta($this->bucket, $remotePath);
        return $result['ContentType'] ?? 'application/octet-stream';
    }
}
