<?php
/**
 * Created by Glee Ltd.
 * User: Hieu
 * Date: 05-Mar-18
 * Time: 4:30 PM
 * Description:
 */

namespace Hura8\System;


final class Paging
{

    protected static $cache = [];

    //get last page
    public static function getLastPage($totalResults, $numPerPage) {
        //$current_url = curPageURL();
        $maxPage = ceil($totalResults / $numPerPage);

        return Url::buildUrl($_SERVER['REQUEST_URI'], ["page" => $maxPage]);
    }

    public static function pageSizeSelectBox($default_size = 15) {
        $html = ["<select class='hura-change-page-size' onchange='window.location=this.value'>"];

        $final_list = static::getPageSizes();
        foreach ($final_list as $item) {
            $is_selected = ($default_size == $item['size']) ? "selected" : "";
            $html[] = "<option value='". $item['url'] ."' ".$is_selected.">". $item['name'] ."</option>";
        }

        $html[] = "</select>";

        return join("", $html);
    }

    //allow to select pageSize
    public static function getPageSizes() {
        $sizes = [15, 30, 50];
        $final_list = [];
        foreach ($sizes as $size) {
            $final_list[] = [
                "size"  => $size,
                "name"  => $size . "/ trang",
                "url"   => Url::buildUrl($_SERVER['REQUEST_URI'], ["page" => '', "pageSize" => $size])
            ];
        }

        return $final_list;
    }

