import React, {Component} from "react";
import PropTypes from 'prop-types';

class Pagination extends Component {
    constructor(props) {
        super(props);
        this.state = {
            options: {},
            paginationData: {},
            nextPageUrl: null,
            prevPageUrl: null,
            currentPage: null
        };
    }

    componentDidMount() {
        this.getProps(this.props);
    }

    UNSAFE_componentWillReceiveProps(props, nextContext) {
        this.getProps(props);
    }

    // Transform props
    getProps = (props) => {
        let defaultProps = Pagination.defaultProps.options;
        let options = this.props.options;
        Object.keys(defaultProps).forEach(function (key) {
            options[key] = props[key] ? props[key] : props['options'][key] ? props['options'][key] : defaultProps[key];
        });
        this.setState({options: options, paginationData: props.data});
    };

    // Check if page is active
    isCurrent = (page) => {
        let currentPage = this.state.paginationData.meta ? this.state.paginationData.meta.current_page : this.state.paginationData.current_page;
        return currentPage === page;
    };

    // Handle pagination buttons click event
    handleClick = (page) => {
        let parameters = {};
        if (this.props.requestParams) {
            parameters = this.props.requestParams;
        }
        parameters.page = page;
        this.props.changePage(parameters);
    };

    // Generate Prev Icon Or Text Buttons
    generateButtonsPrev = () => {
        let options = this.state.options;
        if (options.buttonIcons) {
            return <i className={options.prevButtonIcon}/>
        }
        return options.prevButtonText;
    };

    // Generate Next Icon Or Text Buttons
    generateButtonsNext = () => {
        let options = this.state.options;
        if (options.buttonIcons) {
            return <i className={options.nextButtonIcon}/>
        }
        return options.nextButtonText;
    };

    // Generate pagination buttons
    generatePagination = () => {
        let paginationData = this.state.paginationData;
        let pagination;
        if (Object.keys(paginationData).length) {
            let options = this.state.options;
            let current = paginationData.hasOwnProperty('current_page') ? paginationData.current_page : paginationData.meta.current_page,
                last = paginationData.hasOwnProperty('last_page') ? paginationData.last_page : paginationData.meta.last_page,
                delta = parseInt(options.numbersCountForShow),
                left = current - delta,
                right = current + delta + 1,
                range = [],
                rangeWithDots = [],
                l;
            for (let i = 1; i <= last; i++) {
                if ((i === 1 || i === last) || (i >= left && i < right)) {
                    range.push(i);
                }
            }
            for (let i of range) {
                if (l) {
                    if (i - l === 2) {
                        rangeWithDots.push(l + 1);
                    } else if (i - l !== 1) {
                        rangeWithDots.push('...');
                    }
                }
                rangeWithDots.push(i);
                l = i;
            }

            let nextPageUrl = paginationData.hasOwnProperty('next_page_url') ? paginationData.next_page_url : paginationData.links.next;
            let prevPageUrl = paginationData.hasOwnProperty('prev_page_url') ? paginationData.prev_page_url : paginationData.links.prev;
            pagination = (
                <ul className={options.containerClass}>
                    {prevPageUrl ?
                        <li className={options.prevButtonClass} onClick={(event) => {
                            event.preventDefault();
                            this.handleClick(current - 1)
                        }}>
                            <a href="" className={options.numberClass}>
                                {this.generateButtonsPrev()}
                            </a>
                        </li> : ""}
                    {rangeWithDots.map((page, index) =>
                        this.generateNumber(page, index)
                    )}
                    {nextPageUrl ?
                        <li className={options.nextButtonClass} onClick={(event) => {
                            event.preventDefault();
                            this.handleClick(current + 1)
                        }}>
                            <a href="" className={options.numberClass}>
                                {this.generateButtonsNext()}
                            </a>
                        </li>
                        : ""}
                </ul>
            );
        }
        return pagination;
    };

    generateNumber(page, index) {
        let options = this.state.options;
        return (
            <li className={this.isCurrent(page) ? options.numberButtonClass + " " + options.activeClass :
                options.numberButtonClass} key={index}>
                <a href="" className={options.numberClass}
                   onClick={(event) => {
                       event.preventDefault();
                       this.handleClick(page === '...' ? index + 1 : page)
                   }}>{page}</a>
            </li>
        );
    }

    render() {
        return (
            <React.Fragment>
                {this.generatePagination()}
            </React.Fragment>
        );
    }
}

Pagination.defaultProps = {
    options: {
        containerClass: "pagination",
        buttonIcons: false,
        prevButtonClass: "page-item",
        prevButtonText: "Prev",
        prevButtonIcon: "fa fa-chevron-left",
        nextButtonClass: "page-item",
        nextButtonText: "Next",
        nextButtonIcon: "fa fa-chevron-right",
        numberButtonClass: "page-item",
        numberClass: "page-link",
        numbersCountForShow: 2,
        activeClass: 'active'
    },
    data: {}
};

Pagination.propTypes = {
    options: PropTypes.shape({
        containerClass: PropTypes.string,
        buttonIcons: PropTypes.bool,
        nextButtonClass: PropTypes.string,
        nextButtonText: PropTypes.string,
        nextButtonIcon: PropTypes.string,
        prevButtonClass: PropTypes.string,
        prevButtonText: PropTypes.string,
        prevButtonIcon: PropTypes.string,
        numberButtonClass: PropTypes.string,
        numberClass: PropTypes.string,
        numberCountForShow: PropTypes.number,
        activeClass: PropTypes.string
    }),
    data: PropTypes.object
};
export default Pagination;
