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

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 CategoryManager = () => {
    const [categories, setCategories] = useState([]);
    const [newCategory, setNewCategory] = useState('');
    const [parentId, setParentId] = useState('0');
    const [editingCategoryId, setEditingCategoryId] = useState(null);
    const [editingName, setEditingName] = useState('');
    const [editingParentId, setEditingParentId] = useState('0');
    const [pendingDeleteCategory, setPendingDeleteCategory] = useState(null);
    const [isDeleting, setIsDeleting] = useState(false);
    const [selectedCategory, setSelectedCategory] = useState(null);
    const [error, setError] = useState('');
    const [categoryType, setCategoryType] = useState('global');
    const [editingIsGlobal, setEditingIsGlobal] = useState(true);
    const [categoryDescription, setCategoryDescription] = useState('');
    const [editingDescription, setEditingDescription] = useState('');
    const restBase = appData.restBase || '/wp-json/manfi-expense-tracker/v1/';
    const isGlobalManager = Boolean(appData.canManageExpenses);

    const loadCategories = () => {
        requestJson(`${restBase}categories`)
            .then((data) => {
                setCategories(Array.isArray(data) ? data : []);
            })
            .catch(() => setError(__('Error fetching categories.', 'manfi-expense-tracker')));
    };

    useEffect(() => {
        loadCategories();
    }, []);

    const parentOptions = useMemo(() => {
        return categories.filter((category) => {
            if (isGlobalManager) {
                return true;
            }

            return !category.is_global;
        });
    }, [categories, isGlobalManager]);

    const categoriesInTreeOrder = useMemo(() => {
        const idSet = new Set(categories.map((category) => Number(category.id)));
        const grouped = new Map();

        categories.forEach((category) => {
            const rawParentId = Number(category.parent_id || 0);
            const parentId = rawParentId > 0 && idSet.has(rawParentId) ? rawParentId : 0;

            if (!grouped.has(parentId)) {
                grouped.set(parentId, []);
            }
            grouped.get(parentId).push(category);
        });

        grouped.forEach((list) => {
            list.sort((a, b) => (a.category_name || '').localeCompare(b.category_name || ''));
        });

        const ordered = [];
        const walk = (parentId, depth) => {
            const children = grouped.get(parentId) || [];

            children.forEach((category) => {
                ordered.push({
                    ...category,
                    treeDepth: depth,
                });
                walk(Number(category.id), depth + 1);
            });
        };

        walk(0, 0);
        return ordered;
    }, [categories]);

    const addCategory = () => {
        if (!newCategory.trim()) {
            setError(__('Category name cannot be empty.', 'manfi-expense-tracker'));
            return;
        }

        setError('');

        requestJson(`${restBase}categories`, {
            method: 'POST',
            body: JSON.stringify({
                category_name: newCategory,
                parent_id: Number(parentId),
                is_global: isGlobalManager ? (categoryType === 'global') : false,
                description: categoryDescription,
            }),
        })
            .then(() => {
                setNewCategory('');
                setParentId('0');
                setCategoryType('global');
                setCategoryDescription('');
                setError('');
                loadCategories();
            })
                .catch((requestError) => setError(requestError.message || __('Failed to add category.', 'manfi-expense-tracker')));
    };

    const deleteCategory = (id) => {
        setIsDeleting(true);
        requestJson(`${restBase}categories/${id}`, { method: 'DELETE' })
            .then(() => {
                setCategories(categories.filter((category) => category.id !== id));
                setPendingDeleteCategory(null);
            })
            .catch((requestError) => setError(requestError.message || __('Error deleting category.', 'manfi-expense-tracker')))
            .finally(() => setIsDeleting(false));
    };

    const askDeleteCategory = (category) => {
        setError('');
        setPendingDeleteCategory(category);
    };

    const cancelDeleteCategory = () => {
        if (isDeleting) {
            return;
        }

        setPendingDeleteCategory(null);
    };

    const startEditCategory = (category) => {
        setError('');
        setEditingCategoryId(category.id);
        setEditingName(category.category_name || '');
        setEditingParentId(String(category.parent_id || 0));
        setEditingIsGlobal(Boolean(category.is_global));
        setEditingDescription(category.description || '');
    };

    const cancelEditCategory = () => {
        setEditingCategoryId(null);
        setEditingName('');
        setEditingParentId('0');
        setEditingIsGlobal(true);
        setEditingDescription('');
    };

    const getEditParentOptions = (category) => {
        return categories.filter((item) => item.id !== category.id && item.is_global === category.is_global);
    };

    const saveCategoryEdit = () => {
        if (!editingCategoryId) {
            return;
        }

        if (!editingName.trim()) {
            setError(__('Category name cannot be empty.', 'manfi-expense-tracker'));
            return;
        }

        requestJson(`${restBase}categories/${editingCategoryId}`, {
            method: 'PUT',
            body: JSON.stringify({
                category_name: editingName.trim(),
                parent_id: Number(editingParentId),
                is_global: editingIsGlobal,
                description: editingDescription.trim(),
            }),
        })
            .then(() => {
                cancelEditCategory();
                loadCategories();
            })
            .catch((requestError) => setError(requestError.message || __('Failed to update category.', 'manfi-expense-tracker')));
    };

    const handleCategoryClick = (category) => {
        setSelectedCategory(category);
    };

    return (
        <div className="manfiet-page-shell">
            <div className="manfiet-page-hero">
                <div className="left-section">
                    <h2 className="manfiet-page-title">{__('Manage Expense Categories', 'manfi-expense-tracker')}</h2>
                    {isGlobalManager && <p className="manfiet-page-subtitle">{__('Categories created here are available in the expense form dropdown for all users.', 'manfi-expense-tracker')}</p>}
                </div>
            </div>

            <div className="manfiet-card manfiet-mb-14">
                {error && <p className="manfiet-alert manfiet-alert-error">{error}</p>}
                <div className="manfiet-form-grid manfiet-form-grid-end">
                    <div className="manfiet-field">
                        <label className="manfiet-label" htmlFor="manfiet-category-name">{__('Category Name', 'manfi-expense-tracker')}</label>
                        <input
                            id="manfiet-category-name"
                            type="text"
                            value={newCategory}
                            onChange={(event) => setNewCategory(event.target.value)}
                            placeholder={__('Enter category name', 'manfi-expense-tracker')}
                            className="manfiet-input"
                        />
                    </div>
                    <div className="manfiet-field">
                        <label className="manfiet-label" htmlFor="manfiet-category-parent">{__('Parent Category', 'manfi-expense-tracker')}</label>
                        <select
                            id="manfiet-category-parent"
                            value={parentId}
                            onChange={(event) => setParentId(event.target.value)}
                            className="manfiet-input"
                        >
                            <option value="0">{__('No parent (top level)', 'manfi-expense-tracker')}</option>
                            {parentOptions.map((category) => (
                                <option key={category.id} value={category.id}>
                                    {category.display_name || category.path_name || category.category_name}
                                </option>
                            ))}
                        </select>
                    </div>
                    {isGlobalManager && (
                        <div className="manfiet-field">
                            <label className="manfiet-label" htmlFor="manfiet-category-type">{__('Type', 'manfi-expense-tracker')}</label>
                            <select
                                id="manfiet-category-type"
                                value={categoryType}
                                onChange={(event) => setCategoryType(event.target.value)}
                                className="manfiet-input"
                            >
                                <option value="global">{__('Global (Shared)', 'manfi-expense-tracker')}</option>
                                <option value="personal">{__('Personal (Private)', 'manfi-expense-tracker')}</option>
                            </select>
                        </div>
                    )}
                    <div className="manfiet-field">
                        <label className="manfiet-label" htmlFor="manfiet-category-description">{__('Description', 'manfi-expense-tracker')}</label>
                        <input
                            id="manfiet-category-description"
                            type="text"
                            value={categoryDescription}
                            onChange={(event) => setCategoryDescription(event.target.value)}
                            placeholder={__('Why this category is used...', 'manfi-expense-tracker')}
                            className="manfiet-input"
                        />
                    </div>
                    <button type="button" onClick={addCategory} className="manfiet-button manfiet-button-primary">
                        {__('Add Category', 'manfi-expense-tracker')}
                    </button>
                </div>
            </div>

            {categories.length === 0 ? (
                <div className="manfiet-card">
                    <p>{__('No categories found. Create your first category below.', 'manfi-expense-tracker')}</p>
                </div>
            ) : (
                <div className="manfiet-card">
                    <table className="manfiet-table manfiet-table-categories">
                        <thead>
                            <tr>
                                <th>{__('Category Name', 'manfi-expense-tracker')}</th>
                                <th className="manfiet-align-center manfiet-col-type">{__('Type', 'manfi-expense-tracker')}</th>
                                <th className="manfiet-align-center manfiet-col-actions">{__('Actions', 'manfi-expense-tracker')}</th>
                            </tr>
                        </thead>
                        <tbody>
                            {categoriesInTreeOrder.map((category) => (
                                <tr key={category.id}>
                                    <td>
                                        {editingCategoryId === category.id ? (
                                            <div className="manfiet-form-stack">
                                                <input
                                                    type="text"
                                                    className="manfiet-input"
                                                    value={editingName}
                                                    onChange={(event) => setEditingName(event.target.value)}
                                                />
                                                <select
                                                    className="manfiet-input"
                                                    value={editingParentId}
                                                    onChange={(event) => setEditingParentId(event.target.value)}
                                                >
                                                    <option value="0">{__('No parent (top level)', 'manfi-expense-tracker')}</option>
                                                    {getEditParentOptions(category).map((parentOption) => (
                                                        <option key={parentOption.id} value={parentOption.id}>
                                                            {parentOption.display_name || parentOption.path_name || parentOption.category_name}
                                                        </option>
                                                    ))}
                                                </select>
                                                {isGlobalManager && (
                                                    <select
                                                        className="manfiet-input"
                                                        value={editingIsGlobal ? 'global' : 'personal'}
                                                        onChange={(event) => setEditingIsGlobal(event.target.value === 'global')}
                                                        style={{ marginTop: '6px' }}
                                                    >
                                                        <option value="global">{__('Global (Shared)', 'manfi-expense-tracker')}</option>
                                                        <option value="personal">{__('Personal (Private)', 'manfi-expense-tracker')}</option>
                                                    </select>
                                                )}
                                                <input
                                                    type="text"
                                                    className="manfiet-input"
                                                    value={editingDescription}
                                                    onChange={(event) => setEditingDescription(event.target.value)}
                                                    placeholder={__('Description', 'manfi-expense-tracker')}
                                                    style={{ marginTop: '6px' }}
                                                />
                                            </div>
                                        ) : (
                                            <button
                                                type="button"
                                                className={`manfiet-inline-link manfiet-cat-name-link ${selectedCategory && selectedCategory.id === category.id ? 'is-active' : ''}`}
                                                onClick={() => handleCategoryClick(category)}
                                            >
                                                <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }}>
                                                    <span className={category.treeDepth === 0 ? 'manfiet-cat-parent-name' : 'manfiet-cat-child-name'}>
                                                        {category.treeDepth > 0 && (
                                                            <span className="manfiet-cat-dashes" aria-hidden="true">
                                                                {'\u2014 '.repeat(category.treeDepth)}
                                                            </span>
                                                        )}
                                                        {category.category_name}
                                                    </span>
                                                    {category.description && (
                                                        <span
                                                            className="manfiet-cat-desc"
                                                            style={{
                                                                fontSize: '11px',
                                                                color: '#64748b',
                                                                marginTop: '2px',
                                                                marginLeft: category.treeDepth > 0 ? `${category.treeDepth * 18}px` : '0',
                                                                fontWeight: 'normal',
                                                                fontStyle: 'italic'
                                                            }}
                                                        >
                                                            {category.description}
                                                        </span>
                                                    )}
                                                </div>
                                            </button>
                                        )}
                                    </td>
                                    <td className="manfiet-align-center">
                                        <span className={category.is_global ? 'manfiet-pill manfiet-pill-global' : 'manfiet-pill manfiet-pill-personal'}>
                                            {category.is_global ? __('Global', 'manfi-expense-tracker') : __('Personal', 'manfi-expense-tracker')}
                                        </span>
                                    </td>
                                    <td className="manfiet-align-center">
                                        {editingCategoryId === category.id ? (
                                            <>
                                                <button type="button" onClick={saveCategoryEdit} className="manfiet-button manfiet-button-primary manfiet-button-sm">
                                                    {__('Save', 'manfi-expense-tracker')}
                                                </button>
                                                <button type="button" onClick={cancelEditCategory} className="manfiet-button manfiet-button-secondary manfiet-button-sm">
                                                    {__('Cancel', 'manfi-expense-tracker')}
                                                </button>
                                            </>
                                        ) : (
                                            <>
                                                <button type="button" onClick={() => startEditCategory(category)} className="manfiet-button manfiet-button-info manfiet-button-sm">
                                                    {__('Edit', 'manfi-expense-tracker')}
                                                </button>
                                                <button type="button" onClick={() => askDeleteCategory(category)} className="manfiet-button manfiet-button-danger manfiet-button-sm">
                                                    {__('Delete', 'manfi-expense-tracker')}
                                                </button>
                                            </>
                                        )}
                                    </td>
                                </tr>
                            ))}
                        </tbody>
                    </table>
                </div>
            )}

            {selectedCategory && (
                <ExpenseExplorerPanel
                    title={__('Expenses by Category', 'manfi-expense-tracker') + ': ' + (selectedCategory.display_name || selectedCategory.path_name || selectedCategory.category_name)}
                    filter={{
                        category_id: selectedCategory.id,
                        include_children: true,
                    }}
                />
            )}

            {pendingDeleteCategory && (
                <div className="manfiet-modal-backdrop" role="presentation" onClick={cancelDeleteCategory}>
                    <div className="manfiet-modal" role="dialog" aria-modal="true" aria-labelledby="manfiet-delete-category-title" onClick={(event) => event.stopPropagation()}>
                        <h3 id="manfiet-delete-category-title" className="manfiet-modal-title">{__('Delete Category?', 'manfi-expense-tracker')}</h3>
                        <p className="manfiet-modal-text">
                            {__('Are you sure you want to delete this category?', 'manfi-expense-tracker')}
                            <strong> {pendingDeleteCategory.display_name || pendingDeleteCategory.path_name || pendingDeleteCategory.category_name}</strong>
                        </p>
                        <div className="manfiet-modal-actions">
                            <button type="button" className="manfiet-button manfiet-button-secondary" onClick={cancelDeleteCategory} disabled={isDeleting}>
                                {__('Cancel', 'manfi-expense-tracker')}
                            </button>
                            <button type="button" className="manfiet-button manfiet-button-danger" onClick={() => deleteCategory(pendingDeleteCategory.id)} disabled={isDeleting}>
                                {isDeleting ? __('Deleting...', 'manfi-expense-tracker') : __('Yes, Delete', 'manfi-expense-tracker')}
                            </button>
                        </div>
                    </div>
                </div>
            )}
        </div>
    );
};

export default CategoryManager;