    //Function nhay trang paging
    public static function pagingAjax($totalResults,$numPerRow,$currentURL,$maxPageDisplay,$holder_id){
        $currentPage = isset($_GET["page"]) ? (int) $_GET["page"] : 1;
        $currentURL =  str_replace(array("?page=".$currentPage, "&page=".$currentPage),"",$currentURL);
        if(strpos($currentURL, "?") !== false) $currentURL .= "&";
        else $currentURL .= "?";

        $maxPage = ceil($totalResults/$numPerRow);
        //max page to see : 20
        $maxPage = ($maxPage > 50) ? 50 : $maxPage;

        if($maxPage==1) return "";
        $farLeft ="<td class=pagingFarSide align=center>...</td>";
        $farRight ="<td class=pagingFarSide align=center>...</td>";
        $link ="<table cellpadding=0 cellspacing=0><tr>";
        //$maxPageDisplay la so page se hien ra, thuong lay 7
        if($currentPage > 1) $link .= "<td class=\"pagingIntact\"><a href=\"javascript:;\" onclick=\"loadAjaxContent('".$holder_id."', '".$currentURL."&page=".($currentPage-1)."')\">&lt;&lt;</a></td>";
        else $link .= "<td class=\"pagingIntact\"><a>Xem</a></td>";
        $link .= "<td class=pagingSpace></td>";

        if($maxPage<=$maxPageDisplay){

            for($i=1;$i<=$maxPage;$i++){
                if($i==$currentPage) $link .= "<td class=\"pagingViewed\">$i</td><td class=pagingSpace></td>";
                else $link .= "<td class=\"pagingIntact\"><a href=\"javascript:;\" onclick=\"loadAjaxContent('".$holder_id."', '".$currentURL."&page=$i')\">$i</a></td><td class=pagingSpace></td>";
            }

            if($currentPage < $maxPage) $link .= "<td class=\"pagingIntact\"><a href=\"javascript:;\" onclick=\"loadAjaxContent('".$holder_id."', '".$currentURL."&page=".($currentPage+1)."')\">&gt;&gt;</a></td>";

        }else{
            //Vay la tong so trang nhieu hon so trang muon hien ra
            if($currentPage<=(ceil($maxPageDisplay/2))){

                //Neu trang dang xem dang o muc 1,2,3,4
                for($i=1;$i<=$maxPageDisplay;$i++){
                    if($i==$currentPage) $link .= "<td class=\"pagingViewed\">$i</td><td class=pagingSpace></td>";
                    else $link .= "<td class=\"pagingIntact\"><a href=\"javascript:;\" onclick=\"loadAjaxContent('".$holder_id."', '".$currentURL."&page=$i')\">$i</a></td><td class=pagingSpace></td>";
                }
                $link .=$farRight;
                //$link .= "<td class=\"pagingIntact\"><a href=\"".$currentURL."&page=".$maxPage."\">".$maxPage."</a></td><td class=pagingSpace></td>";//the last page
                $link .= "<td class=\"pagingIntact\"><a href=\"javascript:;\" onclick=\"loadAjaxContent('".$holder_id."', '".$currentURL."&page=".($currentPage+1)."')\">&gt;&gt;</a></td>";

            }elseif($currentPage<=($maxPage-round($maxPageDisplay/2,0))){
                //Neu trang dang xem o muc cao hon 4
                $link .= "<td class=\"pagingIntact\"><a href=\"javascript:;\" onclick=\"loadAjaxContent('".$holder_id."', '".$currentURL."&page=1')\">1</a></td><td class=pagingSpace></td>";//the 1st page
                $link .=$farLeft;
                for($i=($currentPage-round($maxPageDisplay/2,0)+1);$i<($currentPage+round($maxPageDisplay/2,0));$i++){
                    if($i==$currentPage) $link .= "<td class=\"pagingViewed\">$i</td><td class=pagingSpace></td>";
                    else $link .= "<td class=\"pagingIntact\"><a href=\"javascript:;\" onclick=\"loadAjaxContent('".$holder_id."', '".$currentURL."&page=$i')\">$i</a></td><td class=pagingSpace></td>";
                }
                $link .=$farRight;
                //$link .= "<td class=\"pagingIntact\"><a href=\"".$currentURL."&page=".$maxPage."\">".$maxPage."</a></td><td class=pagingSpace></td>";//the last page
                $link .= "<td class=\"pagingIntact\"><a href=\"javascript:;\" onclick=\"loadAjaxContent('".$holder_id."', '".$currentURL."&page=".($currentPage+1)."')\">&gt;&gt;</a></td>";
            }else{
                //May trang cuoi cung
                $link .= "<td class=\"pagingIntact\"><a href=\"javascript:;\" onclick=\"loadAjaxContent('".$holder_id."', '".$currentURL."&page=1')\">1</a></td><td class=pagingSpace></td>";//the 1st page
                $link .=$farLeft;
                for($i=($maxPage-$maxPageDisplay+1);$i<=$maxPage;$i++){
                    if($i==$currentPage) $link .= "<td class=\"pagingViewed\">$i</td><td class=pagingSpace></td>";
                    else $link .= "<td class=\"pagingIntact\"><a href=\"javascript:;\" onclick=\"loadAjaxContent('".$holder_id."', '".$currentURL."&page=$i')\">$i</a></td><td class=pagingSpace></td>";
                }
            }
        }
        $link .= "</tr></table>";
        //Lua chon hien thi, phai it nhat tu 2 trang tro len moi hien ra

        if($maxPage>1){
            return $link;
        }

        return false;
    }

