<?php
namespace FlysystemOffload\Filesystem\Adapters;

use Aws\S3\S3Client;
use FlysystemOffload\Filesystem\AdapterInterface;
use League\Flysystem\AwsS3V3\AwsS3V3Adapter;
use League\Flysystem\FilesystemAdapter;
use WP_Error;

class S3Adapter implements AdapterInterface
{
    public function validate(array $settings)
    {
        $required = ['access_key', 'secret_key', 'region', 'bucket'];

        foreach ($required as $field) {
            if (empty($settings[$field])) {
                return new WP_Error('flysystem_offload_invalid_s3', sprintf(__('Campo S3 faltante: %s', 'flysystem-offload'), $field));
            }
        }

        return true;
    }

    public function create(array $settings): FilesystemAdapter|WP_Error
    {
        try {
            $clientConfig = [
                'credentials' => [
                    'key' => $settings['access_key'],
                    'secret' => $settings['secret_key']
                ],
                'region' => $settings['region'],
                'version' => 'latest'
            ];

            if (!empty($settings['endpoint'])) {
                $clientConfig['endpoint'] = $settings['endpoint'];
                $clientConfig['use_path_style_endpoint'] = true;
            }

            $client = new S3Client($clientConfig);

            return new AwsS3V3Adapter($client, $settings['bucket'], $settings['prefix'] ?? '');
        } catch (\Throwable $e) {
            return new WP_Error('flysystem_offload_s3_error', $e->getMessage());
        }
    }

    public function publicBaseUrl(array $settings): string
    {
        $cdn = $settings['cdn_base_url'] ?? null;
        if ($cdn) {
            return rtrim($cdn, '/');
        }

        $bucket       = $settings['bucket'] ?? '';
        $endpoint     = $settings['endpoint'] ?? null;
        $region       = $settings['region'] ?? 'us-east-1';
        $usePathStyle = (bool) ($settings['use_path_style_endpoint'] ?? false);
        $prefix       = trim($settings['prefix'] ?? '', '/');

        $normalizedUrl = null;

        if ($endpoint) {
            $endpoint = rtrim($endpoint, '/');
            $parts    = parse_url($endpoint);

            if (! $parts || empty($parts['host'])) {
                $normalizedUrl = sprintf('%s/%s', $endpoint, $bucket);
            } elseif ($usePathStyle) {
                $path   = isset($parts['path']) ? rtrim($parts['path'], '/') : '';
                $scheme = $parts['scheme'] ?? 'https';
                $port   = isset($parts['port']) ? ':' . $parts['port'] : '';

                $normalizedUrl = sprintf('%s://%s%s%s/%s', $scheme, $parts['host'], $port, $path, $bucket);
            } else {
                $scheme = $parts['scheme'] ?? 'https';
                $port   = isset($parts['port']) ? ':' . $parts['port'] : '';
                $path   = isset($parts['path']) ? rtrim($parts['path'], '/') : '';

                $normalizedUrl = sprintf('%s://%s.%s%s%s', $scheme, $bucket, $parts['host'], $port, $path);
            }
        }

        if (! $normalizedUrl) {
            $normalizedUrl = sprintf('https://%s.s3.%s.amazonaws.com', $bucket, $region);
        }

        return $prefix ? $normalizedUrl . '/' . $prefix : $normalizedUrl;
    }
}
