<?php

namespace Salesloo;

use ArrayAccess;
use ArrayIterator;
use IteratorAggregate;
use Traversable;

if (!defined('ABSPATH')) {
    exit; // Exit if accessed directly.
}

/**
 * database collection
 */
class Collection implements ArrayAccess, IteratorAggregate
{
    public $count = 0;

    public $found = 0;

    public $results_per_page = 20;

    public $current_num_page = 1;

    public $max_num_pages = 0;

    public $pagination;

    /**
     * collection items
     */
    protected $items = [];

    /**
     * create new collection
     */
    public function __construct($items = [])
    {
        $this->items = $items;
    }

    /**
     * Get an iterator for the items.
     *
     * @return Traversable
     */
    public function getIterator(): Traversable
    {
        return new ArrayIterator($this->items);
    }

    /**
     * Count the number of items in the collection.
     *
     * @return int
     */
    public function count()
    {
        return count($this->items);
    }

    /**
     * Found the number of items in the query
     *
     * @return int
     */
    public function found()
    {
        return $this->found;
    }

    /**
     * result s per page
     */
    public function results_per_page()
    {
        return $this->results_per_page;
    }

    /**
     * show current num page
     */
    public function current_num_page()
    {
        return $this->current_num_page;
    }

    /**
     * show max num pages
     */
    public function max_num_pages()
    {
        return $this->max_num_pages;
    }

    public function pagination($url = false)
    {
        if ($url) {
            $this->pagination->next_url = esc_url($url) . $this->pagination->next_url;
            $this->pagination->prev_url = esc_url($url) . $this->pagination->prev_url;
        }

        return $this->pagination;
    }

    /**
     * Add an item to the collection.
     *
     * @param  mixed  $item
     * @return $this
     */
    public function add($item)
    {
        $this->items[] = $item;

        return $this;
    }

    /**
     * Determine if an item exists at an offset.
     *
     * @param  mixed  $key
     * @return bool
     */
    public function offsetExists($key): bool
    {
        return isset($this->items[$key]);
    }

    /**
     * Get an item at a given offset.
     *
     * @param  mixed  $key
     * @return mixed
     */
    public function offsetGet($key): mixed
    {
        return $this->items[$key];
    }

    /**
     * Set the item at a given offset.
     *
     * @param  mixed  $key
     * @param  mixed  $value
     * @return void
     */
    public function offsetSet($key, $value): void
    {
        if (is_null($key)) {
            $this->items[] = $value;
        } else {
            $this->items[$key] = $value;
        }
    }

    /**
     * Unset the item at a given offset.
     *
     * @param  string  $key
     * @return void
     */
    public function offsetUnset($key): void
    {
        unset($this->items[$key]);
    }
}