    // 04-Sept-2020
    public static function paging_template($totalResults, $numPerRow, $currentURL = '', $maxPageDisplay = 7){
        // parameter variables
        if(!$currentURL) $currentURL = $_SERVER['REQUEST_URI'];
        $url_parts = self::destructUrlWithCustomPageParam($currentURL);
        /*[
            'path' => $url_path,
            'query' => $query_params,
            'page' => $current_page,
        ];*/

        $query_without_page = $url_parts['query'];
        $current_page       = (isset($url_parts['page']) && $url_parts['page']) ? intval($url_parts['page']) : 1;
        $total_pages = ceil($totalResults / $numPerRow);
        $page_space = ceil(($maxPageDisplay - 1) / 2);
        if($current_page > $total_pages) $current_page = $total_pages;

        /*
         * $current_page is expected to be always in the middle:
         * 3 =  $page_space = ( $maxPageDisplay = 7-1/2)
         * if current_page = 4 -> expect start = 4-3 = 1, expect end = 4+3 = 7
         * if current_page = 2 -> expect start = 2-3 = -1, expect end = 2+3 = 5. Since -1 is not valid, we need to add 2 to make it at least 1, so the end need to add 2 as well, so the result is: start = 1, end = 7
         *  if current_page = 6 -> expect start = 6-3 = 3, expect end = 6+3 = 9. if max page =8, the end need to offset 9-8 = 1, so the start also need to offset 1, the result: start=3-1 = 2, end=9-1=8
         * */

        // expect result
        $start_index = $current_page - $page_space;
        $end_index   = $current_page + $page_space;

        //calculate offset
        if($start_index < 1) {
            $offset = 1 - $start_index;
            $start_index = 1;
            $end_index += $offset;
            if($end_index > $total_pages) $end_index = $total_pages;
        }else if($end_index > $total_pages) {
            $offset = $end_index - $total_pages;
            $end_index = $total_pages;
            $start_index -= $offset;
            if($start_index < 1) $start_index = 1;
        }

        $page_collection = [];
        $build_table = [];

        // add prev
        if($start_index > 1) {
            $query_without_page['page'] = $current_page-1;
            $url        = self::buildUrlWithCustomPageParam($url_parts['path'], $query_without_page);

            $build_table[] = "<td class=\"pagingIntact\"><a title='Back' href=\"".$url."\"> &lt;&lt; </a></td><td class=pagingSpace></td>";
            $page_collection[] = [
                "name" => "prev",
                "url"  => $url,
                "is_active" => 0,
            ];
        }

        for($i = $start_index; $i <= $end_index ; $i++) {
            $query_without_page['page'] = $i;
            $url        = self::buildUrlWithCustomPageParam($url_parts['path'], $query_without_page);
            $is_active  =  ($i == $current_page) ? 1 : 0;

            $page_collection[] = [
                "name" => $i,
                "url"  => $url,
                "is_active" => $is_active,
            ];

            if($is_active) {
                $build_table[] = "<td class=\"pagingViewed\">".$i."</td><td class=pagingSpace></td>";
            }else{
                $build_table[] = "<td class=\"pagingIntact\"><a href=\"".$url."\">".$i."</a></td><td class=pagingSpace></td>";
            }
        }

        // add forward
        if($end_index < $total_pages) {
            $query_without_page['page'] = $current_page + 1;
            $url        = self::buildUrlWithCustomPageParam($url_parts['path'], $query_without_page);
            $build_table[] = "<td class=\"pagingIntact\"><a title='Next' href=\"".$url."\"> &gt;&gt; </a></td><td class=pagingSpace></td>";
            $page_collection[] = [
                "name" => "next",
                "url"  => $url,
                "is_active" => 0,
            ];
        }

        //-------------------
        if($total_pages > 1 ){
            $tb_page = join("", [
                '<table cellpadding="0" cellspacing="0"><tr>',
                join('', $build_table) ,
                "</tr></table>"
            ]) ;

            return array($page_collection, $tb_page, $total_pages);
        }

        return array([], '', 1);
    }

    // Url with page parameter format
    // default: domain/path?key1=value1&key2=value2&page=1|2|3...
    // custom1: domain/path/1|2|3/?key1=value1&key2=value2
    public static function buildUrlWithCustomPageParam($url_path, array $params){
        $url_format_type = self::getUrlWithCustomPageFormat();

        $params_without_page = $params;
        $page_number = 1;
        if(isset($params['page'])) {
            $page_number = intval($params['page']);
            unset($params_without_page['page']);
        }

        // custom1 (use case: hanoicomputer.vn)
        if($url_format_type == 'custom1') {
            if($page_number > 1){
                $url_path = $url_path."/".$page_number."/";
            }
        }else{
            // default
            if($page_number > 1){
                // push page to the end, always
                $params_without_page['page'] = $page_number;
            }
        }


        if(sizeof($params_without_page)) {
            return join("", [$url_path, "?", http_build_query($params_without_page)]);
        }

        return $url_path;
    }

