<?php

namespace GriffinForms\Admin\Html\Pages\Lists;

class ColumnPreferences
{
    private static ?self $instance = null;

    private const OPTION_PREFIX = 'list_prefs_';
    private const OPTION_GROUP  = 'lists';

    private function __construct() {}

    public static function getInstance(): self
    {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Load saved preferences for a list type.
     * Returns null when no preferences have been saved yet.
     *
     * Preference array shape (all keys optional):
     * [
     *   'columns'   => string[],           // ordered enabled column keys (locked excluded)
     *   'variants'  => [ col_key => variant_key ],
     *   'widths'    => [ col_key => css_value ],
     *   'list_size' => int,
     * ]
     */
    public function load(string $list_type): ?array
    {
        $raw = \GriffinForms\Settings::getInstance()->getOption(
            self::OPTION_PREFIX . sanitize_key($list_type)
        );

        return is_array($raw) ? $raw : null;
    }

    /**
     * Save preferences for a list type.
     * updateOption() treats empty arrays as "delete" — passing an empty $prefs resets to defaults.
     */
    public function save(string $list_type, array $prefs): void
    {
        \GriffinForms\Settings::getInstance()->updateOption(
            self::OPTION_PREFIX . sanitize_key($list_type),
            $this->sanitize($prefs),
            self::OPTION_GROUP
        );
    }

    /**
     * Delete saved preferences for a list type (resets to registry defaults).
     */
    public function reset(string $list_type): void
    {
        \GriffinForms\Settings::getInstance()->deleteOption(
            self::OPTION_PREFIX . sanitize_key($list_type)
        );
    }

    private function sanitize(array $prefs): array
    {
        $clean = [];

        if (isset($prefs['columns']) && is_array($prefs['columns'])) {
            $clean['columns'] = array_values(array_map('sanitize_key', $prefs['columns']));
        }

        if (isset($prefs['variants']) && is_array($prefs['variants'])) {
            $clean['variants'] = [];
            foreach ($prefs['variants'] as $col => $variant) {
                $col     = sanitize_key((string) $col);
                $variant = sanitize_key((string) $variant);
                if ($col !== '' && $variant !== '') {
                    $clean['variants'][$col] = $variant;
                }
            }
        }

        if (isset($prefs['widths']) && is_array($prefs['widths'])) {
            $clean['widths'] = [];
            foreach ($prefs['widths'] as $col => $width) {
                $col   = sanitize_key((string) $col);
                $width = preg_replace('/[^0-9a-z.%]/', '', strtolower((string) $width));
                if ($col !== '' && $width !== '') {
                    $clean['widths'][$col] = $width;
                }
            }
        }

        if (isset($prefs['list_size'])) {
            $size    = absint($prefs['list_size']);
            $allowed = [10, 25, 50, 100];
            $clean['list_size'] = in_array($size, $allowed, true) ? $size : 10;
        }

        return $clean;
    }
}
