import {useEffect, useState, useRef} from "@wordpress/element";
import {__, sprintf} from "@wordpress/i18n";
import PopupContainer from "../../../../../../../popups/container";
import Checkbox from "../../../../../../../fields/checkbox";
import {handleError} from "../../../../../../../../helpers/notifications";
import {GetPosts} from "../../../../../../../../rest/wp-objects";
import {getFormatedDate} from "../../../../../../../../../helpers";
import Input from "../../../../../../../fields/input";
import Pagination from "../../../../../../../sections/pagination";
import Description from "../../../../../../../sections/description";

export default function PostSelectionPopup({postType, selectedPostIds, onSave, onCancel, notifications, popupProps}) {
    const [loading, setLoading] = useState(0);
    const [isDataFetched, setIsDataFetched] = useState(false);
    const [posts, setPosts] = useState([]);
    const [pagination, setPagination] = useState({
        page: 1,
        perPage: LimbChatbot.screen_options?.lbaic_items_per_page || 10,
        total: 0,
    });
    const [selectedPosts, setSelectedPosts] = useState(selectedPostIds === 'all' ? [] : (selectedPostIds || []));
    const [isAllSelected, setIsAllSelected] = useState(selectedPostIds === 'all');
    const [searchTerm, setSearchTerm] = useState('');
    const searchDebounce = useRef(null);

    const saveButtonDisabled = loading > 0;

    /**
     * Handle search input change with debounce
     *
     * @param {string} value Search value
     */
    const handleSearchChange = (value) => {
        setSearchTerm(value);

        // Clear any previously set debounce timer
        if (searchDebounce.current) {
            clearTimeout(searchDebounce.current);
        }

        const resetPosts = searchTerm.trim() && !value.trim();

        if (value.trim() || resetPosts) {
            // Set a new debounce timer to delay API call
            searchDebounce.current = setTimeout(() => {
                // Reset pagination to first page when searching
                fetchPosts(1, pagination.perPage, {
                    search: value
                })
            }, 400);
        }
    };

    useEffect(() => {
        fetchPosts(pagination.page, pagination.perPage);
    }, [postType]);

    // Sync state when selectedPostIds prop changes (e.g., when reopening popup)
    useEffect(() => {
        setSelectedPosts(selectedPostIds === 'all' ? [] : (selectedPostIds || []));
        setIsAllSelected(selectedPostIds === 'all');
    }, [selectedPostIds]);

    const fetchPosts = async (page, perPage, params = {}) => {
        setLoading(prev => prev + 1);
        try {
            // Default params
            const reqParams = {
                page: page,
                per_page: perPage,
                status: 'publish',
                orderby: 'title',
                order: 'asc'
            };
            // Add search param
            if (params.search?.trim().length > 0) {
                reqParams.lbaic_title_search = params.search;
            }
            // Get posts
            const res = await GetPosts(postType, reqParams);
            // Update state
            setPosts(res.items || []);
            // Pagination info
            setPagination(prevState => ({
                ...prevState,
                page: page,
                total: res.total,
            }));
        } catch (e) {
            handleError(e, notifications.set, {
                title: __("Failed to get objects.", 'limb-chatbot'),
                description: e.message ? __(e.message, 'limb-chatbot') : __("Please check and try again.", 'limb-chatbot'),
            });
        }
        setIsDataFetched(true);
        setLoading(prev => prev - 1);
    };

    const handlePostToggle = (postId) => {
        if (isAllSelected) {
            // If all are selected, clicking individual posts should deselect all and select only that post
            setIsAllSelected(false);
            setSelectedPosts([postId]);
        } else {
            setSelectedPosts(prev => {
                if (prev.includes(postId)) {
                    return prev.filter(id => id !== postId);
                } else {
                    return [...prev, postId];
                }
            });
        }
    };

    const handleSelectAll = () => {
        // If all posts are selected globally, clicking page checkbox should deselect all
        if (isAllSelected) {
            setIsAllSelected(false);
            setSelectedPosts([]);
            return;
        }

        // Get current page post IDs
        const currentPagePostIds = posts.map(post => post.id);

        // Check if all current page posts are selected
        const allCurrentPageSelected = currentPagePostIds.every(id => selectedPosts.includes(id));

        if (allCurrentPageSelected) {
            // If all current page posts are selected, remove them from selection
            setSelectedPosts(prev => prev.filter(id => !currentPagePostIds.includes(id)));
        } else {
            // If not all current page posts are selected, add all current page posts to selection
            setSelectedPosts(prev => {
                const newSelection = [...prev];
                currentPagePostIds.forEach(id => {
                    if (!newSelection.includes(id)) {
                        newSelection.push(id);
                    }
                });
                return newSelection;
            });
        }
    };

    const handleSave = () => {
        if (saveButtonDisabled) {
            return;
        }
        // If all posts are selected, pass 'all', otherwise pass the selected IDs array
        onSave(isAllSelected ? 'all' : selectedPosts);
    };

    const handleSelectAllPosts = () => {
        if (isAllSelected) {
            // Clear selection
            setIsAllSelected(false);
            setSelectedPosts([]);
        } else {
            // Select all posts
            setIsAllSelected(true);
            setSelectedPosts([]);
        }
    };

    const isAllCurrentPageSelected = posts.length > 0 && posts.every(item => selectedPosts.includes(item.id)) && !isAllSelected;
    const isPartiallySelected = !isAllCurrentPageSelected && !isAllSelected && posts.some(item => selectedPosts.includes(item.id));

    return (
        <PopupContainer
            title={sprintf(__("Select %s", 'limb-chatbot'), postType)}
            description={__("Choose specific items to include in your knowledge.", 'limb-chatbot')}
            close={onCancel}
            loading={loading > 0}
            showLoadingContainer={loading > 0 && !isDataFetched}
            popupClassName='lbaic-settings-mp-sp-popup'
            style={{
                '--lbaic-settings-popup-max-width': '600px',
            }}
            footer={
                <>
                    <button type='button'
                            className='lbaic-settings-button lbaic-settings-button-center lbaic-settings-button-h-40 lbaic-settings-button-secondary'
                            onClick={onCancel}>
                        <span className='lbaic-settings-button-label'>{__("Cancel", 'limb-chatbot')}</span>
                    </button>
                    <button type='button'
                            className={`lbaic-settings-button lbaic-settings-button-center lbaic-settings-button-h-40 lbaic-settings-button-primary${saveButtonDisabled ? ' lbaic-settings-button-disabled' : ''}`}
                            onClick={handleSave}>
                        <span className='lbaic-settings-button-label'>{__("Save", 'limb-chatbot')}</span>
                    </button>
                </>
            }
            {...popupProps}
        >
            <div className='lbaic-settings-column'>
                <div className='lbaic-settings-column-in'>
                    <Input placeholder={__("Search", 'limb-chatbot')} value={searchTerm} setValue={handleSearchChange}
                           disabled={loading > 0}/>
                </div>
            </div>

            {pagination.total > 0 && !searchTerm && (
                <div className='lbaic-settings-column'>
                    <div className='lbaic-settings-column-in'>
                        <button type='button'
                                className='lbaic-settings-button lbaic-settings-button-center lbaic-settings-button-h-40 lbaic-settings-button-secondary'
                                onClick={handleSelectAllPosts}
                                disabled={loading > 0}>
                            <span className='lbaic-settings-button-label'>
                                {isAllSelected
                                    ? __("Clear selection", 'limb-chatbot')
                                    : sprintf(__("Select all %d items", 'limb-chatbot'), pagination.total)}
                            </span>
                        </button>
                    </div>
                </div>
            )}

            {posts.length > 0 ? (
                <div className='lbaic-settings-e-anf-table-wrapper lbaic-settings-scroll-hidden'>
                    <div className="lbaic-settings-scroll-x">
                        <table className='lbaic-settings-e-anf-table'>
                            <thead className='lbaic-settings-e-anf-table-header'>
                            <tr className='lbaic-settings-e-anf-table-header-in'>
                                <th className='lbaic-settings-e-anf-table-header-item lbaic-settings-mp-popup-table-header-checkbox'>
                                    <Checkbox isChecked={isAllCurrentPageSelected || isAllSelected}
                                              isIntermediateChecked={isPartiallySelected}
                                              toggleValue={handleSelectAll}/>
                                </th>
                                <th className='lbaic-settings-e-anf-table-header-item'>
                                    <span
                                        className='lbaic-settings-e-anf-table-header-label'>{__("Title", 'limb-chatbot')}</span>
                                </th>
                                <th className='lbaic-settings-e-anf-table-header-item'>
                                    <span
                                        className='lbaic-settings-e-anf-table-header-label'>{__("Updated", 'limb-chatbot')}</span>
                                </th>
                            </tr>
                            </thead>
                            <tbody className='lbaic-settings-e-anf-table-body'>
                            {posts.map(post => (
                                <tr key={post.id}
                                    className='lbaic-settings-e-anf-table-body-in lbaic-settings-cursor-pointer'
                                    onClick={() => handlePostToggle(post.id)}>
                                    <td className='lbaic-settings-e-anf-table-body-item'>
                                        <Checkbox isChecked={isAllSelected || selectedPosts.includes(post.id)}
                                                  toggleValue={() => handlePostToggle(post.id)}/>
                                    </td>
                                    <td className='lbaic-settings-e-anf-table-body-item'>
                                        <a href={post.link} target="_blank" rel="noopener"
                                           className='lbaic-settings-table-card-body-input-link'
                                           onClick={(e) => e.stopPropagation()}>
                                            <span
                                                className='lbaic-settings-e-anf-table-body-label lbaic-settings-mp-popup-table-body-title-label'
                                                dangerouslySetInnerHTML={{__html: post.title || __("Untitled", 'limb-chatbot')}}/>
                                            <svg
                                                className='lbaic-settings-table-card-body-i lbaic-settings-table-card-body-input-i'
                                                xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24'>
                                                <use href='#lbaic-settings-external-arrow'
                                                     className="lbaic-settings-external-arrow"/>
                                                <use href='#lbaic-external-box'/>
                                            </svg>
                                        </a>
                                    </td>
                                    <td className='lbaic-settings-e-anf-table-body-item'>
                                    <span
                                        className='lbaic-settings-e-anf-table-body-label'>{getFormatedDate(post.modified_gmt, 'MMM D, YYYY')}</span>
                                    </td>
                                </tr>
                            ))}
                            </tbody>
                        </table>
                    </div>
                </div>
            ) : (
                <Description>{searchTerm ? __("No items found matching your search.", 'limb-chatbot') : __("No items available.", 'limb-chatbot')}</Description>
            )}
            <Pagination page={pagination.page} perPage={pagination.perPage} total={pagination.total}
                        goTo={(page) => fetchPosts(page, pagination.perPage)}/>

            {pagination.total > 0 && (
                <Description>
                    {isAllSelected
                        ? sprintf(__("%d items selected", 'limb-chatbot'), pagination.total, postType)
                        : sprintf(__("%d items selected", 'limb-chatbot'), selectedPosts.length, postType)}
                </Description>
            )}
        </PopupContainer>
    );
}