    // destruct Url to get url_path and query params
    public static function destructUrlWithCustomPageParam($full_url){
        $cache_key      = md5($full_url);
        $cached_value   = self::getCache($cache_key);
        // if in cache, get right away
        if($cached_value) return $cached_value;

        // not in cache, build and set cache
        $url_format_type = self::getUrlWithCustomPageFormat();

        // destruct
        $parsed_url = explode("?", $full_url);
        $url_path   = isset($parsed_url[0]) ? $parsed_url[0] : '';
        $query_part = isset($parsed_url[1]) ? $parsed_url[1] : '';
        $query_params = [];
        $current_page = 1;

        if($query_part) {
            parse_str($query_part, $query_params);
        }

        // custom1: url format= domain/path/1|2|3/?key1=value1&key2=value2
        if($url_format_type == 'custom1') {
            $match = [];
            if(preg_match("{/(.*?)/([0-9]+)/$}", $url_path, $match)){
                if(isset($match[2]) && $match[2] > 1) $current_page = $match[2];
                $url_path = "/".$match[1];
            }

        } else {
            // default
            if(isset($query_params['page'])) {
                $current_page = $query_params['page'];
                unset($query_params['page']);
            }
        }

        $cached_value = [
            'path' => $url_path,
            'query' => $query_params,
            'page' => $current_page,
        ];

        self::setCache($cache_key, $cached_value);

        return $cached_value;
    }


    // check if user in in the admin panel
    protected static function is_in_admin(){
        return substr($_SERVER['REQUEST_URI'], 0, 7) == '/admin/';
    }

    // Url with page parameter format
    // default: domain/path?key1=value1&key2=value2&page=1|2|3...
    // custom1: domain/path/1|2|3/?key1=value1&key2=value2
    protected static function getUrlWithCustomPageFormat() {
        $url_format_type = "default";

        // keep default for admin panel
        if(self::is_in_admin()) {
            return $url_format_type;
        }

        // or search page
        if(substr($_SERVER['REQUEST_URI'], 0, 4) == '/tim') {
            return $url_format_type;
        }

        if(defined("URL_PAGING_FORMAT") && URL_PAGING_FORMAT) {
            $url_format_type = URL_PAGING_FORMAT;
        }

        return $url_format_type;
    }

    protected static function getCache($key) {
        return isset(self::$cache[$key]) ? unserialize(self::$cache[$key]) : null;
    }

    protected static function setCache($key, $value) {
        self::$cache[$key] = serialize($value);
    }

