import React, { useEffect, useMemo, useState, useRef } from 'react';
import { __, sprintf } 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 ExpenseList = ({ expenses, onExpenseUpdated }) => {
    const restBase = appData.restBase || '/wp-json/manfi-expense-tracker/v1/';
    const [categories, setCategories] = useState([]);
    const [tags, setTags] = useState([]);
    const [editingId, setEditingId] = useState(null);
    const [isSaving, setIsSaving] = useState(false);
    const [editForm, setEditForm] = useState({
        category_id: '',
        amount: '',
        date: '',
        recurring_interval: '',
        tag_ids: [],
        remark: '',
    });
    const [error, setError] = useState('');
    const [sortConfig, setSortConfig] = useState({ key: 'date', direction: 'desc' });

    const itemsPerPage = Number(appData.expensesPerPage) || 20;
    const [currentPage, setCurrentPage] = useState(1);
    const prevLengthRef = useRef(expenses.length);

    useEffect(() => {
        if (prevLengthRef.current !== expenses.length) {
            setCurrentPage(1);
            prevLengthRef.current = expenses.length;
        }
    }, [expenses.length]);

    const sortedExpenses = useMemo(() => {
        let sortableItems = [...expenses];
        if (sortConfig.key !== null) {
            sortableItems.sort((a, b) => {
                let aValue = a[sortConfig.key];
                let bValue = b[sortConfig.key];

                if (sortConfig.key === 'amount') {
                    aValue = parseFloat(aValue || 0);
                    bValue = parseFloat(bValue || 0);
                } else if (sortConfig.key === 'date') {
                    aValue = new Date(aValue || 0).getTime();
                    bValue = new Date(bValue || 0).getTime();
                } else {
                    aValue = String(aValue || '').toLowerCase();
                    bValue = String(bValue || '').toLowerCase();
                }

                if (aValue < bValue) {
                    return sortConfig.direction === 'asc' ? -1 : 1;
                }
                if (aValue > bValue) {
                    return sortConfig.direction === 'asc' ? 1 : -1;
                }
                return 0;
            });
        }
        return sortableItems;
    }, [expenses, sortConfig]);

    const totalPages = Math.ceil(sortedExpenses.length / itemsPerPage);

    const paginatedExpenses = useMemo(() => {
        const startIndex = (currentPage - 1) * itemsPerPage;
        return sortedExpenses.slice(startIndex, startIndex + itemsPerPage);
    }, [sortedExpenses, currentPage, itemsPerPage]);

    const requestSort = (key) => {
        let direction = 'asc';
        if (sortConfig.key === key && sortConfig.direction === 'asc') {
            direction = 'desc';
        }
        setSortConfig({ key, direction });
    };

    const renderSortIndicator = (key) => {
        if (sortConfig.key !== key) {
            return <span className="manfiet-sort-indicator">↕</span>;
        }
        return sortConfig.direction === 'asc' ? 
            <span className="manfiet-sort-indicator active">▲</span> : 
            <span className="manfiet-sort-indicator active">▼</span>;
    };

    useEffect(() => {
        requestJson(`${restBase}categories`)
            .then((data) => setCategories(Array.isArray(data) ? data : []))
            .catch(() => setCategories([]));

        requestJson(`${restBase}tags`)
            .then((data) => setTags(Array.isArray(data) ? data : []))
            .catch(() => setTags([]));
    }, [restBase]);

    const categoryByPath = useMemo(() => {
        const map = new Map();
        categories.forEach((category) => {
            map.set(category.path_name || category.category_name, category);
        });
        return map;
    }, [categories]);

    const startEditing = (expense) => {
        const matchedCategory = categoryByPath.get(expense.category);
        const tagIds = (Array.isArray(expense.tags) ? expense.tags : [])
            .map((tagName) => {
                const matchedTag = tags.find((tag) => tag.tag_name === tagName);
                return matchedTag ? String(matchedTag.id) : null;
            })
            .filter(Boolean);

        setEditingId(expense.id);
        setEditForm({
            category_id: matchedCategory ? String(matchedCategory.id) : '',
            amount: String(expense.amount ?? ''),
            date: expense.date || '',
            recurring_interval: expense.recurring_interval || '',
            tag_ids: tagIds,
            remark: expense.remark || '',
        });
        setError('');
    };

    const cancelEditing = () => {
        setEditingId(null);
        setError('');
    };

    const saveEdit = (expenseId) => {
        if (!editForm.category_id) {
            setError(__('Please select a category.', 'manfi-expense-tracker'));
            return;
        }

        if (!editForm.amount || Number(editForm.amount) <= 0) {
            setError(__('Amount must be greater than zero.', 'manfi-expense-tracker'));
            return;
        }

        if (!editForm.date) {
            setError(__('Date is required.', 'manfi-expense-tracker'));
            return;
        }

        setIsSaving(true);
        setError('');

        requestJson(`${restBase}expenses/${expenseId}`, {
            method: 'PUT',
            body: JSON.stringify({
                category_id: Number(editForm.category_id),
                amount: Number(editForm.amount),
                date: editForm.date,
                recurring_interval: editForm.recurring_interval,
                tags: tags
                    .filter((tag) => editForm.tag_ids.includes(String(tag.id)))
                    .map((tag) => tag.tag_name),
                remark: editForm.remark ? editForm.remark.trim() : '',
            }),
        })
            .then(() => {
                setEditingId(null);
                if (typeof onExpenseUpdated === 'function') {
                    onExpenseUpdated();
                }
            })
            .catch((saveError) => {
                setError(saveError.message || __('Failed to update expense.', 'manfi-expense-tracker'));
            })
            .finally(() => {
                setIsSaving(false);
            });
    };

    const handleDelete = (expenseId) => {
        if (!window.confirm(__('Are you sure you want to delete this expense?', 'manfi-expense-tracker'))) {
            return;
        }

        setError('');

        requestJson(`${restBase}expenses/${expenseId}`, {
            method: 'DELETE',
        })
            .then(() => {
                if (typeof onExpenseUpdated === 'function') {
                    onExpenseUpdated();
                }
            })
            .catch((deleteError) => {
                setError(deleteError.message || __('Failed to delete expense.', 'manfi-expense-tracker'));
            });
    };

    if (!expenses.length) {
        return <p>{__('No expenses found yet.', 'manfi-expense-tracker')}</p>;
    }

    return (
        <>
        <div className="manfiet-table-scroll">
            {error && <p className="manfiet-alert manfiet-alert-error">{error}</p>}
            <table className="manfiet-table">
                <thead>
                    <tr>
                        <th className="sortable" onClick={() => requestSort('category')}>
                            {__('Category', 'manfi-expense-tracker')}
                            {renderSortIndicator('category')}
                        </th>
                        <th className="manfiet-align-right sortable" onClick={() => requestSort('amount')}>
                            {__('Amount', 'manfi-expense-tracker')}
                            {renderSortIndicator('amount')}
                        </th>
                        <th className="sortable" onClick={() => requestSort('date')}>
                            {__('Date', 'manfi-expense-tracker')}
                            {renderSortIndicator('date')}
                        </th>
                        <th className="sortable" onClick={() => requestSort('recurring_interval')}>
                            {__('Recurring', 'manfi-expense-tracker')}
                            {renderSortIndicator('recurring_interval')}
                        </th>
                        <th>{__('Tags', 'manfi-expense-tracker')}</th>
                        <th className="manfiet-align-center">{__('Actions', 'manfi-expense-tracker')}</th>
                    </tr>
                </thead>
                <tbody>
                    {paginatedExpenses.map((expense) => {
                        const isEditing = editingId === expense.id;
                        return (
                            <tr key={expense.id}>
                                <td>
                                    {isEditing ? (
                                        <>
                                            <select
                                                className="manfiet-input"
                                                value={editForm.category_id}
                                                onChange={(event) => setEditForm((current) => ({ ...current, category_id: event.target.value }))}
                                            >
                                                <option value="">{__('Select category', 'manfi-expense-tracker')}</option>
                                                {categories.map((category) => (
                                                    <option key={category.id} value={category.id}>
                                                        {category.display_name || category.path_name || category.category_name}
                                                    </option>
                                                ))}
                                            </select>
                                            <textarea
                                                className="manfiet-input"
                                                style={{ marginTop: '6px', resize: 'vertical', minHeight: '50px', fontFamily: 'inherit' }}
                                                placeholder={__('Remark (optional)', 'manfi-expense-tracker')}
                                                value={editForm.remark}
                                                onChange={(event) => setEditForm((current) => ({ ...current, remark: event.target.value }))}
                                                rows={2}
                                            />
                                        </>
                                    ) : (
                                        <>
                                            <div>{expense.category}</div>
                                            {expense.remark && (
                                                <div style={{ fontSize: '11px', color: '#64748b', fontStyle: 'italic', marginTop: '3px' }}>
                                                    {expense.remark}
                                                </div>
                                            )}
                                        </>
                                    )}
                                </td>
                                <td className="manfiet-align-right manfiet-font-semibold">
                                    {isEditing ? (
                                        <input
                                            type="number"
                                            min="0.01"
                                            step="0.01"
                                            className="manfiet-input"
                                            value={editForm.amount}
                                            onChange={(event) => setEditForm((current) => ({ ...current, amount: event.target.value }))}
                                        />
                                    ) : (
                                         <>{appData.currencySymbol || '$'}{Number(expense.amount).toFixed(2)}</>
                                    )}
                                </td>
                                <td>
                                    {isEditing ? (
                                        <input
                                            type="date"
                                            className="manfiet-input"
                                            value={editForm.date}
                                            onChange={(event) => setEditForm((current) => ({ ...current, date: event.target.value }))}
                                        />
                                    ) : (
                                        expense.date
                                    )}
                                </td>
                                <td>
                                    {isEditing ? (
                                        <select
                                            className="manfiet-input"
                                            value={editForm.recurring_interval}
                                            onChange={(event) => setEditForm((current) => ({ ...current, recurring_interval: event.target.value }))}
                                        >
                                            <option value="">{__('One-time', 'manfi-expense-tracker')}</option>
                                            <option value="day">{__('Daily', 'manfi-expense-tracker')}</option>
                                            <option value="week">{__('Weekly', 'manfi-expense-tracker')}</option>
                                            <option value="month">{__('Monthly', 'manfi-expense-tracker')}</option>
                                            <option value="year">{__('Yearly', 'manfi-expense-tracker')}</option>
                                        </select>
                                    ) : (
                                        expense.recurring_interval || __('One-time', 'manfi-expense-tracker')
                                    )}
                                </td>
                                <td>
                                    {isEditing ? (
                                        <select
                                            multiple
                                            className="manfiet-input manfiet-input-multi"
                                            value={editForm.tag_ids}
                                            onChange={(event) => {
                                                const selected = Array.from(event.target.selectedOptions).map((option) => option.value);
                                                setEditForm((current) => ({ ...current, tag_ids: selected }));
                                            }}
                                        >
                                            {tags.map((tag) => (
                                                <option key={tag.id} value={String(tag.id)}>
                                                    {tag.tag_name}
                                                </option>
                                            ))}
                                        </select>
                                    ) : (
                                        <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>
                                <td className="manfiet-align-center manfiet-nowrap">
                                    {isEditing ? (
                                        <>
                                            <button
                                                type="button"
                                                className="manfiet-button manfiet-button-primary manfiet-button-sm"
                                                onClick={() => saveEdit(expense.id)}
                                                disabled={isSaving}
                                            >
                                                {isSaving ? __('Saving...', 'manfi-expense-tracker') : __('Save', 'manfi-expense-tracker')}
                                            </button>
                                            <button
                                                type="button"
                                                className="manfiet-button manfiet-button-secondary manfiet-button-sm"
                                                onClick={cancelEditing}
                                                disabled={isSaving}
                                            >
                                                {__('Cancel', 'manfi-expense-tracker')}
                                            </button>
                                        </>
                                    ) : (
                                        <>
                                            <button
                                                type="button"
                                                className="manfiet-button manfiet-button-info manfiet-button-sm"
                                                onClick={() => startEditing(expense)}
                                                style={{ marginRight: '6px' }}
                                            >
                                                {__('Edit', 'manfi-expense-tracker')}
                                            </button>
                                            <button
                                                type="button"
                                                className="manfiet-button manfiet-button-danger manfiet-button-sm"
                                                onClick={() => handleDelete(expense.id)}
                                            >
                                                {__('Delete', 'manfi-expense-tracker')}
                                            </button>
                                        </>
                                    )}
                                </td>
                            </tr>
                        );
                    })}
                </tbody>
            </table>
        </div>
        {totalPages > 1 && (
            <div className="manfiet-pagination-row">
                <div className="manfiet-pagination-summary">
                    {sprintf(
                        __('Showing %d–%d of %d expenses', 'manfi-expense-tracker'),
                        (currentPage - 1) * itemsPerPage + 1,
                        Math.min(currentPage * itemsPerPage, sortedExpenses.length),
                        sortedExpenses.length
                    )}
                </div>
                <div className="manfiet-pagination-pages">
                    <button
                        type="button"
                        className="manfiet-page-btn"
                        onClick={() => setCurrentPage(1)}
                        disabled={currentPage === 1}
                        title={__('First Page', 'manfi-expense-tracker')}
                    >
                        «
                    </button>
                    <button
                        type="button"
                        className="manfiet-page-btn"
                        onClick={() => setCurrentPage((prev) => Math.max(prev - 1, 1))}
                        disabled={currentPage === 1}
                        title={__('Previous Page', 'manfi-expense-tracker')}
                    >
                        ‹
                    </button>
                    
                    {Array.from({ length: totalPages }, (_, i) => i + 1)
                        .filter((page) => {
                            return page === 1 || page === totalPages || Math.abs(page - currentPage) <= 2;
                        })
                        .map((page, index, array) => {
                            const showEllipsisBefore = index > 0 && page - array[index - 1] > 1;
                            return (
                                <React.Fragment key={page}>
                                    {showEllipsisBefore && (
                                        <span className="manfiet-pagination-ellipsis">...</span>
                                    )}
                                    <button
                                        type="button"
                                        className={`manfiet-page-btn ${currentPage === page ? 'is-active' : ''}`}
                                        onClick={() => setCurrentPage(page)}
                                        disabled={currentPage === page}
                                    >
                                        {page}
                                    </button>
                                </React.Fragment>
                            );
                        })}

                    <button
                        type="button"
                        className="manfiet-page-btn"
                        onClick={() => setCurrentPage((prev) => Math.min(prev + 1, totalPages))}
                        disabled={currentPage === totalPages}
                        title={__('Next Page', 'manfi-expense-tracker')}
                    >
                        ›
                    </button>
                    <button
                        type="button"
                        className="manfiet-page-btn"
                        onClick={() => setCurrentPage(totalPages)}
                        disabled={currentPage === totalPages}
                        title={__('Last Page', 'manfi-expense-tracker')}
                    >
                        »
                    </button>
                </div>
            </div>
        )}
        </>
    );
};

export default ExpenseList;
