<?php

namespace GriffinForms\Admin\Html\Pages\Lists;

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

    /** @var array<string, array<string, array>> list_type => [ column_key => config ] */
    private array $columns = [];

    private function __construct() {}

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

    /**
     * Register a column for a given list type.
     *
     * @param string $list_type  Singular item type: 'form', 'submission', 'file', etc.
     * @param string $key        Column slug matching the existing cell method naming convention.
     * @param array  $config {
     *   @type string $label           Translated display label. Empty string = icon-only column.
     *   @type bool   $sortable        Whether DB-level ORDER BY is supported. Default false.
     *   @type bool   $locked          Cannot be hidden or reordered (checkbox + primary). Default false.
     *   @type bool   $default_on      Included in the default column set. Default true.
     *   @type string $default_width   CSS width value e.g. '8%'. Empty = no override. Default ''.
     *   @type array  $variants        Optional. [ 'variant_key' => 'Variant Label' ]
     *   @type string $default_variant Key from $variants used when no preference saved. Default ''.
     * }
     */
    public function register(string $list_type, string $key, array $config): void
    {
        $defaults = [
            'label'           => $key,
            'sortable'        => false,
            'locked'          => false,
            'default_on'      => true,
            'default_width'   => '',
            'variants'        => [],
            'default_variant' => '',
        ];

        $this->columns[$list_type][$key] = array_merge($defaults, $config);
    }

    /**
     * Return all registered columns for a list type in registration order.
     *
     * @return array<string, array>  column_key => config
     */
    public function getColumns(string $list_type): array
    {
        return $this->columns[$list_type] ?? [];
    }

    /**
     * Return column keys that are on by default, in registration order.
     * 'checkbox' is always first.
     *
     * @return string[]
     */
    public function getDefaultColumns(string $list_type): array
    {
        $all  = $this->columns[$list_type] ?? [];
        $keys = array_keys(array_filter($all, static fn($c) => $c['default_on']));

        if (in_array('checkbox', $keys, true)) {
            $keys = array_merge(['checkbox'], array_diff($keys, ['checkbox']));
        }

        return array_values($keys);
    }

    /**
     * Return column keys that are locked (cannot be hidden or reordered).
     *
     * @return string[]
     */
    public function getLockedColumns(string $list_type): array
    {
        $all = $this->columns[$list_type] ?? [];
        return array_keys(array_filter($all, static fn($c) => $c['locked']));
    }

    /**
     * Check whether any columns have been registered for a list type.
     */
    public function hasColumns(string $list_type): bool
    {
        return !empty($this->columns[$list_type]);
    }
}
