<?php
/**
 * Theme style reads from Bricks options.
 *
 * @package LolaCoreForBricks
 */

declare(strict_types=1);

namespace LolaCoreForBricks\Gateways;

use LolaCoreForBricks\Support\BricksMetaKeys;
use LolaCoreForBricks\Support\PaginatedList;

/**
 * Reads bricks_theme_styles with conditions and scope.
 */
class ThemeStyleGateway
{
    /**
     * @param array<string, mixed> $params
     * @return array<string, mixed>
     */
    public function getThemeStyles(array $params): array
    {
        $limit  = (int) ($params['limit'] ?? 50);
        $offset = (int) ($params['offset'] ?? 0);

        $styles = $this->normalizeStyles(get_option(BricksMetaKeys::OPTION_THEME_STYLES, []));
        $page   = PaginatedList::slice($styles, $limit, $offset);

        return [
            'theme_styles' => $page['items'],
            'total'        => $page['total'],
            'truncated'    => $page['truncated'],
            'limit'        => $page['limit'],
            'offset'       => $page['offset'],
        ];
    }

    /**
     * @param mixed $raw
     * @return array<int, array<string, mixed>>
     */
    private function normalizeStyles(mixed $raw): array
    {
        if (!is_array($raw)) {
            return [];
        }

        $items = [];
        foreach ($raw as $key => $style) {
            if (!is_array($style)) {
                continue;
            }

            $styleId = (string) ($style['id'] ?? (is_string($key) ? $key : ''));
            if ($styleId === '') {
                continue;
            }

            $settings   = is_array($style['settings'] ?? null) ? $style['settings'] : [];
            $conditions = is_array($style['conditions'] ?? null)
                ? $style['conditions']
                : (is_array($settings['conditions']['conditions'] ?? null) ? $settings['conditions']['conditions'] : []);

            $items[] = [
                'id'                 => $styleId,
                'name'               => (string) ($style['label'] ?? $style['name'] ?? $styleId),
                'settings_count'     => count($settings),
                'conditions'         => $conditions,
                'conditions_summary' => $this->summarizeConditions($conditions),
                'affects'            => $this->affectsFromConditions($conditions),
            ];
        }

        return $items;
    }

    /**
     * @param array<int, mixed> $conditions
     * @return string
     */
    private function summarizeConditions(array $conditions): string
    {
        if ($conditions === []) {
            return 'Applies site-wide (no conditions set).';
        }

        $parts = [];
        foreach ($conditions as $condition) {
            if (!is_array($condition)) {
                continue;
            }

            $main = (string) ($condition['main'] ?? 'unknown');
            $parts[] = match ($main) {
                'any'      => 'Entire website',
                'postType' => 'Post types: ' . implode(', ', (array) ($condition['postType'] ?? [])),
                'ids'      => 'Specific pages/posts',
                'terms'    => 'Taxonomy terms',
                default    => $main,
            };
        }

        return $parts === [] ? 'Conditional scope' : implode('; ', $parts);
    }

    /**
     * @param array<int, mixed> $conditions
     * @return array<string, mixed>
     */
    private function affectsFromConditions(array $conditions): array
    {
        if ($conditions === []) {
            return ['scope' => 'site_wide'];
        }

        $postTypes = [];
        foreach ($conditions as $condition) {
            if (!is_array($condition)) {
                continue;
            }

            if (($condition['main'] ?? '') === 'postType' && is_array($condition['postType'] ?? null)) {
                $postTypes = array_merge($postTypes, $condition['postType']);
            }
        }

        if ($postTypes !== []) {
            return ['scope' => 'post_types', 'post_types' => array_values(array_unique(array_map('strval', $postTypes)))];
        }

        return ['scope' => 'conditional'];
    }
}
