<?php
namespace FlysystemOffload\Filesystem;

use FlysystemOffload\Filesystem\Adapters\AzureBlobAdapter;
use FlysystemOffload\Filesystem\Adapters\DropboxAdapter;
use FlysystemOffload\Filesystem\Adapters\GoogleCloudAdapter;
use FlysystemOffload\Filesystem\Adapters\GoogleDriveAdapter;
use FlysystemOffload\Filesystem\Adapters\OneDriveAdapter;
use FlysystemOffload\Filesystem\Adapters\S3Adapter;
use FlysystemOffload\Filesystem\Adapters\SftpAdapter;
use FlysystemOffload\Filesystem\Adapters\WebdavAdapter;
use League\Flysystem\Filesystem;
use League\Flysystem\FilesystemOperator;
use WP_Error;

class FilesystemFactory
{
    private array $settings;

    public function __construct(array $settings)
    {
        $this->settings = $settings;
    }

    public function make(): FilesystemOperator|WP_Error
    {
        $adapterKey = $this->settings['adapter'] ?? 'local';
        $config = $this->settings['adapters'][$adapterKey] ?? [];

        $adapter = $this->resolveAdapter($adapterKey);

        if (is_wp_error($adapter)) {
            return $adapter;
        }

        $validation = $adapter->validate($config);
        if (is_wp_error($validation)) {
            return $validation;
        }

        $flyAdapter = $adapter->create($config);
        if (is_wp_error($flyAdapter)) {
            return $flyAdapter;
        }

        return new Filesystem($flyAdapter);
    }

    public function resolvePublicBaseUrl(string $adapterKey, array $settings): string
    {
        $adapter = $this->resolveAdapter($adapterKey);

        if (is_wp_error($adapter)) {
            return content_url('/uploads');
        }

        return $adapter->publicBaseUrl($settings);
    }

    private function resolveAdapter(string $adapterKey): AdapterInterface|WP_Error
    {
        return match ($adapterKey) {
            's3' => new S3Adapter(),
            'sftp' => new SftpAdapter(),
            'gcs' => new GoogleCloudAdapter(),
            'azure' => new AzureBlobAdapter(),
            'webdav' => new WebdavAdapter(),
            'googledrive' => new GoogleDriveAdapter(), // stub (dev)
            'onedrive' => new OneDriveAdapter(),       // stub (dev)
            'dropbox' => new DropboxAdapter(),         // stub (dev)
            default => new class implements AdapterInterface {
                public function create(array $settings)
                {
                    return new \League\Flysystem\Local\LocalFilesystemAdapter(WP_CONTENT_DIR . '/flysystem-uploads');
                }
                public function publicBaseUrl(array $settings): string
                {
                    return content_url('/flysystem-uploads');
                }
                public function validate(array $settings)
                {
                    wp_mkdir_p(WP_CONTENT_DIR . '/flysystem-uploads');
                    return true;
                }
            }
        };
    }
}
