<?php
/** 
 * @package     VikRestaurants
 * @subpackage  core
 * @author      E4J s.r.l.
 * @copyright   Copyright (C) 2023 E4J s.r.l. All Rights Reserved.
 * @license     http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
 * @link        https://vikwp.com
 */

// No direct access
defined('ABSPATH') or die('No script kiddies please!');

/**
 * VikRestaurants admin note model.
 *
 * @since 1.10
 */
class VikRestaurantsModelAdminnote extends JModelVRE
{
    /**
     * Basic item loading implementation.
     *
     * @param   mixed    $pk   An optional primary key value to load the row by, or an array of fields to match.
     *                         If not set the instance property value is used.
     * @param   boolean  $new  True to return an empty object if missing.
     *
     * @return  mixed    The record object on success, null otherwise.
     */
    public function getItem($pk, $new = false)
    {
        // load item through parent
        $item = parent::getItem($pk, $new);

        if ($item)
        {
            if ($item->created_by)
            {
                $author = new JUser($item->created_by);
                $item->author = new stdClass;
                $item->author->id = $author->id;
                $item->author->name = $author->name;
                $item->author->email = $author->email;
            }
            else
            {
                $item->author = null;
            }

            if ($item->modified_by)
            {
                $editor = new JUser($item->modified_by);
                $item->editor = new stdClass;
                $item->editor->id = $editor->id;
                $item->editor->name = $editor->name;
                $item->editor->email = $editor->email;
            }
            else
            {
                $item->editor = null;
            }
        }

        return $item;
    }

    /**
     * Basic save implementation.
     *
     * @param   mixed  $data  Either an array or an object of data to save.
     *
     * @return  mixed  The ID of the record on success, false otherwise.
     */
    public function save($data)
    {
        if (empty($data['id']))
        {
            if (empty($data['created']))
            {
                $data['created'] = JFactory::getDate('now')->toSql();
            }

            if (empty($data['created_by']))
            {
                $data['created_by'] = JFactory::getUser()->id;
            }
        }
        else
        {
            if (empty($data['modified']))
            {
                $data['modified'] = JFactory::getDate('now')->toSql();
            }

            if (empty($data['modified_by']))
            {
                $data['modified_by'] = JFactory::getUser()->id;
            }
        }

        // attempt to save the record
        return parent::save($data);
    }

    /**
     * Loads the notes that can be seen by the specified user.
     * 
     * @param   int    $idUser   The ID of the user that should access the notes.
     * @param   array  $options  A configuration array.
     * 
     * @return  object[]
     */
    public function loadNotes(int $idUser, array $options = [])
    {
        $db = JFactory::getDbo();

        $query = $db->getQuery(true);

        // load the admin notes
        $query->select('n.*');
        $query->from($db->qn('#__vikrestaurants_admin_notes', 'n'));
        
        // take only the public notes or the ones created by me
        $query->where([
            $db->qn('n.created_by') . ' = ' . $idUser,
            $db->qn('n.status') . ' = 1',
        ], 'OR');

        if (empty($options['archived']))
        {
            // hide the archived notes
            $query->andWhere($db->qn('status') . ' <> 2');
        }

        $db->setQuery($query);
        $notes = $db->loadObjectList();

        if (!$notes)
        {
            return [];
        }

        $userIds = $users = [];

        foreach ($notes as $note)
        {
            $userIds[] = $note->created_by;
            $userIds[] = $note->modified_by;
        }

        // take all the involved user IDs
        $userIds = array_values(array_unique(array_filter($userIds)));

        $query = $db->getQuery(true);

        // load the user details
        $query->select($db->qn(['u.name', 'u.email', 'u.id']));
        $query->from($db->qn('#__users', 'u'));

        // take only the involved users
        $query->where($db->qn('u.id') . ' IN (' . implode(',', array_map('intval', $userIds)) . ')');

        $db->setQuery($query);
        
        foreach ($db->loadObjectList() as $user)
        {
            // lookup the users by ID
            $users[$user->id] = $user;
        }

        foreach ($notes as $note)
        {
            // obtain author and editor information, if any
            $note->author = $users[$note->created_by] ?? null;
            $note->editor = $users[$note->modified_by] ?? null;
        }

        return $notes;
    }
}
