<?php

class SearchHistory extends Base {

    // Variables

    private $current_user_serial = 0;
    private $current_user_id = "";
    private $current_user_name = "";
    private $current_user_email = "";

    // =================
    // Class Constructor
    // =================

    public function __construct() {

        set_error_handler(array($this, "displayError"));

        date_default_timezone_set(self::TIMEZONE);

        $this->current_user_serial = $_SESSION[self::USER_SERIAL] ?? 0;
        $this->current_user_id = $_SESSION[self::USER_ID] ?? "";
        $this->current_user_name = $_SESSION[self::USER_NAME] ?? "";
        $this->current_user_email = $_SESSION[self::USER_EMAIL] ?? "";
    }

    // ============================
    // Save Users Search Parameters
    // ============================

    public function saveUserSearchParameters($searchpayload) {

        $user = $this->current_user_serial;
        $subscription_serial = $searchpayload['subscription_serial'];

        switch ($subscription_serial) {

            case 1:
            case 2:
            case 3:
            case 4:

                $searchcriteria = json_encode(array_filter($searchpayload, fn($key) => str_starts_with($key, 'permitfact_'), ARRAY_FILTER_USE_KEY));

                break;

            case 5:

                $searchcriteria = json_encode(array_filter($searchpayload, fn($key) => str_starts_with($key, 'pzfact_'), ARRAY_FILTER_USE_KEY));

                break;

            case 7:
            case 10:

                $searchcriteria = json_encode(array_filter($searchpayload, fn($key) => str_starts_with($key, 'businessfact_'), ARRAY_FILTER_USE_KEY));

                break;

            default :
                return;
        }

        $SQL = "insert into searchhistories
          
                         (  searchhistory_user,
                            searchhistory_subscription,
                            searchhistory_parameters,
                            searchhistory_creator,
                            searchhistory_created )
                               
                  values ( :searchhistory_user,
                           :searchhistory_subscription,
                           :searchhistory_parameters,
                           :searchhistory_creator,
                           :searchhistory_created )";

        $connection = $this->connect();
        $statement = $connection->prepare($SQL);

        $statement->bindValue(":searchhistory_user", $user);
        $statement->bindValue(":searchhistory_subscription", $subscription_serial);
        $statement->bindValue(":searchhistory_parameters", $searchcriteria);
        $statement->bindValue(":searchhistory_creator", $this->current_user_name);
        $statement->bindValue(":searchhistory_created", $this->getTimestamp());

        $statement->execute();
    }

    // ============================
    // Save Users Search Parameters
    // ============================

    public function updateUserSearchParameters($searchpayload) {

        $user = $this->current_user_serial;
        $subscription_serial = $searchpayload['subscription_serial'];

        switch ($subscription_serial) {

            case 1:
            case 2:
            case 3:
            case 4:

                $searchcriteria = json_encode(array_filter($searchpayload, fn($key) => str_starts_with($key, 'permitfact_'), ARRAY_FILTER_USE_KEY));

                break;

            case 5:

                $searchcriteria = json_encode(array_filter($searchpayload, fn($key) => str_starts_with($key, 'pzfact_'), ARRAY_FILTER_USE_KEY));

                break;

            case 7:
            case 10:

                $searchcriteria = json_encode(array_filter($searchpayload, fn($key) => str_starts_with($key, 'businessfact_'), ARRAY_FILTER_USE_KEY));

                break;

            default :
                return;
        }

        $SQL = "update searchhistories
                   set searchhistory_parameters   = :searchhistory_parameters,
                       searchhistory_changer      = :searchhistory_changer,
                       searchhistory_changed      = :searchhistory_changed
                 where searchhistory_user         = :searchhistory_user
                   and searchhistory_subscription = :searchhistory_subscription";

        $statement = $this->connect()->prepare($SQL);

        $statement->bindValue(":searchhistory_parameters", $searchcriteria);
        $statement->bindValue(":searchhistory_changer", $this->current_user_name);
        $statement->bindValue(":searchhistory_changed", $this->getTimestamp());
        $statement->bindValue(":searchhistory_user", $user);
        $statement->bindValue(":searchhistory_subscription", $subscription_serial);

        $statement->execute();
    }

    // ============================
    // Gets Users Search Parameters
    // ============================

    public function getUsersPreviousSearchParameters($user, $subscription) {

        $SQL = "select view_searchhistories.* 
                  from view_searchhistories
                 where view_searchhistories.searchhistory_user         = {$user}
                   and view_searchhistories.searchhistory_subscription = {$subscription}";

        $recordset = $this->getTable("searchhistory", $SQL);

        return $this->materializeSearchHistoryParameters($recordset);
    }

    // ============================
    // Gets Users Search Parameters
    // ============================

    public function materializeSearchHistoryParameters(SimpleXMLElement $SXE): SimpleXMLElement {

        if (!isset($SXE->record)) {
            return $SXE;
        }

        // Keys that should ALWAYS materialize as <key><id>..</id></key>
        // even if there is only one value.
        $multiSelectKeys = [
            'permitfact_project_city', 'permitfact_county', 'permitfact_project_type', 'permitfact_work_type', 'permitfact_building_type',
            'businessfact_city', 'businessfact_city', 'businessfact_county', 'businessfact_action', 'businessfact_business_class',
            'pzfact_project_city', 'pzfact_project_city', 'pzfact_project_city', 'pzfact_project_city'
        ];

        foreach ($SXE->record as $record) {

            if (!isset($record->searchhistory_parameters)) {
                continue;
            }

            $json = trim((string) $record->searchhistory_parameters);
            if ($json === '') {
                continue;
            }

            $data = json_decode($json, true);
            if (!is_array($data)) {
                continue;
            }

            // Clear existing text content
            $record->searchhistory_parameters[0] = null;

            foreach ($data as $key => $value) {

                $nodeName = preg_replace('/[^A-Za-z0-9_\-:.]/', '_', (string) $key);

                $isMulti = in_array($key, $multiSelectKeys, true);

                // If this is a multi-select key:
                // - Accept arrays (preferred)
                // - Accept CSV strings (legacy)
                // - Accept single scalar and wrap it in <id>
                if ($isMulti) {
                    $parent = $record->searchhistory_parameters->addChild($nodeName);

                    if (is_array($value)) {
                        $parts = $value;
                    } else {
                        $valueStr = trim((string) $value);

                        // empty -> create empty parent node and move on
                        if ($valueStr === '') {
                            continue;
                        }

                        // CSV or single
                        $parts = (strpos($valueStr, ',') !== false) ? explode(',', $valueStr) : [$valueStr];
                    }

                    $parts = array_values(array_filter(array_map('trim', $parts), fn($v) => $v !== ''));

                    foreach ($parts as $p) {
                        $parent->addChild('id', htmlspecialchars($p, ENT_XML1 | ENT_QUOTES, 'UTF-8'));
                    }

                    continue;
                }

                // Non-multi-select keys (same as your current behavior)
                if (is_string($value) && strpos($value, ',') !== false) {

                    $parent = $record->searchhistory_parameters->addChild($nodeName);

                    $parts = array_values(array_filter(array_map('trim', explode(',', $value)), fn($v) => $v !== ''));
                    foreach ($parts as $p) {
                        $parent->addChild('id', htmlspecialchars($p, ENT_XML1 | ENT_QUOTES, 'UTF-8'));
                    }
                } else {
                    $record->searchhistory_parameters->addChild(
                            $nodeName,
                            htmlspecialchars((string) $value, ENT_XML1 | ENT_QUOTES, 'UTF-8')
                    );
                }
            }
        }

        return $SXE;
    }
}

?>
