import { useEffect, useState, Fragment, useRef } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import 'mantine-datatable/styles.css';
import { DataTable } from '@/components/Shared/DataTable';

import { setPageTitle } from '../../../store/themeConfigSlice';
import { coloredToast, progressToast } from '@/lib/toast';

import Flatpickr from 'react-flatpickr';
import 'flatpickr/dist/flatpickr.css';

interface BackInStock {
    id: string;
    phone: string;
    items: {
        product: {
            product_title: string;
            product_items: any;
            product_qty: number;
        };
        attributeSelected: any;
    };
    is_sent: boolean;
    createdAt: Date;
}

function formatDate(date: Date): string {
    const dateObj = new Date(date);
    const year = dateObj.getFullYear();
    const month = String(dateObj.getMonth() + 1).padStart(2, '0');
    const day = String(dateObj.getDate()).padStart(2, '0');
    return `${year}-${month}-${day}`;
}

const BackInStockIndex = () => {
    const dispatch = useDispatch();
    useEffect(() => {
        dispatch(setPageTitle('Back In Stock'));
    }, []);

    const [isMounted, setIsMounted] = useState(false);

    useEffect(() => {
        setIsMounted(true);
    }, []);

    const [page, setPage] = useState(1);
    const PAGE_SIZES = [5, 10, 20, 30, 50, 100];
    const [pageSize, setPageSize] = useState(PAGE_SIZES[0]);
    const [records, setRecords] = useState<BackInStock[]>([]);
    const [totalRecords, setTotalRecords] = useState(0);
    const [search, setSearch] = useState('');
    const [isLoading, setIsLoading] = useState(true); // Add isLoading state
    const [bulkData, setBulkData] = useState<any>([]);
    const [isBulkButton, setIsBulkButton] = useState(false);
    const [isErrorData, setIsErrorData] = useState<any>([]);
    const [isLoadingDownload, setIsLoadingDownload] = useState(false);
    const [appliedFilter, setAppliedFilter] = useState({
        date_range: '',
    });
    const [isFiltered, setIsFiltered] = useState(false);
    // Fetch data from API
    const fetchData = async () => {
        setIsLoading(true); // Set isLoading to true before fetching data
        try {
            const api_url = process.env.API_URL;
            const response = await fetch(`${api_url}api/back-in-stock/list?page=${page}&per_page=${pageSize}&dateRange=${appliedFilter.date_range}`, {
                method: 'GET',
                headers: {
                    'Content-Type': 'application/json',
                },
                credentials: 'include', // Include this option
            });
            const data = await response.json();

            setPage(data.currentPage);
            setTotalRecords(data.totalData);
            setRecords(data.data);

            setIsLoading(false); // Set isLoading to false after data is fetched
        } catch (error) {
            console.error('Error fetching data:', error);
        } finally {
            setIsLoading(false);
        }
    };

    useEffect(() => {
        fetchData();
    }, [page, pageSize, search]);

    useEffect(() => {
        setIsLoadingDownload(false);
    }, [isLoading]);

    const clearFlatpickr = useRef<any>(null);

    const removeFilter = () => {
        setAppliedFilter({
            ...appliedFilter,
            date_range: '',
        });
        if (clearFlatpickr.current) {
            clearFlatpickr.current.flatpickr.clear();
        }
        setIsFiltered(false);
    };

    useEffect(() => {
        fetchData();
    }, [appliedFilter.date_range]);

    const sendWhatsapp = async (id: string) => {
        try {
            const api_url = process.env.API_URL;
            const response = await fetch(`${api_url}api/back-in-stock/send-wa/${id}`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                credentials: 'include', // Include this option
            });

            if (!response.ok) {
                throw new Error('Whatsapp notification fail');
            }
            fetchData();

            coloredToast('success', 'Whatsapp notification sent successfully');
        } catch (e: any) {
            coloredToast('warning', e.message);
        }
    };

    async function handleDownloadExcel(data: any) {
        const XLSX = await import('xlsx');
        const workbook = XLSX.utils.book_new();
        const worksheet = XLSX.utils.json_to_sheet(data);

        XLSX.utils.book_append_sheet(workbook, worksheet, 'Back in Stock Cart');

        XLSX.writeFile(workbook, 'Back in Stock Cart.xlsx', { compression: true });
    }

    const handleDownload = async () => {
        setIsLoadingDownload(true);
        let allData = [];
        const api_url = process.env.API_URL;
        const url = appliedFilter.date_range ? `${api_url}api/back-in-stock/download-list?dateRange=${appliedFilter.date_range}` : `${api_url}api/back-in-stock/download-list`;

        const response = await fetch(url, {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json',
            },
            credentials: 'include',
        });
        allData = await response.json();
        const mappingBackinStock = allData.data.map((data: any) => {
            const isSent = data.is_sent ? 'Sent Notification' : 'Not Sent Notification';
            const phone = data.phone;
            const created_at = data.createdAt;
            const items_name = data.items.product.product_title;
            const items_qty = data.items.product.product_qty;

            return {
                phone,
                items_name,
                items_qty,
                created_at,
                isSent,
            };
        });

        handleDownloadExcel(mappingBackinStock);
        setIsLoadingDownload(false);
    };

    const checkQty = (items: any) => {
        if (!items || !items.attributeSelected || !items.product) {
            return 0;
        }

        const allAttributesFilled = items.attributeSelected.every((attribute: any) => attribute.values);

        let totalQty;

        if (items.product.product_items.length > 0) {
            if (allAttributesFilled) {
                // Sum qty of product_items matching attributeSelected
                totalQty = items.product.product_items.reduce((sum: number, item: any) => {
                    const isMatch = items.attributeSelected.every((attr: any) => {
                        return item.attributes.some((attrItem: any) => {
                            if (attrItem.name === attr.name) {
                                if (attrItem.value.label) {
                                    return attrItem.value.label === attr.values; // Compare with label if it exists
                                } else {
                                    return attrItem.value === attr.values; // Compare with direct value
                                }
                            }
                            return false;
                        });
                    });
                    return isMatch ? sum + item.qty : sum;
                }, 0);
            }
        } else {
            totalQty = items.product.product_qty;
        }
        return totalQty;
    };

    const sendBulkNotification = async (data: any, delayMs: number) => {
        try {
            const api_url = process.env.API_URL;
            let count = 0;

            progressToast(`Sending Message`, count, data.length);

            for (const item of data) {
                await delay(delayMs);
                const response = await fetch(`${api_url}api/back-in-stock/send-wa/${item.id}`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    credentials: 'include',
                });
                if (!response.ok) {
                    setIsErrorData(item.id);
                    coloredToast('warning', `Some Message is not send`);
                } else {
                    count++;
                    progressToast(`Sending Message `, count, data.length);
                }
            }

            fetchData();
            setBulkData([]);
            setIsBulkButton(false);
            if (isErrorData.length > 0) {
                coloredToast('warning', `Some Message is not send`);
            } else {
                coloredToast('success', 'All Whatsapp notifications has been sent');
            }
        } catch (e: any) {
            coloredToast('warning', e.message);
        }
    };

    const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));

    return (
        <>
                {isMounted && (
                    <>
                        <div className="mb-3">
                            <div className="flex-between mb-4 flex">
                                <div className="w-1/2">Back in Stock</div>
                            </div>
                            <div className="flex w-full flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
                                <button className="btn btn-sm btn-outline-success flex items-center justify-center" onClick={handleDownload} disabled={isLoadingDownload}>
                                    {isLoadingDownload ? (
                                        <>
                                            <div className="h-4 w-4 animate-spin rounded-full border-2 border-solid border-current border-r-transparent"></div>
                                            <span className="ml-2">Downloading..</span>
                                        </>
                                    ) : (
                                        'Download Back in Stock'
                                    )}
                                </button>

                                {isBulkButton && (
                                    <button type="button" className="btn btn-outline-info" onClick={() => sendBulkNotification(bulkData, 500)}>
                                        Blast Message
                                    </button>
                                )}

                                <div className="flex items-center justify-end gap-3">
                                    {isFiltered && (
                                        <div className="badge badge-outline-danger flex min-w-max cursor-pointer items-center px-3" onClick={() => removeFilter()}>
                                            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
                                                <path d="M14.5 9.50002L9.5 14.5M9.49998 9.5L14.5 14.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
                                            </svg>
                                            <span className="ml-1">Remove Filter</span>
                                        </div>
                                    )}

                                    <Flatpickr
                                        options={{
                                            mode: 'range',
                                            dateFormat: 'Y-m-d',
                                            position: 'auto left',
                                        }}
                                        className="form-input"
                                        placeholder="Select Date Range"
                                        onChange={(dateRange) => {
                                            if (Array.isArray(dateRange) && dateRange.length === 2) {
                                                const startDate = formatDate(dateRange[0]);
                                                const endDate = formatDate(dateRange[1]);
                                                setAppliedFilter({
                                                    ...appliedFilter,
                                                    date_range: `${startDate} to ${endDate}`,
                                                });
                                                setIsFiltered(true);
                                            }
                                            fetchData();
                                        }}
                                        ref={clearFlatpickr}
                                    />
                                </div>
                            </div>
                        </div>

                        <div className="panel mt-5  overflow-hidden border-0 px-0 pt-0">
                            <div className="user-table">
                                <div className="datatables pagination-padding">
                                    {isLoading ? (
                                        // Show loading indicator here
                                        <div className="flex justify-center py-4 text-center">
                                            <svg
                                                viewBox="0 0 24 24"
                                                width="24"
                                                height="24"
                                                stroke="currentColor"
                                                strokeWidth="1.5"
                                                fill="none"
                                                strokeLinecap="round"
                                                strokeLinejoin="round"
                                                className="h-5 w-5 animate-spin text-white-dark"
                                            >
                                                <line x1="12" y1="2" x2="12" y2="6"></line>
                                                <line x1="12" y1="18" x2="12" y2="22"></line>
                                                <line x1="4.93" y1="4.93" x2="7.76" y2="7.76"></line>
                                                <line x1="16.24" y1="16.24" x2="19.07" y2="19.07"></line>
                                                <line x1="2" y1="12" x2="6" y2="12"></line>
                                                <line x1="18" y1="12" x2="22" y2="12"></line>
                                                <line x1="4.93" y1="19.07" x2="7.76" y2="16.24"></line>
                                                <line x1="16.24" y1="7.76" x2="19.07" y2="4.93"></line>
                                            </svg>
                                            <span className="ms-3">Please wait, we&apos;re still working to load the data...</span>
                                        </div>
                                    ) : (
                                        <DataTable
                                            className="table-hover whitespace-nowrap"
                                            records={records}
                                            minHeight={250}
                                            noRecordsText="No data found"
                                            selectedRecords={bulkData}
                                            onSelectedRecordsChange={(selectedRecords) => {
                                                setBulkData(selectedRecords);
                                                setIsBulkButton(selectedRecords.length > 0);
                                            }}
                                            isRecordSelectable={(record) => {
                                                const totalQty = checkQty(record.items);
                                                return !record.is_sent && record.phone !== '' && totalQty > 0;
                                            }}
                                            columns={[
                                                {
                                                    accessor: 'phone',
                                                    render: ({ phone }) => <div className="font-semibold">{phone || ''}</div>,
                                                },
                                                {
                                                    accessor: 'items',
                                                    render: ({ items }) => {
                                                        const totalQty = checkQty(items);
                                                        return (
                                                            <>
                                                                <div>{items.product?.product_title || ''} </div>
                                                                <div>
                                                                    {items.attributeSelected &&
                                                                        items.attributeSelected.length > 0 &&
                                                                        items.attributeSelected
                                                                            .filter((attribute: any) => attribute.values) // Filter out attributes with empty values
                                                                            .map((attribute: any) => `${attribute.name}: ${attribute.values}`)
                                                                            .join(', ')}{' '}
                                                                </div>
                                                                {totalQty > 0 ? <div className="badge w-fit text-success">in stock</div> : <div className="badge w-fit text-danger">out of stock</div>}
                                                            </>
                                                        );
                                                    },
                                                },
                                                {
                                                    accessor: 'action',
                                                    title: 'Actions',
                                                    render: ({ id, phone, is_sent, items }) => {
                                                        const totalQty = checkQty(items);

                                                        return (
                                                            <>
                                                                {phone && !is_sent && totalQty > 0 && (
                                                                    <>
                                                                        <button type="button" className="btn btn-sm btn-outline-success " onClick={() => sendWhatsapp(id)}>
                                                                            <svg width="15" height="15" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                                                                <path
                                                                                    d="M16.1007 13.359L16.5562 12.9062C17.1858 12.2801 18.1672 12.1515 18.9728 12.5894L20.8833 13.628C22.1102 14.2949 22.3806 15.9295 21.4217 16.883L20.0011 18.2954C19.6399 18.6546 19.1917 18.9171 18.6763 18.9651M4.00289 5.74561C3.96765 5.12559 4.25823 4.56668 4.69185 4.13552L6.26145 2.57483C7.13596 1.70529 8.61028 1.83992 9.37326 2.85908L10.6342 4.54348C11.2507 5.36691 11.1841 6.49484 10.4775 7.19738L10.1907 7.48257"
                                                                                    stroke="currentColor"
                                                                                    strokeWidth="1.5"
                                                                                />
                                                                                <path
                                                                                    opacity="0.5"
                                                                                    d="M18.6763 18.9651C17.0469 19.117 13.0622 18.9492 8.8154 14.7266C4.81076 10.7447 4.09308 7.33182 4.00293 5.74561"
                                                                                    stroke="currentColor"
                                                                                    strokeWidth="1.5"
                                                                                />
                                                                                <path
                                                                                    opacity="0.5"
                                                                                    d="M16.1007 13.3589C16.1007 13.3589 15.0181 14.4353 12.0631 11.4971C9.10807 8.55886 10.1907 7.48242 10.1907 7.48242"
                                                                                    stroke="currentColor"
                                                                                    strokeWidth="1.5"
                                                                                    strokeLinecap="round"
                                                                                />
                                                                            </svg>
                                                                        </button>
                                                                    </>
                                                                )}
                                                                {is_sent && <div className="badge w-fit bg-success"> Notification has been sent</div>}
                                                            </>
                                                        );
                                                    },
                                                },
                                            ]}
                                            highlightOnHover
                                            totalRecords={totalRecords}
                                            recordsPerPage={pageSize}
                                            page={page}
                                            onPageChange={(p) => setPage(p)}
                                            recordsPerPageOptions={PAGE_SIZES}
                                            onRecordsPerPageChange={setPageSize}
                                            paginationText={({ from, to, totalRecords }) => `Showing  ${from} to ${to} of ${totalRecords} data`}
                                        />
                                    )}
                                </div>
                            </div>
                        </div>
                    </>
                )}
        </>
    );
};

export default BackInStockIndex;
