<?php
/**
 * SettingsService — centralised, cached settings reader.
 *
 * Usage:
 *   SettingsService::get( 'checkout', 'min_order_amount', '0' )
 *   SettingsService::section( 'appearance' )  // returns full key→value map
 *   SettingsService::bool( 'general', 'catalog_track_inventory', true )
 *   SettingsService::int( 'appearance', 'products_per_page', 12 )
 *
 * All reads are cached for the current PHP request. The cache can be
 * flushed with ::flush() (called automatically when SettingsController
 * saves a section).
 *
 * @package TitanCart\Services
 */

namespace TitanCart\Services;

defined( 'ABSPATH' ) || exit;

class SettingsService {

    /** @var array<string, array<string,string>> Cached section → [key → value] */
    private static array $cache = [];

    /**
     * Get a single setting value.
     *
     * @param  string $section  DB section name (e.g. 'checkout', 'general', 'appearance')
     * @param  string $key      Setting key
     * @param  string $default  Fallback when the row doesn't exist
     * @return string
     */
    public static function get( string $section, string $key, string $default = '' ): string {
        $map = self::section( $section );
        return array_key_exists( $key, $map ) ? $map[ $key ] : $default;
    }

    /**
     * Get a boolean setting (treats '1' as true, anything else as false).
     */
    public static function bool( string $section, string $key, bool $default = false ): bool {
        $map = self::section( $section );
        if ( ! array_key_exists( $key, $map ) ) {
            return $default;
        }
        return $map[ $key ] === '1';
    }

    /**
     * Get an integer setting.
     */
    public static function int( string $section, string $key, int $default = 0 ): int {
        $map = self::section( $section );
        if ( ! array_key_exists( $key, $map ) ) {
            return $default;
        }
        return (int) $map[ $key ];
    }

    /**
     * Get a float setting.
     */
    public static function float( string $section, string $key, float $default = 0.0 ): float {
        $map = self::section( $section );
        if ( ! array_key_exists( $key, $map ) ) {
            return $default;
        }
        return (float) $map[ $key ];
    }

    /**
     * Load an entire section as key→value associative array.
     * Result is cached for the request lifetime.
     *
     * @param  string $section
     * @return array<string,string>
     */
    public static function section( string $section ): array {
        if ( isset( self::$cache[ $section ] ) ) {
            return self::$cache[ $section ];
        }

        $db   = titancart_db();
        $rows = $db->getArray(
            "SELECT `key`, value FROM {$db->table('settings')} WHERE section = ?s",
            $section
        );

        $map = [];
        foreach ( $rows as $row ) {
            $map[ $row['key'] ] = $row['value'];
        }

        self::$cache[ $section ] = $map;
        return $map;
    }

    /**
     * Flush the entire cache or just one section.
     */
    public static function flush( ?string $section = null ): void {
        if ( $section !== null ) {
            unset( self::$cache[ $section ] );
        } else {
            self::$cache = [];
        }
    }
}
