<?php

namespace CaptureRelay;

final class Config
{
    public const API_NAMESPACE = 'capture-relay/v1';
    public const NETWORK_ID = 'capture-relay';
    public const PRIVACY_URL = 'https://www.capturerelay.app/privacy.html';
    public const TERMS_URL = 'https://www.capturerelay.app/terms.html';
    public const CONTACT_URL = 'https://www.capturerelay.app/#contact';
    public const DB_VERSION = '1.1.1';
    public const MIN_IMAGE_DIMENSION = 100;
    public const MAX_IMAGE_DIMENSION = 12000;
    public const MIN_IMAGE_PIXELS = 1000000;
    public const MAX_IMAGE_PIXELS = 40000000;

    private const TABLE_SUFFIXES = [
        'requests',
        'devices',
        'blocks',
        'rate_limits',
        'nonces',
        'uploads',
        'activity',
    ];

    public static function defaults(): array
    {
        return [
            'uploads_enabled' => true,
            'new_requests_enabled' => true,
            'approval_emails' => true,
            'upload_emails' => false,
            'notification_recipients' => (string) get_option('admin_email', ''),
            'request_expiration_hours' => 24,
            'request_retention_days' => 30,
            'maximum_pending_requests' => 25,
            'requests_per_hour_ip' => 10,
            'requests_per_hour_device' => 3,
            'requests_per_hour_global' => 60,
            'media_requests_per_hour_ip' => 240,
            'pairing_requests_per_hour_ip' => 1200,
            'required_image_width' => 800,
            'required_image_height' => 500,
            'jpeg_quality' => 75,
            // The mobile app continues to send a signed JPEG. The plugin
            // performs the final safe rewrite and chooses this Media Library
            // output format, so older released apps remain compatible.
            'output_image_format' => 'jpeg',
            'maximum_upload_bytes' => 600 * 1024,
            'allowed_formats' => ['image/jpeg'],
            'caption_format' => 'Photo by {credit}',
            'default_copyright' => '',
            'metadata_policy' => 'minimal',
            'uploads_per_hour_device' => 120,
            'activity_retention_days' => 90,
            'upload_record_retention_days' => 90,
            'required_capability' => 'manage_options',
            'repeat_request_emails' => false,
        ];
    }

    public static function all(): array
    {
        $saved = get_option('capture_relay_settings', []);
        $saved = is_array($saved) ? $saved : [];
        // Before 1.4.1, one switch controlled both uploads and new requests.
        // Preserve that saved choice during upgrade instead of unexpectedly
        // enabling new connection requests on a paused website.
        if (!array_key_exists('new_requests_enabled', $saved)) {
            $saved['new_requests_enabled'] = array_key_exists('uploads_enabled', $saved)
                ? (bool) $saved['uploads_enabled']
                : true;
        }
        $settings = array_intersect_key(
            wp_parse_args($saved, self::defaults()),
            self::defaults()
        );
        $requiredSize = self::normalizeImageSize(
            (string) $settings['required_image_width'] . 'x' . (string) $settings['required_image_height']
        );
        if ($requiredSize === null) {
            $defaults = self::defaults();
            $settings['required_image_width'] = $defaults['required_image_width'];
            $settings['required_image_height'] = $defaults['required_image_height'];
        } else {
            [$settings['required_image_width'], $settings['required_image_height']] = array_map('intval', explode('x', $requiredSize));
        }
        return $settings;
    }

    public static function get(string $key, mixed $fallback = null): mixed
    {
        $settings = self::all();
        return $settings[$key] ?? $fallback;
    }

    public static function normalizeImageSize(string $size): ?string
    {
        $size = strtolower(trim($size));
        if (!preg_match('/^(\d{2,5})x(\d{2,5})$/', $size, $matches)) {
            return null;
        }
        $width = (int) $matches[1];
        $height = (int) $matches[2];
        if (
            $width <= $height ||
            $width < self::MIN_IMAGE_DIMENSION ||
            $height < self::MIN_IMAGE_DIMENSION ||
            $width > self::MAX_IMAGE_DIMENSION ||
            $height > self::MAX_IMAGE_DIMENSION
        ) {
            return null;
        }
        return $width . 'x' . $height;
    }

    public static function table(string $name): string
    {
        if (!in_array($name, self::TABLE_SUFFIXES, true)) {
            throw new \InvalidArgumentException('Unknown CaptureRelay database table.');
        }
        global $wpdb;
        return $wpdb->prefix . 'capture_relay_' . $name;
    }

    public static function identityHash(string $deviceUuid, string $platform = 'unknown'): string
    {
        return hash('sha256', self::NETWORK_ID . '|' . Security::siteIdentity() . '|legacy-uuid|' . sanitize_key($platform) . '|' . $deviceUuid);
    }
}
