<?php
/**
 * Persistence layer for integration registry rows (upsert and duplicate-key races).
 *
 * @package FleekDash\Integration
 */

namespace FleekDash\Integration;

defined('ABSPATH') || exit;

/**
 * @internal Used by {@see Registry}; not a public API surface.
 */
final class RegistryPersistence
{
    /**
     * @return array{success: bool, inserted_new_row: bool, error?: string|null}
     */
    public static function persistRegistryRow(string $table, array $validated_manifest, string $manifest_hash): array
    {
        global $wpdb;

        $payload = self::buildRegistryRowPayload($validated_manifest, $manifest_hash);
        $integration_id = $validated_manifest['integration_id'];

        if (self::integrationExists($integration_id)) {
            $updated = $wpdb->update(
                $table,
                $payload['data'],
                ['integration_id' => $integration_id],
                $payload['formats'],
                ['%s'],
            );
            $success = $updated !== false;
            $result = [
                'success' => $success,
                'inserted_new_row' => false,
                'error' => $success ? null : (string) $wpdb->last_error,
            ];
        } else {
            $inserted = $wpdb->insert($table, $payload['data'], $payload['formats']);

            if ($inserted !== false) {
                $result = ['success' => true, 'inserted_new_row' => true];
            } elseif (self::isMysqlDuplicateKeyError((string) $wpdb->last_error)) {
                $updated = $wpdb->update(
                    $table,
                    $payload['data'],
                    ['integration_id' => $integration_id],
                    $payload['formats'],
                    ['%s'],
                );
                $success = $updated !== false;
                $result = [
                    'success' => $success,
                    'inserted_new_row' => false,
                    'error' => $success ? null : (string) $wpdb->last_error,
                ];
            } else {
                $result = [
                    'success' => false,
                    'inserted_new_row' => false,
                    'error' => (string) $wpdb->last_error,
                ];
            }
        }

        return $result;
    }

    /**
     * @return array{data: array<string, mixed>, formats: string[]}
     */
    private static function buildRegistryRowPayload(array $validated_manifest, string $manifest_hash): array
    {
        $data = [
            'integration_id' => $validated_manifest['integration_id'],
            'name' => $validated_manifest['name'],
            'description' => $validated_manifest['description'] ?? '',
            'version' => $validated_manifest['version'],
            'author' => $validated_manifest['author'] ?? '',
            'author_uri' => $validated_manifest['author_uri'] ?? '',
            'integration_type' => $validated_manifest['integration_type'],
            'plugin_file' => $validated_manifest['plugin_file'],
            'icon' => $validated_manifest['icon'] ?? 'package',
            'category' => $validated_manifest['category'] ?? 'plugin',
            'source' => $validated_manifest['source'] ?? 'external',
            'source_label' => $validated_manifest['source_label'] ?? '',
            'manifest' => \wp_json_encode($validated_manifest),
            'manifest_hash' => $manifest_hash,
            'settings_schema' => \wp_json_encode($validated_manifest['settings_schema'] ?? null),
            'wp_menu_slug' => $validated_manifest['wp_menu_slug'] ?? null,
            'has_wp_menu' => !empty($validated_manifest['wp_menu_slug']) ? 1 : 0,
            'has_integration_routes' => !empty($validated_manifest['routes']) ? 1 : 0,
            'allowed_roles' => \wp_json_encode($validated_manifest['allowed_roles'] ?? null),
            'feature_key' => $validated_manifest['feature_key'] ?? null,
            'license_required' => !empty($validated_manifest['license_required']) ? 1 : 0,
            'required_tier' => $validated_manifest['required_tier'] ?? null,
            'is_active' => 1,
            'is_available' => 1,
        ];

        $formats = [
            '%s',
            '%s',
            '%s',
            '%s',
            '%s',
            '%s',
            '%s',
            '%s',
            '%s',
            '%s',
            '%s',
            '%s',
            '%s',
            '%s',
            '%s',
            '%s',
            '%d',
            '%d',
            '%s',
            '%s',
            '%d',
            '%s',
            '%d',
            '%d',
        ];

        return ['data' => $data, 'formats' => $formats];
    }

    private static function isMysqlDuplicateKeyError(string $message): bool
    {
        return $message !== '' && stripos($message, 'duplicate') !== false;
    }

    private static function integrationExists(string $integration_id): bool
    {
        global $wpdb;

        $table = $wpdb->prefix . 'fleekdash_integration_registry';

        $count = $wpdb->get_var(
            $wpdb->prepare(
                "SELECT COUNT(*) FROM `{$table}` WHERE `integration_id` = %s",
                $integration_id
            )
        );

        return $count > 0;
    }
}
