<?php

namespace classes;

/**
 * Ensures additive schema for department lifecycle metadata.
 */
class departments_schema_bootstrap
{
    private static bool $initialized = false;
    private const ARCHIVED_INDEX = 'idx_departments_archived';

    public static function ensureTables(): void
    {
        if (self::$initialized) {
            return;
        }

        global $db;

        if (!isset($db) || !is_object($db) || !method_exists($db, 'query')) {
            return;
        }

        if (!self::tableExists($db, 'departments')) {
            return;
        }

        if (!self::columnExists($db, 'departments', 'archived')) {
            $db->query(
                "ALTER TABLE departments
                    ADD COLUMN archived TINYINT(1) NOT NULL DEFAULT 0
                    AFTER visible"
            );
        }

        if (!self::columnExists($db, 'departments', 'custom_pricing_only')) {
            $db->query(
                "ALTER TABLE departments
                    ADD COLUMN custom_pricing_only TINYINT(1) NOT NULL DEFAULT 0
                    AFTER archived"
            );
        }

        if (!self::indexExists($db, 'departments', self::ARCHIVED_INDEX)) {
            $db->query(
                "ALTER TABLE departments
                    ADD INDEX " . self::ARCHIVED_INDEX . " (archived)"
            );
        }

        self::$initialized = true;
    }

    private static function tableExists(object $db, string $table): bool
    {
        $table = self::escapeIdentifier($table);
        $result = $db->query("SHOW TABLES LIKE '{$table}'");

        if ($result === false || !is_object($result) || !property_exists($result, 'num_rows')) {
            return false;
        }

        return (int)$result->num_rows > 0;
    }

    private static function columnExists(object $db, string $table, string $column): bool
    {
        $table = self::escapeIdentifier($table);
        $column = self::escapeIdentifier($column);
        $result = $db->query("SHOW COLUMNS FROM `{$table}` LIKE '{$column}'");

        if ($result === false || !is_object($result) || !property_exists($result, 'num_rows')) {
            return false;
        }

        return (int)$result->num_rows > 0;
    }

    private static function indexExists(object $db, string $table, string $index): bool
    {
        $table = self::escapeIdentifier($table);
        $index = self::escapeIdentifier($index);
        $result = $db->query("SHOW INDEX FROM `{$table}` WHERE Key_name = '{$index}'");

        if ($result === false || !is_object($result) || !property_exists($result, 'num_rows')) {
            return false;
        }

        return (int)$result->num_rows > 0;
    }

    private static function escapeIdentifier(string $value): string
    {
        return str_replace(['\\', "'", '`'], ['\\\\', "\\'", ''], $value);
    }
}
