import {useCallback, useEffect, useState} from "@wordpress/element";
import {__, sprintf} from "@wordpress/i18n";
import ContentBodyInner from "../../../containers/content/body-inner";
import ContentLoading from "../../../containers/content/loading";
import Container from "../../../containers/content/container";
import ContentFooterLayout from "../../../containers/content/footer/_components/layout";
import Filters from "./filters";
import Table from "./table";
import Drawer from "./drawer";
import {getVisibleColumns} from "./_components/configure-columns-button";
import {GetLeadsColumns, GetLeads} from "../../../../../../rest/leads";
import {handleError} from "../../../../../../helpers/notifications";
import Button from "../../../../../button/_";

export default function Leads({notifications}) {
    const [loading, setLoading] = useState(0);
    const [isDataFetched, setIsDataFetched] = useState(false);
    const [counts, setCounts] = useState({
        leads: 0,
        visitors: 0,
        all: 0
    });
    const [type, setType] = useState('leads');
    const [filters, setFilters] = useState({});
    const [pagination, setPagination] = useState({
        page: 1,
        perPage: LimbChatbot.screen_options?.lbaic_items_per_page || 10,
        total: 0,
    });
    const [selectedLeads, setSelectedLeads] = useState([]);
    const [selectAll, setSelectAll] = useState(false);
    const [isAllSelected, setIsAllSelected] = useState(false);
    const [selectedLead, setSelectedLead] = useState(null);
    const [isDrawerOpen, setIsDrawerOpen] = useState(false);
    const [allColumns, setAllColumns] = useState([]);
    const [visibleColumns, setVisibleColumns] = useState([]);
    const [leadsData, setLeadsData] = useState([]);

    // Status filter options
    const statusFilterOptions = [
        {label: __("All Status", 'limb-chatbot'), value: null},
        // TODO: Add status options from data
    ];

    // Source filter options
    const sourceFilterOptions = [
        {label: __("All Sources", 'limb-chatbot'), value: null},
        // TODO: Add source options from data
    ];

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

    useEffect(() => {
        if (allColumns.length) {
            setVisibleColumns(getVisibleColumns(allColumns));
        }
    }, [allColumns]);

    const getLeadsColumns = async () => {
        setLoading(prev => prev + 1);
        try {
            const res = await GetLeadsColumns();
            if (res?.items) {
                // Add fixed columns: Status (first), then dynamic columns, then Source and Captured
                // const statusColumn = {
                //     id: 'status',
                //     label: __("Status", 'limb-chatbot'),
                //     fixed: true,
                //     alwaysVisible: true
                // };

                const dynamicColumns = res.items.map(col => ({
                    id: col.field_key,
                    label: col.label,
                    field_id: col.id,
                    data_type: col.data_type
                }));

                const fixedColumns = [
                    {id: 'source', label: __("Source", 'limb-chatbot'), fixed: true, alwaysVisible: true},
                    {id: 'captured', label: __("Captured", 'limb-chatbot'), fixed: true, alwaysVisible: true}
                ];

                setAllColumns([
                    /*statusColumn,*/
                    ...dynamicColumns,
                    ...fixedColumns
                ]);
            }
        } catch (e) {
            handleError(e, notifications.set, {
                title: __("Failed to fetch lead columns.", 'limb-chatbot'),
                description: e.message ? __(e.message, 'limb-chatbot') : __("Please check and try again.", 'limb-chatbot'),
            });
        }
        setLoading(prev => prev - 1);
    };

    const fetchLeads = useCallback(async (page, perPage, params = {}) => {
        setLoading(prev => prev + 1);

        let items, total;
        try {
            // Merge filters with params
            const moreParams = {
                ...filters,
                ...params
            };

            // Remove empty strings, null, and undefined
            const cleanParams = Object.fromEntries(
                Object.entries(moreParams).filter(([_, v]) => v !== '' && v != null)
            );

            const res = await GetLeads({
                page: page,
                per_page: perPage,
                orderby: 'created_at',
                order: 'desc',
                ...cleanParams
            });

            items = res?.items || [];
            total = res?.total || 0;

            // Update counts
            setCounts({
                leads: total,
                visitors: 0,
                all: total
            });
        } catch (e) {
            handleError(e, notifications.set, {
                title: __("Failed to fetch leads.", 'limb-chatbot'),
                description: e.message ? __(e.message, 'limb-chatbot') : __("Please check and try again.", 'limb-chatbot'),
            });
            items = [];
            total = 0;
        }

        setLeadsData(items);
        setPagination(prevState => ({
            ...prevState,
            page: page,
            total: total,
        }));

        setLoading(prev => prev - 1);
        setIsDataFetched(true);
    }, [filters, notifications.set]);

    const filterLeads = useCallback(async (filterParams) => {
        await fetchLeads(1, pagination.perPage, filterParams);
    }, [fetchLeads, pagination.perPage]);

    useEffect(() => {
        if (allColumns.length) {
            fetchLeads(pagination.page, pagination.perPage);
        }
    }, [allColumns]);

    const handleFilterChange = (filterType) => {
        setType(filterType);
        setSelectedLeads([]);
        setSelectAll(false);
        setIsAllSelected(false);
        fetchLeads(1, pagination.perPage);
    };

    const handleConfigureColumnsChange = (columns) => {
        setVisibleColumns(columns);
    };

    const formatLeadDataForTable = (lead) => {
        const row = {id: lead.id};

        // Add status column
        row.status = lead.status || 'new';

        // Map lead_values to their field_keys
        lead.lead_values?.forEach(lv => {
            row[lv.lead_field.field_key] = lv.value;
        });

        // Add fixed columns
        row.source = {
            title: lead.source_title || __("N/A", 'limb-chatbot'),
            type: lead.source_type || __("N/A", 'limb-chatbot')
        };
        row.captured = lead.created_at;

        return row;
    };

    const handleLeadSelect = (leadId) => {
        setSelectedLeads(prev => {
            const newSelected = prev.indexOf(leadId) === -1
                ? [...prev, leadId]
                : prev.filter(item => item !== leadId);

            // Check if all current page items are selected
            const currentPageIds = leadsData.map(lead => lead.id);
            const allPageSelected = currentPageIds.length > 0 &&
                currentPageIds.every(id => newSelected.includes(id));
            setSelectAll(allPageSelected);

            return newSelected;
        });
        setIsAllSelected(false);
    };

    const handleSelectAll = () => {
        if (selectAll) {
            setSelectedLeads([]);
            setSelectAll(false);
            setIsAllSelected(false);
        } else {
            const allIds = leadsData.map(lead => lead.id);
            setSelectedLeads(allIds);
            setSelectAll(true);
            setIsAllSelected(false);
        }
    };

    const handleToggleSelectAll = () => {
        if (isAllSelected) {
            // Clear all selection
            setSelectedLeads([]);
            setSelectAll(false);
            setIsAllSelected(false);
        } else {
            // Select all items (set a flag to select all)
            setIsAllSelected(true);
            setSelectAll(true);
        }
    };

    const handleRowClick = (e, leadId) => {
        if (e.target.closest('.lbaic-settings-checkbox')) {
            return;
        }
        const leadData = leadsData.find(l => l.id === leadId);
        if (leadData) {
            setSelectedLead(leadData);
            setIsDrawerOpen(true);
        }
    };

    const handleCloseDrawer = () => {
        setIsDrawerOpen(false);
        setSelectedLead(null);
    };

    const handleSaveEdit = (editedData) => {
        // TODO: Implement save edit
        setSelectedLead(prev => prev ? {
            ...prev,
            data: {...prev.data, ...editedData}
        } : null);
    };

    const handleDelete = () => {
        // TODO: Implement delete
        handleCloseDrawer();
    };

    return (
        <>
            <ContentBodyInner>
                {!isDataFetched && <ContentLoading/>}
                <Container className="lbaic-settings-leads">
                    <Filters
                        type={type}
                        counts={counts}
                        statusFilterOptions={statusFilterOptions}
                        sourceFilterOptions={sourceFilterOptions}
                        onFilterChange={handleFilterChange}
                        filterLeads={filterLeads}
                        setFilters={setFilters}
                        setSelectedLeads={setSelectedLeads}
                        setSelectAll={setSelectAll}
                        setIsAllSelected={setIsAllSelected}
                        allColumns={allColumns}
                        onConfigureColumnsChange={handleConfigureColumnsChange}
                    />

                    <Table
                        selectedRows={selectedLeads}
                        selectAll={selectAll}
                        onLeadSelect={handleLeadSelect}
                        onSelectAll={handleSelectAll}
                        onRowClick={handleRowClick}
                        allColumns={allColumns}
                        visibleColumns={visibleColumns}
                        tableData={leadsData.map(formatLeadDataForTable)}
                        pagination={pagination}
                        loading={loading > 0}
                        isDataFetched={isDataFetched}
                        _callback={fetchLeads}
                        emptyLabel={__("No leads found.", 'limb-chatbot')}
                        paginationProps={{
                            totalItemsLabel: __("leads", 'limb-chatbot')
                        }}
                    />
                </Container>
            </ContentBodyInner>
            <ContentFooterLayout
                loading={loading > 0}
            >
                {(selectedLeads.length > 0 || isAllSelected) && (
                    <>
                        {/* Show the "Select all X" button when all current page items are selected AND there are more items */}
                        {selectAll && !isAllSelected && pagination.total > leadsData.length && (
                            <Button
                                type="secondary"
                                label={sprintf(__("Select all %d", 'limb-chatbot'), pagination.total)}
                                onClick={handleToggleSelectAll}
                                disabled={loading > 0}
                                className="lbaic-settings-content-footer-actions-in"
                            />
                        )}
                        {/* Show "Clear selection" when all items are selected */}
                        {isAllSelected && (
                            <Button
                                type="secondary"
                                label={__("Clear selection", 'limb-chatbot')}
                                onClick={handleToggleSelectAll}
                                disabled={loading > 0}
                                className="lbaic-settings-content-footer-actions-in"
                            />
                        )}
                        {/* Export button */}
                        <Button
                            type="secondary"
                            label={__("Export", 'limb-chatbot')}
                            icon="download"
                            onClick={() => {}}
                            disabled={loading > 0}
                            className="lbaic-settings-content-footer-actions-in lbaic-settings-content-footer-actions-end"
                        />
                    </>
                )}
            </ContentFooterLayout>

            <Drawer
                lead={selectedLead}
                allColumns={allColumns}
                isOpen={isDrawerOpen}
                onClose={handleCloseDrawer}
                onSaveEdit={handleSaveEdit}
                onDelete={handleDelete}
            />
        </>
    );
}