<?php

namespace Kylin\Storage\Adapters;

use Kylin\Storage\Contracts\StorageAdapterInterface;
use Kylin\Storage\Tencent\Client as CosClient;

class TencentAdapter implements StorageAdapterInterface
{
    private CosClient $client;
    private string $bucket;

    public function __construct(array $config)
    {
        $this->bucket = $config['bucket'];
        $this->client = new CosClient([
            'region' => $config['region'],
            'schema' => $config['schema'] ?? 'https',
            'credentials' => [
                'secretId' => $config['secret_id'],
                'secretKey' => $config['secret_key'],
                'token' => $config['token'] ?? null,
            ],
        ]);
    }

    public function upload(string $localPath, string $remotePath, array $options = []): string
    {
        $this->client->upload(
            $this->bucket,
            $remotePath,
            fopen($localPath, 'rb'),
            $options
        );
        return $remotePath;
    }

    public function download(string $remotePath, ?string $localPath = null): string
    {
        $result = $this->client->getObject([
            'Bucket' => $this->bucket,
            'Key' => $remotePath,
        ]);

        $content = $result['Body'];

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

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

    public function delete(string $remotePath): bool
    {
        $this->client->deleteObject([
            'Bucket' => $this->bucket,
            'Key' => $remotePath,
        ]);
        return true;
    }

    public function getUrl(string $remotePath): string
    {
        return $this->client->getObjectUrl($this->bucket, $remotePath);
    }

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

    public function exists(string $remotePath): bool
    {
        try {
            $this->client->headObject([
                'Bucket' => $this->bucket,
                'Key' => $remotePath,
            ]);
            return true;
        } catch (\Throwable) {
            return false;
        }
    }

    public function getSize(string $remotePath): int
    {
        try {
            $result = $this->client->headObject([
                'Bucket' => $this->bucket,
                'Key' => $remotePath,
            ]);
            return (int) ($result['ContentLength'] ?? 0);
        } catch (\Throwable) {
            return 0;
        }
    }

    public function getMimeType(string $remotePath): string
    {
        try {
            $result = $this->client->headObject([
                'Bucket' => $this->bucket,
                'Key' => $remotePath,
            ]);
            return $result['ContentType'] ?? 'application/octet-stream';
        } catch (\Throwable) {
            return 'application/octet-stream';
        }
    }
}
