import React, { useEffect, useMemo, useState } from 'react';
import { __ } from '@wordpress/i18n';

const appData = window.manfietExpenseTrackerData || {};

const requestJson = (url, options = {}) => {
    const headers = {
        'Content-Type': 'application/json',
        ...(options.headers || {}),
    };

    if (appData.restNonce) {
        headers['X-WP-Nonce'] = appData.restNonce;
    }

    return fetch(url, {
        credentials: 'same-origin',
        ...options,
        headers,
    }).then(async (response) => {
        const data = await response.json().catch(() => ({}));

        if (!response.ok) {
            throw new Error(data.message || 'Request failed');
        }

        return data;
    });
};

const ExpenseExplorerPanel = ({ title, filter }) => {
    const restBase = appData.restBase || '/wp-json/manfi-expense-tracker/v1/';
    const [items, setItems] = useState([]);
    const [pagination, setPagination] = useState({ page: 1, per_page: 50, total: 0, total_pages: 0 });
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState('');

    const loadPage = (pageNumber) => {
        if (!filter || (!filter.category_id && !filter.tag_name)) {
            return;
        }

        const params = new URLSearchParams();
        params.set('page', String(pageNumber));
        params.set('per_page', '50');

        if (filter.category_id) {
            params.set('category_id', String(filter.category_id));
            params.set('include_children', filter.include_children ? '1' : '0');
        }

        if (filter.tag_name) {
            params.set('tag_name', filter.tag_name);
        }

        setLoading(true);
        setError('');

        requestJson(`${restBase}expenses/explore?${params.toString()}`)
            .then((data) => {
                const list = Array.isArray(data.items) ? data.items : [];
                const meta = data.pagination || {};

                setItems(list);
                setPagination({
                    page: Number(meta.page || pageNumber),
                    per_page: Number(meta.per_page || 50),
                    total: Number(meta.total || 0),
                    total_pages: Number(meta.total_pages || 0),
                });
            })
            .catch((requestError) => {
                setItems([]);
                setError(requestError.message || __('Failed to load expenses.', 'manfi-expense-tracker'));
            })
            .finally(() => setLoading(false));
    };

    useEffect(() => {
        setItems([]);
        setPagination({ page: 1, per_page: 50, total: 0, total_pages: 0 });
        if (filter) {
            loadPage(1);
        }
    }, [filter?.category_id, filter?.include_children, filter?.tag_name]);

    const hasPrevious = pagination.page > 1;
    const hasNext = pagination.total_pages > pagination.page;
    const pageTokens = useMemo(() => {
        const totalPages = pagination.total_pages;
        const currentPage = pagination.page;

        if (totalPages <= 0) {
            return [1];
        }

        if (totalPages <= 7) {
            return Array.from({ length: totalPages }, (_, index) => index + 1);
        }

        const tokens = [1];
        let start = Math.max(2, currentPage - 1);
        let end = Math.min(totalPages - 1, currentPage + 1);

        if (currentPage <= 3) {
            start = 2;
            end = 4;
        }

        if (currentPage >= totalPages - 2) {
            start = totalPages - 3;
            end = totalPages - 1;
        }

        if (start > 2) {
            tokens.push('left-ellipsis');
        }

        for (let page = start; page <= end; page += 1) {
            tokens.push(page);
        }

        if (end < totalPages - 1) {
            tokens.push('right-ellipsis');
        }

        tokens.push(totalPages);
        return tokens;
    }, [pagination.page, pagination.total_pages]);

    return (
        <div className="manfiet-card manfiet-mt-12">
            <div className="manfiet-card-head-row manfiet-mb-14">
                <h3 className="manfiet-card-title manfiet-card-title-no-margin">{title}</h3>
                <div className="manfiet-pagination-summary">
                    {loading
                        ? __('Loading expenses...', 'manfi-expense-tracker')
                        : __('Newest first (LIFO). 50 per page.', 'manfi-expense-tracker')}
                </div>
            </div>

            {error && <p className="manfiet-alert manfiet-alert-error">{error}</p>}

            {items.length === 0 ? (
                <p className="manfiet-text-muted">{loading ? __('Loading...', 'manfi-expense-tracker') : __('No expenses found for this filter.', 'manfi-expense-tracker')}</p>
            ) : (
                <div className="manfiet-table-scroll">
                    <table className="manfiet-table">
                        <thead>
                            <tr>
                                <th>{__('Category', 'manfi-expense-tracker')}</th>
                                <th className="manfiet-align-right">{__('Amount', 'manfi-expense-tracker')}</th>
                                <th>{__('Date', 'manfi-expense-tracker')}</th>
                                <th>{__('Recurring', 'manfi-expense-tracker')}</th>
                                <th>{__('Tags', 'manfi-expense-tracker')}</th>
                            </tr>
                        </thead>
                        <tbody>
                            {items.map((expense) => (
                                <tr key={expense.id}>
                                    <td>{expense.category}</td>
                                    <td className="manfiet-align-right manfiet-font-semibold">{appData.currencySymbol || '$'}{Number(expense.amount || 0).toFixed(2)}</td>
                                    <td>{expense.date}</td>
                                    <td>{expense.recurring_interval || __('One-time', 'manfi-expense-tracker')}</td>
                                    <td>
                                        <div className="manfiet-tag-list">
                                            {(Array.isArray(expense.tags) ? expense.tags : []).length > 0 ? (
                                                expense.tags.map((tagName) => (
                                                    <span key={`${expense.id}-${tagName}`} className="manfiet-tag-chip">{tagName}</span>
                                                ))
                                            ) : (
                                                <span className="manfiet-text-muted">{__('No tags', 'manfi-expense-tracker')}</span>
                                            )}
                                        </div>
                                    </td>
                                </tr>
                            ))}
                        </tbody>
                    </table>
                </div>
            )}

            <div className="manfiet-pagination-row">
                <button
                    type="button"
                    className="manfiet-button manfiet-button-secondary manfiet-button-sm"
                    disabled={!hasPrevious || loading}
                    onClick={() => loadPage(pagination.page - 1)}
                >
                    {__('Previous', 'manfi-expense-tracker')}
                </button>
                <div className="manfiet-pagination-pages" role="navigation" aria-label={__('Pagination', 'manfi-expense-tracker')}>
                    {pageTokens.map((token) => {
                        if (typeof token !== 'number') {
                            return (
                                <span key={token} className="manfiet-pagination-ellipsis" aria-hidden="true">...</span>
                            );
                        }

                        return (
                            <button
                                key={`page-${token}`}
                                type="button"
                                className={`manfiet-page-btn ${token === pagination.page ? 'is-active' : ''}`}
                                disabled={loading || token === pagination.page}
                                onClick={() => loadPage(token)}
                                aria-current={token === pagination.page ? 'page' : undefined}
                            >
                                {token}
                            </button>
                        );
                    })}
                </div>
                <span className="manfiet-pagination-status">
                    {pagination.total_pages > 0
                        ? __('Page', 'manfi-expense-tracker') +
                            ' ' + pagination.page +
                            ' ' + __('of', 'manfi-expense-tracker') +
                            ' ' + pagination.total_pages +
                            ' (' + pagination.total + ' ' + __('total', 'manfi-expense-tracker') + ')'
                        : __('Page 1 of 1 (0 total)', 'manfi-expense-tracker')}
                </span>
                <button
                    type="button"
                    className="manfiet-button manfiet-button-secondary manfiet-button-sm"
                    disabled={!hasNext || loading}
                    onClick={() => loadPage(pagination.page + 1)}
                >
                    {__('Next', 'manfi-expense-tracker')}
                </button>
            </div>
        </div>
    );
};

export default ExpenseExplorerPanel;
