<?php
namespace Admidio\Roles\Entity;

use Admidio\Infrastructure\Database;
use Admidio\Infrastructure\Entity\Entity;
use Admidio\Infrastructure\Exception;
use Admidio\Changelog\Entity\LogChanges;
use Admidio\Roles\Entity\ListConfiguration;
use Admidio\ProfileFields\Entity\ProfileField;

/**
 ***********************************************************************************************
 * Class manages access to database table adm_user_data
 *
 * @copyright The Admidio Team
 * @see https://www.admidio.org/
 * @license https://www.gnu.org/licenses/gpl-2.0.html GNU General Public License v2.0 only
 * 
 * Log changes to the list columns configuration. The lsc_lst_id and the lsc_usf_id/lsc_special_field
 * are not modified, to they are treated (together with the lsc_id) to identify the record and log
 * creation/deletion. The other fields are logged as record modifications. 
 * 
 ***********************************************************************************************
 */

 class ListColumns extends Entity
{
    /**
     * Constructor that will create an object of a recordset of the table adm_list_columns.
     * @param Database $database Object of the class Database. This should be the default global object **$gDb**.
     * @param int $id The id of the profile field. If 0, an empty object of the table is created.
     * @throws Exception
     */
    public function __construct(Database $database, int $id = 0)
    {
        parent::__construct($database, TBL_LIST_COLUMNS, 'lsc', $id);
        $this->connectAdditionalTable(TBL_LISTS, 'lst_id', 'lsc_lst_id');
    }

    /**
     * Logs creation of the DB record
     * 
     * @return true Returns **true** if no error occurred
     */
    public function logCreation(): bool
    {
        if (!self::$loggingEnabled) return false;
        $table = $this->tableName;
        $table = str_replace(TABLE_PREFIX . '_', '', $table);
        
        // create list and fields objects
        $listID = (int)$this->getValue('lsc_lst_id');
        $list = new ListConfiguration($this->db, $listID);


        // Log object: Object 'lsc_lst_id' from table 'lists'
        //      LinkTo is: lsc_lst_id
        // Related to: Field (usf_id or special_field)
        // Field and value is lsc_*
        $logEntry = new LogChanges($this->db);
        $logEntry->setLogCreation($table, 
            $this->dbColumns[$this->keyColumnName],
            $list->getValue('lst_uuid'), $list->readableName()
        );

        $usfID = $this->getValue('lsc_usf_id');
        $specialField = $this->getValue('lsc_special_field');
        if (!empty($usfID)) {
            $usf = new ProfileField($this->db, $usfID);
            $logEntry->setLogRelated($usf->getValue('usf_uuid'), $usf->readableName());
        } elseif (!empty($specialField)) {
            $logEntry->setLogRelated('', $specialField);
        } else {
        }
        
        $this->adjustLogEntry($logEntry);
        return $logEntry->save();
    }

    /**
     * Logs deletion of the DB record
     * 
     * @return true Returns **true** if no error occurred
     */
    public function logDeletion(): bool
    {
        if (!self::$loggingEnabled) return false;
        $table = $this->tableName;
        $table = str_replace(TABLE_PREFIX . '_', '', $table);
        
        // create list and fields objects
        $listID = (int)$this->getValue('lsc_lst_id');
        $list = new ListConfiguration($this->db, $listID);


        // Log object: Object 'lsc_lst_id' from table 'lists'
        //      LinkTo is: lsc_lst_id
        // Related to: Field (usf_id or special_field)
        // Field and value is lsc_*
        $logEntry = new LogChanges($this->db);
        $logEntry->setLogDeletion($table, 
            $this->dbColumns[$this->keyColumnName],
            $list->getValue('lst_uuid'), $list->readableName()
        );

        $usfID = $this->getValue('lsc_usf_id');
        $specialField = $this->getValue('lsc_special_field');
        if (!empty($usfID)) {
            $usf = new ProfileField($this->db, $usfID);
            $logEntry->setLogRelated($usf->getValue('usf_uuid'), $usf->readableName());
        } elseif (!empty($specialField)) {
            $logEntry->setLogRelated('', $specialField);
        } else {
        }
        
        $this->adjustLogEntry($logEntry);
        return $logEntry->save();
    }

    /**
     * Logs all modifications of the DB record
     * @param array $logChanges Array of all changes, generated by the save method
     * @return true Returns **true** if no error occurred
     * @throws Exception
     */
    public function logModifications(array $logChanges): bool
    {
        if (!self::$loggingEnabled) return false;
        $retVal = true;
        $table = $this->tableName;
        $table = str_replace(TABLE_PREFIX . '_', '', $table);
        $id = $this->dbColumns[$this->keyColumnName];

        // create list and fields objects
        $listID = (int)$this->getValue('lsc_lst_id');
        $list = new ListConfiguration($this->db, $listID);
        $listUUID = $list->getValue('lst_uuid');
        $listName = $list->readableName();

        $logEntry = new LogChanges($this->db);

        // Log each individual record modification
        foreach ($logChanges as $field => $changes) {
            if ($this->isNewRecord()) {
                // Ignore certain fields that are already used to identify the column (List and Field information)
                if (in_array($field, ['lsc_lst_id', 'lsc_usf_id', 'lsc_special_field'] )) {
                    continue;
                }
            }

            // create log object, use List as the main object
            // Log object: Object 'lsc_lst_id' from table 'lists'
            //      LinkTo is: lsc_lst_id
            // Related to: Field (usf_id or special_field)
            // Field and value is lsc_*
            $logEntry->setLogModification($table, 
                $id, $listUUID, $listName, 
                $field, $this->getFieldTitle($field), 
                $changes['oldValue'], $changes['newValue']);


            // Link the user field or special field as related item:
            $usfID = $this->getValue('lsc_usf_id');
            $specialField = $this->getValue('lsc_special_field');
            if (!empty($usfID)) {
                $usf = new ProfileField($this->db, $usfID);
                $logEntry->setLogRelated($usf->getValue('usf_uuid'), $usf->readableName());
            } elseif (!empty($specialField)) {
                $logEntry->setLogRelated('', $specialField);
            } else {
            }
            

            $this->adjustLogEntry($logEntry);
            $retVal = $retVal && $logEntry->save();
            $logEntry->clear();
            $logEntry->saveChangesWithoutRights();
        }
        return $retVal;
    }

}
