<?php

/**
 * @package         Smile Pack
 * @version         1.2.3 Pro
 * 
 * @author          Tassos Marinos <info@tassos.gr>
 * @link            http://www.tassos.gr
 * @copyright       Copyright © 2024 Tassos Marinos All Rights Reserved
 * @license         GNU GPLv3 <http://www.gnu.org/licenses/gpl.html> or later
*/

defined('_JEXEC') or die('Restricted access');

use Joomla\CMS\Factory;

abstract class SPMapMarkersItem
{
    protected $params;
    
    protected $db;

    protected $query;
    
    public function __construct($params)
    {
        $this->params = $params;
        
        $this->db = Factory::getDbo();
        
        $this->setup();
    }

    private function setup()
    {
        $this->query = $this->db->getQuery(true);
        $this->query->select('fv.item_id, fv.value')
            ->from($this->db->quoteName('#__fields_values', 'fv'))
            ->join('LEFT', $this->db->quoteName('#__fields', 'f') . ' ON f.id = fv.field_id')
            ->where($this->db->quoteName('f.type') . ' = ' . $this->db->q('acfmap'))
            ->where($this->db->quoteName('fv.field_id') . ' = ' . $this->db->q($this->getFieldID()))
            ->where($this->db->quoteName('f.context') . ' = ' . $this->db->q($this->context));

        $this->setJoin();
    }

    abstract protected function setJoin();
    abstract protected function getFieldID();
    abstract protected function getMarkers();

    protected function getDBResults()
    {
		$this->db->setQuery($this->query);

        $markers = $this->db->loadAssocList();

        $markers = $this->prepareMarkers($markers);
        
        return $markers;
    }

    private function prepareMarkers($markers = [])
    {
        $_markers = [];
        
        foreach ($markers as $key => &$value)
        {
            if (!isset($value['value']))
            {
                continue;
            }

            $item_id = isset($value['item_id']) ? (int) $value['item_id'] : null;
            $cat_id = isset($value['catid']) ? (int) $value['catid'] : null;
            $language = isset($value['language']) ? (string) $value['language'] : null;

            if (!$value = json_decode($value['value'], true))
            {
                continue;
            }

            foreach ($value as $marker)
            {
                // Ensure the marker doesn't exist in the list of already added markers
                // This way, we only render unique markers
                $markerExists = array_filter($_markers, function($item) use ($marker) {
                    return sprintf($item['latitude']) === sprintf($marker['latitude']) && sprintf($item['longitude']) === sprintf($marker['longitude']);
                });

                if ($markerExists)
                {
                    continue;
                }

                $marker['language'] = $language;
                $marker['item_id'] = $item_id;
                $marker['cat_id'] = $cat_id;
                $marker['context'] = $this->context;

                $_markers = array_merge($_markers, [$marker]);
            }
        }

        return $_markers;
    }

    /**
     * Return all categories child ids.
     * 
     * @param   array   $categories
     * @param   string  $context
     * 
     * @return  array
     */
    protected function getCategoriesChildIds($categories = [], $context = 'com_content')
    {
        $query = $this->db->getQuery(true)
            ->select('a.id')
            ->from($this->db->quoteName('#__categories', 'a'))
            ->where('a.extension = ' . $this->db->quote($context))
            ->where('a.published = 1');

        $children = [];

        while (!empty($categories))
        {
            $query
                ->clear('where')
                ->where($this->db->quoteName('a.parent_id') . ' IN (' . implode(',', $categories) . ')');
            
            $this->db->setQuery($query);

            $categories = $this->db->loadColumn();

            $children = array_merge($children, $categories);
        }

        return $children;
    }
}