<?php
declare(strict_types=1);

namespace ROITheme\Shared\Infrastructure\Persistence\WordPress;

use ROITheme\Shared\Domain\Contracts\PageVisibilityRepositoryInterface;

/**
 * Implementación WordPress del repositorio de visibilidad
 *
 * @package ROITheme\Shared\Infrastructure\Persistence\WordPress
 */
final class WordPressPageVisibilityRepository implements PageVisibilityRepositoryInterface
{
    private const GROUP_NAME = '_page_visibility';
    private const TABLE_SUFFIX = 'roi_theme_component_settings';

    private const VISIBILITY_FIELDS = [
        'show_on_home',
        'show_on_posts',
        'show_on_pages',
        'show_on_archives',
        'show_on_search',
    ];

    /**
     * Constructor con inyección de dependencias
     *
     * IMPORTANTE: Sigue el patrón existente de WordPressComponentSettingsRepository
     * donde $wpdb se inyecta por constructor, no se usa global.
     */
    public function __construct(
        private readonly \wpdb $wpdb
    ) {}

    public function getVisibilityConfig(string $componentName): array
    {
        $table = $this->wpdb->prefix . self::TABLE_SUFFIX;

        $results = $this->wpdb->get_results(
            $this->wpdb->prepare(
                "SELECT attribute_name, attribute_value
                 FROM {$table}
                 WHERE component_name = %s
                 AND group_name = %s",
                $componentName,
                self::GROUP_NAME
            ),
            ARRAY_A
        );

        if (empty($results)) {
            return [];
        }

        $config = [];
        foreach ($results as $row) {
            $config[$row['attribute_name']] = $row['attribute_value'] === '1';
        }

        return $config;
    }

    public function saveVisibilityConfig(string $componentName, array $config): void
    {
        $table = $this->wpdb->prefix . self::TABLE_SUFFIX;

        foreach ($config as $field => $enabled) {
            if (!in_array($field, self::VISIBILITY_FIELDS, true)) {
                continue;
            }

            $exists = $this->wpdb->get_var($this->wpdb->prepare(
                "SELECT COUNT(*) FROM {$table}
                 WHERE component_name = %s
                 AND group_name = %s
                 AND attribute_name = %s",
                $componentName,
                self::GROUP_NAME,
                $field
            ));

            $value = $enabled ? '1' : '0';

            if ($exists) {
                $this->wpdb->update(
                    $table,
                    [
                        'attribute_value' => $value,
                        'updated_at' => current_time('mysql'),
                    ],
                    [
                        'component_name' => $componentName,
                        'group_name' => self::GROUP_NAME,
                        'attribute_name' => $field,
                    ]
                );
            } else {
                $this->wpdb->insert($table, [
                    'component_name' => $componentName,
                    'group_name' => self::GROUP_NAME,
                    'attribute_name' => $field,
                    'attribute_value' => $value,
                    'is_editable' => 1,
                    'created_at' => current_time('mysql'),
                    'updated_at' => current_time('mysql'),
                ]);
            }
        }
    }

    public function hasVisibilityConfig(string $componentName): bool
    {
        $table = $this->wpdb->prefix . self::TABLE_SUFFIX;

        $count = $this->wpdb->get_var($this->wpdb->prepare(
            "SELECT COUNT(*) FROM {$table}
             WHERE component_name = %s
             AND group_name = %s",
            $componentName,
            self::GROUP_NAME
        ));

        return (int) $count > 0;
    }

    public function getAllComponentNames(): array
    {
        $table = $this->wpdb->prefix . self::TABLE_SUFFIX;

        $results = $this->wpdb->get_col(
            "SELECT DISTINCT component_name FROM {$table} ORDER BY component_name"
        );

        return $results ?: [];
    }

    public function createDefaultVisibility(string $componentName, array $defaults): void
    {
        if ($this->hasVisibilityConfig($componentName)) {
            return;
        }

        $this->saveVisibilityConfig($componentName, $defaults);
    }
}
