// Copyright © Selmo Technology GmbH. All Rights Reserved

using Novus.Shared.Dto;

namespace SelmoStudio.Hmi.Server.Pagination
{
    public class PaginationCache<T> where T : IDto
    {
        private T[] _items;
        private int _currentIndex = 0;
        private int _pageSize = 3;

        public PaginationCache(List<T> items)
        {
            _items = items.ToArray();
        }

        public void SetPageSize(int pageSize)
        {
            _pageSize = pageSize > 0 ? pageSize : 1;
        }

        public bool HasMoreThanOnePage()
        {
            return _items.Length > _pageSize;
        }

        public void Reset()
        {
            _currentIndex = 0;
        }

        public void GoToPreviousPage()
        {
            if (_currentIndex == 0)
            {
                if (AllowOverflow)
                {
                    GoToPage(GetTotalPages());
                }
            }
            else
            {
                GoToPage(GetCurrentPage() - 1);
            }
        }

        public void GoToNextPage()
        {
            if (GetCurrentPage() == GetTotalPages())
            {
                if (AllowOverflow)
                {
                    GoToPage(1);
                }
            }
            else
            {
                GoToPage(GetCurrentPage() + 1);
            }
        }

        private void GoToPage(int pageNumber)
        {
            if (pageNumber < 1)
            {
                pageNumber = AllowOverflow ? GetTotalPages() : 1;
            }
            else if (pageNumber > GetTotalPages())
            {
                pageNumber = AllowOverflow ? 1 : GetTotalPages();
            }

            _currentIndex = (pageNumber - 1) * _pageSize;
        }

        private int GetTotalPages()
        {
            return (_items.Length + _pageSize - 1) / _pageSize;
        }

        private int GetCurrentPage()
        {
            return _currentIndex / _pageSize + 1;
        }

        public void SelectItem(T item)
        {
            var itemIndex = Array.IndexOf(_items, item);

            if (itemIndex >= 0 && itemIndex < _items.Length)
            {
                _currentIndex = itemIndex;
            }
        }

        public T[] GetCurrent()
        {
            int startIndex = (_currentIndex / _pageSize) * _pageSize;
            int endIndex = Math.Min(startIndex + _pageSize, _items.Length);

            return _items[startIndex..endIndex];
        }

        public bool AllowOverflow { get; set; } = true;
    }
}