<?php

class FilterPreset extends Model
{
  private bool $_isChanged = false;
  private bool $_autoSave = true;
  private string $_lastError = '';

  public function __construct($id)
  {
    parent::__construct($id);

    // Critical properties
    $this->_isChanged = false;
  }


  /**
   * Filter Preset class destructor
   ** Saves changes to the user record if there are any (and autoSave is not disabled)
   */
  public function __destruct()
  {
    if ($this->_autoSave && $this->_isChanged) $this->save();
  }


  /**
   * Makes it possible to set $object->field
   *
   * @param string $key
   * @param mixed
   */
  public function __set($key, $value)
  {
    $this->_isChanged = true;
    parent::__set($key, $value);
  }


  /**
   * Returns all Filter Preset Preferences
   * @param boolean $asJSON - Return results as a JSON string
   * @return array All currently saves session settings
   */
  public function getAll($asJSON = false)
  {
    return $asJSON ? json_encode(($this->_values ?? [])) : ($this->_values ?? []);
  }


  /**
   * Set AutoSave
   ** Allows (or prevents) changes to the filter preset record from being saved to the database at
   ** completion of script execution.  Enabled by default.
   *
   * @param string $autoSave (True if changes are to be saved automatically, otherwise false)
   */
  public function setAutoSave($autoSave)
  {
    $this->_autoSave = $autoSave;
  }


  /**
   * Save the filter preset record if there are any changes pending
   *
   * @return boolean (True if save was successful, otherwise false)
   */
  public function save()
  {
    // Don't save unless something has been changed
    if ($this->_isChanged === false)
    {
      $this->_lastError = 'No changes have been made to save.';
      return false;
    }

    // Make sure all critical properties are completed
    if (is_null($this->userId) || is_null($this->presetName) || strlen($this->presetName) < 3)
    {
      $this->_lastError = 'Cannot save, one or more filter preset settings are missing.';
      return false;
    }

    // Properties to Fields
    $fieldMap = [
      'userId'                          => 'user_id',
      'presetName'                      => 'preset_name',
      'filterStationIds'                => 'filter_station_ids',
      'filterVisibleSymbols'            => 'filter_visible_symbols',
      'filterSymbolInvert'              => 'filter_symbol_invert',
      'filterMoving'                    => 'filter_moving',
      'filterMovingSpeed'               => 'filter_moving_speed',
      'filterElevationAbove'            => 'filter_elevation_above',
      'filterElevationBelow'            => 'filter_elevation_below',
      'filterWeather'                   => 'filter_weather',
      'filterTelemetry'                 => 'filter_telemetry'
    ];

    // Get the site backend database connection
    $pdo = PDOMysqlConnection::getInstance();

    $sqlParts = [];
    $parameters = [];

    // Inserting or saving?
    if ($this->isExistingObject())
    {
      $sql = 'UPDATE filter_presets SET';

      // Add all fields
      foreach ($fieldMap AS $property => $column)
      {
        if (isset($this->$property))
        {
          $sqlParts[] = "$column = ? ";
          array_push($parameters, $this->$property);
        }
      }

      array_push($parameters, $this->_id);
      $sql .= implode(',', $sqlParts);
      $sql .= 'WHERE id = ? LIMIT 1';

      $stmt = $pdo->prepareAndExec($sql, $parameters);
      if ($stmt)
      {
        $this->_isChanged = false;
        return true;
      }
      $this->_lastError = 'An error occurred saving the filter preset.';
    }
    else
    {
      $columns = [];

      // Add only the non-null preferences
      foreach ($fieldMap AS $property => $column)
      {
        if (isset($this->$property))
        {
          $columns[] = $column;
          $sqlParts[] = "?";
          array_push($parameters, $this->$property);
        }
      }

      $placeholders = implode(',', $sqlParts);
      $columns = implode(',', $columns);

      $sql = "INSERT INTO filter_presets
                ($columns)
              VALUES
                ($placeholders)";

      $stmt = $pdo->prepareAndExec($sql, $parameters);
      $id = $pdo->lastInsertId();
      if ($id)
      {
        $this->_id = $id;
        $this->_isChanged = false;
        return true;
      }

      $this->_lastError = 'An error occurred creating the filter preset.';
    }

    return false;
  }


  /**
   * Delete the filter preset record
   *
   * @return boolean (True if delete was successful, otherwise false)
   */
  public function delete()
  {
    if ($this->isExistingObject())
    {
      // Get the site backend database connection
      $pdo = PDOMysqlConnection::getInstance();

      $sql = 'DELETE FROM filter_presets WHERE id = ? LIMIT 1';
      $stmt = $pdo->prepareAndExec($sql, [$this->_id]);
      if ($stmt)
      {
        return true;
      }
      $this->_lastError = 'An error occurred deleting the filter preset.';
    }
  }


  /**
   * Returns the last error message set during a filter preset action then
   * sets _lastError to an empty string.
   *
   * @return string (Text of the last recorded error)
   */
  public function getLastError()
  {
    $last_error = $this->_lastError;
    $this->_lastError = '';
    return $last_error;
  }
}