    //Function nhay trang
    public static function paging($totalResults, $numPerRow, $currentURL, $maxPageDisplay, $limitPage = 50){
        $currentPage = isset($_GET["page"]) ? (int) $_GET["page"] : 1;
        $currentURL =  str_replace(array("?page=".$currentPage, "&page=".$currentPage),"",$currentURL);
        //build_url($currentURL, array("page"=>''));

        $first_url = $currentURL; //when $page=1

        if(strpos($currentURL, "?") !== false) $currentURL .= "&";
        else $currentURL .= "?";

        $maxPage = ceil($totalResults/$numPerRow);
        //max page to see : 20
        if($limitPage > 0){
            $maxPage = ($maxPage > $limitPage) ? $limitPage : $maxPage;
        }

        if($maxPage==1) return "";
        $farLeft ="<td class=\"pagingFarSide\" align=\"center\">...</td>";
        $farRight ="<td class=\"pagingFarSide\" align=\"center\">...</td>";
        $link ="<table cellpadding=\"0\" cellspacing=\"0\"><tr>";
        //$maxPageDisplay la so page se hien ra, thuong lay 7
        if($currentPage == 2) $link .= "<td class=\"pagingIntact\"><a href=\"".$first_url."\">Quay lại</a></td>";
        else if($currentPage > 2) $link .= "<td class=\"pagingIntact\"><a href=\"".$currentURL."page=".($currentPage-1)."\">Quay lại</a></td>";
        else $link .= "<td class=\"pagingIntact\"><a>Xem trang</a></td>";

        $link .= "<td class=\"pagingSpace\"></td>";

        if($maxPage<=$maxPageDisplay){

            for($i=1;$i<=$maxPage;$i++){
                if($i==$currentPage) $link .= "<td class=\"pagingViewed\">$i</td><td class=pagingSpace></td>";
                else {
                    if($i== 1) $link .= "<td class=\"pagingIntact\"><a href=\"".$first_url."\">$i</a></td><td class=pagingSpace></td>";
                    else $link .= "<td class=\"pagingIntact\"><a href=\"".$currentURL."page=$i\">$i</a></td><td class=pagingSpace></td>";
                }
            }

            if($currentPage < $maxPage) $link .= "<td class=\"pagingIntact\"><a href=\"".$currentURL."page=".($currentPage+1)."\">Tiếp theo</a></td>";

        }else{

            //Vay la tong so trang nhieu hon so trang muon hien ra
            if($currentPage<=(ceil($maxPageDisplay/2))){

                //Neu trang dang xem dang o muc 1,2,3,4
                for($i=1;$i<=$maxPageDisplay;$i++){
                    if($i==$currentPage) $link .= "<td class=\"pagingViewed\">$i</td><td class=\"pagingSpace\"></td>";
                    else {
                        if($i== 1)  $link .= "<td class=\"pagingIntact\"><a href=\"".$first_url."\">$i</a></td><td class=\"pagingSpace\"></td>";
                        else $link .= "<td class=\"pagingIntact\"><a href=\"".$currentURL."page=$i\">$i</a></td><td class=\"pagingSpace\"></td>";
                    }
                }
                $link .=$farRight;
                //$link .= "<td class=\"pagingIntact\"><a href=\"".$currentURL."page=".$maxPage."\">".$maxPage."</a></td><td class=pagingSpace></td>";//the last page
                $link .= "<td class=\"pagingIntact\"><a href=\"".$currentURL."page=".($currentPage+1)."\">Tiếp theo</a></td>";

            }elseif($currentPage<=($maxPage-round($maxPageDisplay/2,0))){
                //Neu trang dang xem o muc cao hon 4
                $link .= "<td class=\"pagingIntact\"><a href=\"".$first_url."\">1</a></td><td class=\"pagingSpace\"></td>";//the 1st page
                $link .= $farLeft;
                for($i=($currentPage-round($maxPageDisplay/2,0)+1);$i<($currentPage+round($maxPageDisplay/2,0));$i++){
                    if($i==$currentPage) $link .= "<td class=\"pagingViewed\">$i</td><td class=pagingSpace></td>";
                    else $link .= "<td class=\"pagingIntact\"><a href=\"".$currentURL."page=$i\">$i</a></td><td class=\"pagingSpace\"></td>";
                }
                $link .= $farRight;
                //$link .= "<td class=\"pagingIntact\"><a href=\"".$currentURL."page=".$maxPage."\">".$maxPage."</a></td><td class=pagingSpace></td>";//the last page
                $link .= "<td class=\"pagingIntact\"><a href=\"".$currentURL."page=".($currentPage+1)."\">Tiếp theo</a></td>";
            }else{
                //May trang cuoi cung
                $link .= "<td class=\"pagingIntact\"><a href=\"".$first_url."\">1</a></td><td class=\"pagingSpace\"></td>";//the 1st page
                $link .= $farLeft;
                for($i=($maxPage-$maxPageDisplay+1);$i<=$maxPage;$i++){
                    if($i==$currentPage) $link .= "<td class=\"pagingViewed\">$i</td><td class=\"pagingSpace\"></td>";
                    else $link .= "<td class=\"pagingIntact\"><a href=\"".$currentURL."page=$i\">$i</a></td><td class=\"pagingSpace\"></td>";
                }
            }
        }

        $link .= "</tr></table>";

        //Lua chon hien thi, phai it nhat tu 2 trang tro len moi hien ra
        if($maxPage > 1){
            return $link;
        }

        return false;
    }
}
