import { useEffect, useState, Fragment } 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 Link from 'next/link';

import ProtectedRoute from '@/components/ProtectedRoute';
import { Dialog, Transition } from '@headlessui/react';
import { coloredToast } from '@/lib/toast';
import Swal from 'sweetalert2';
import NumberFormatter from '@/lib/ribuan';
import { logActivity } from '@/utils/activityLogger';
import CloseIcon from '@mui/icons-material/Close';

interface Point {
    id: string;
    email: string;
    name: string;
    point: number;
}

interface PointLogItem {
    user_id: {
        email?: string;
        name?: string;
    };
    point_amount: number;
    description: string;
    createdAt: Date;
}

const PointIndex = () => {
    const dispatch = useDispatch();
    useEffect(() => {
        dispatch(setPageTitle('Points'));
    }, []);

    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<Point[]>([]);
    const [totalRecords, setTotalRecords] = useState(0);
    const [search, setSearch] = useState('');

    const [isLoading, setIsLoading] = useState(true); // Add isLoading state
    const [isRequestPoint, setRequestPoint] = useState(false); // Add isLoading state

    const [isLodaingExpire, setIsLodaingExpire] = useState(false);

    const [pointModal, setPointModal] = useState<any>(false);
    const [pointLogModalOpen, setPointLogModalOpen] = useState(false);
    const [selectedPointEmail, setSelectedPointEmail] = useState('');
    const [isLoadingPointLog, setIsLoadingPointLog] = useState(false);
    const [pointLogRecords, setPointLogRecords] = useState<PointLogItem[]>([]);
    const [pointAction, setPointAction] = useState<any>({
        action: '',
        action_amount: 0,
        id: '',
        current_point: 0,
    });

    // 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/users/data?page=${page}&per_page=${pageSize}&sortByPoint=true&email=${search}`, {
                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);
            setIsLoading(false); // Set isLoading to false even if there's an error
        }
    };

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

    const handleKeypress = (event: React.KeyboardEvent<HTMLInputElement>) => {
        if (event.keyCode === 13) {
            if (page !== 1) {
                setPage(1);
            } else {
                fetchData();
            }
        }
    };
    const addPoint = (id: string, point: number) => {
        setPointAction({
            action: 'add',
            action_amount: 0,
            id,
            current_point: point,
        });
        setPointModal(true);
    };
    const deductPoint = (id: string, point: number) => {
        setPointAction({
            action: 'deduct',
            action_amount: 0,
            id,
            current_point: point,
        });
        setPointModal(true);
    };
    const changeValue = (value: any) => {
        setPointAction((prev: any) => {
            return {
                ...prev,
                action_amount: value,
            };
        });
    };
    const savePointAction = async () => {
        setRequestPoint(true);
        if (pointAction.action === 'deduct' && pointAction.action_amount > pointAction.current_point) {
            coloredToast('warning', 'point cannot under 0');
            setRequestPoint(false);
            return;
        }
        if (pointAction.action_amount <= 0) {
            coloredToast('warning', 'point amount is required');
            setRequestPoint(false);
            return;
        }

        try {
            const payload = {
                point_request: parseInt(pointAction.action_amount),
            };
            const api_url = process.env.API_URL;
            const fetchUrl = pointAction.action === 'add' ? `${api_url}api/point/add/${pointAction.id}` : `${api_url}api/point/deduct/${pointAction.id}`;
            const response = await fetch(fetchUrl, {
                method: 'PATCH',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify(payload),
                credentials: 'include', // Include this option
            });

            if (!response.ok) {
                const res = await response.json();
                throw new Error(res.message);
            }
        } catch (error: any) {
            coloredToast('warning', error.message || 'something went wrong');
        }
        coloredToast('success', 'point adjusted successfully');
        const finalPoint = pointAction.action === 'add' ? Number(pointAction.current_point) + Number(pointAction.action_amount) : Number(pointAction.current_point) - Number(pointAction.action_amount);

        await logActivity({
            location: 'Point',
            description: `User ID: ${pointAction.id} | Action: ${pointAction.action} | Amount: ${Number(pointAction.action_amount)} | Point before: ${Number(
                pointAction.current_point
            )} | Point after: ${finalPoint}`,
        });
        setPointModal(false);
        setRequestPoint(false);

        fetchData();
    };

    const handleExpirePoints = () => {
        const currentDate = new Date();
        const expiryDate = new Date('2025-12-31T23:59:59');

        if (currentDate > expiryDate) {
            Swal.fire({
                icon: 'warning',
                title: 'Are you sure?',
                text: "You won't be able to revert this!",
                showCancelButton: true,
                confirmButtonText: 'Reset Points',
                padding: '2em',
                customClass: {
                    container: 'sweet-alerts',
                },
            }).then(async (result) => {
                if (result.value) {
                    setIsLodaingExpire(true);
                    try {
                        const api_url = process.env.API_URL;
                        const response = await fetch(`${api_url}api/point/expire`, {
                            method: 'POST',
                            headers: { 'Content-Type': 'application/json' },
                            credentials: 'include',
                        });
                        if (!response.ok) {
                            const res = await response.json();
                            throw new Error(res.message);
                        }
                        Swal.fire({
                            title: 'Reset Points!',
                            text: 'All points have been reset.',
                            icon: 'success',
                            customClass: {
                                container: 'sweet-alerts',
                            },
                        });
                        fetchData();
                    } catch (error: any) {
                        coloredToast('warning', error.message || 'something went wrong');
                    }
                    setIsLodaingExpire(false);
                }
            });
        } else {
            coloredToast('warning', 'Points cannot be expired until after December 31, 2025.');
        }
    };

    const fetchPointLogsByEmail = async (email: string) => {
        setSelectedPointEmail(email);
        setPointLogModalOpen(true);
        setIsLoadingPointLog(true);
        setPointLogRecords([]);

        try {
            const api_url = process.env.API_URL;
            const response = await fetch(`${api_url}api/point/logs?page=1&per_page=100&email=${encodeURIComponent(email)}`, {
                method: 'GET',
                headers: {
                    'Content-Type': 'application/json',
                },
                credentials: 'include',
            });
            const data = await response.json();
            setPointLogRecords(Array.isArray(data?.data) ? data.data : []);
        } catch (error) {
            console.error('Error fetching point logs:', error);
            setPointLogRecords([]);
        } finally {
            setIsLoadingPointLog(false);
        }
    };

    return (
        <>
            {isMounted && (
                    <>
                        <div className="mb-3">
                            <ul className="flex space-x-2 rtl:space-x-reverse">
                                <li>
                                    <span>Points</span>
                                </li>
                            </ul>
                        </div>
                        {/* table of points  */}

                        <div className="flex flex-wrap items-center justify-between gap-4">
                            <div className="flex items-center gap-2">
                                <Link href="/points/log" className="btn btn-outline-success gap-2">
                                    <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none">
                                        <path
                                            d="M2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2"
                                            stroke="currentColor"
                                            strokeWidth="1.5"
                                            strokeLinecap="round"
                                        />
                                        <path opacity="0.5" d="M12 9V13H16" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
                                        <circle opacity="0.5" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeDasharray="0.5 3.5" />
                                    </svg>
                                    Point Logs
                                </Link>
                            </div>
                            <div className="flex w-full flex-col gap-4 sm:w-auto sm:flex-row sm:items-center sm:gap-3">
                                <div>
                                    <button className="btn btn-outline-warning" onClick={handleExpirePoints}>
                                        {isLodaingExpire ? (
                                            <>
                                                <span className="inline-block h-5 w-5 animate-spin rounded-full border-2 border-warning border-l-transparent align-middle ltr:mr-4 rtl:ml-4"></span>
                                                <span className="inline-block">Resetting Points</span>
                                            </>
                                        ) : (
                                            'Expire Points'
                                        )}
                                    </button>
                                </div>
                                <div>
                                    <Link href="/points/setting">
                                        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
                                            <circle cx="12" cy="12" r="3" stroke="currentColor" strokeWidth="1.5" />
                                            <path
                                                opacity="0.5"
                                                d="M13.7654 2.15224C13.3978 2 12.9319 2 12 2C11.0681 2 10.6022 2 10.2346 2.15224C9.74457 2.35523 9.35522 2.74458 9.15223 3.23463C9.05957 3.45834 9.0233 3.7185 9.00911 4.09799C8.98826 4.65568 8.70226 5.17189 8.21894 5.45093C7.73564 5.72996 7.14559 5.71954 6.65219 5.45876C6.31645 5.2813 6.07301 5.18262 5.83294 5.15102C5.30704 5.08178 4.77518 5.22429 4.35436 5.5472C4.03874 5.78938 3.80577 6.1929 3.33983 6.99993C2.87389 7.80697 2.64092 8.21048 2.58899 8.60491C2.51976 9.1308 2.66227 9.66266 2.98518 10.0835C3.13256 10.2756 3.3397 10.437 3.66119 10.639C4.1338 10.936 4.43789 11.4419 4.43786 12C4.43783 12.5581 4.13375 13.0639 3.66118 13.3608C3.33965 13.5629 3.13248 13.7244 2.98508 13.9165C2.66217 14.3373 2.51966 14.8691 2.5889 15.395C2.64082 15.7894 2.87379 16.193 3.33973 17C3.80568 17.807 4.03865 18.2106 4.35426 18.4527C4.77508 18.7756 5.30694 18.9181 5.83284 18.8489C6.07289 18.8173 6.31632 18.7186 6.65204 18.5412C7.14547 18.2804 7.73556 18.27 8.2189 18.549C8.70224 18.8281 8.98826 19.3443 9.00911 19.9021C9.02331 20.2815 9.05957 20.5417 9.15223 20.7654C9.35522 21.2554 9.74457 21.6448 10.2346 21.8478C10.6022 22 11.0681 22 12 22C12.9319 22 13.3978 22 13.7654 21.8478C14.2554 21.6448 14.6448 21.2554 14.8477 20.7654C14.9404 20.5417 14.9767 20.2815 14.9909 19.902C15.0117 19.3443 15.2977 18.8281 15.781 18.549C16.2643 18.2699 16.8544 18.2804 17.3479 18.5412C17.6836 18.7186 17.927 18.8172 18.167 18.8488C18.6929 18.9181 19.2248 18.7756 19.6456 18.4527C19.9612 18.2105 20.1942 17.807 20.6601 16.9999C21.1261 16.1929 21.3591 15.7894 21.411 15.395C21.4802 14.8691 21.3377 14.3372 21.0148 13.9164C20.8674 13.7243 20.6602 13.5628 20.3387 13.3608C19.8662 13.0639 19.5621 12.558 19.5621 11.9999C19.5621 11.4418 19.8662 10.9361 20.3387 10.6392C20.6603 10.4371 20.8675 10.2757 21.0149 10.0835C21.3378 9.66273 21.4803 9.13087 21.4111 8.60497C21.3592 8.21055 21.1262 7.80703 20.6602 7C20.1943 6.19297 19.9613 5.78945 19.6457 5.54727C19.2249 5.22436 18.693 5.08185 18.1671 5.15109C17.9271 5.18269 17.6837 5.28136 17.3479 5.4588C16.8545 5.71959 16.2644 5.73002 15.7811 5.45096C15.2977 5.17191 15.0117 4.65566 14.9909 4.09794C14.9767 3.71848 14.9404 3.45833 14.8477 3.23463C14.6448 2.74458 14.2554 2.35523 13.7654 2.15224Z"
                                                stroke="currentColor"
                                                strokeWidth="1.5"
                                            />
                                        </svg>
                                    </Link>
                                </div>
                                <div className="relative">
                                    <input
                                        type="text"
                                        placeholder="Search by email"
                                        className="peer form-input py-2 ltr:pr-11 rtl:pl-11"
                                        value={search}
                                        onChange={(e) => setSearch(e.target.value)}
                                        onKeyDown={handleKeypress}
                                    />
                                    <div className="absolute top-1/2 -translate-y-1/2 peer-focus:text-primary ltr:right-[11px] rtl:left-[11px]">
                                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                            <circle cx="11.5" cy="11.5" r="9.5" stroke="currentColor" strokeWidth="1.5" opacity="0.5"></circle>
                                            <path d="M18.5 18.5L22 22" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"></path>
                                        </svg>
                                    </div>
                                </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"
                                            columns={[
                                                {
                                                    accessor: 'no',
                                                    render: (_, index) => index + 1,
                                                },
                                                {
                                                    accessor: 'email',
                                                    render: ({ email }) => (
                                                        <button
                                                            type="button"
                                                            className="font-semibold  hover:underline"
                                                            onClick={() => fetchPointLogsByEmail(email)}
                                                        >
                                                            {email}
                                                        </button>
                                                    ),
                                                },

                                                {
                                                    accessor: 'name',
                                                },
                                                {
                                                    accessor: 'point',
                                                    render: ({ point }) => <>{point > 0 ? point.toLocaleString('id-ID') : 0}</>,
                                                },

                                                {
                                                    accessor: 'action',
                                                    title: 'Actions',
                                                    textAlign: 'center',
                                                    render: ({ id, point }) => (
                                                        <div className="mx-auto flex w-max items-center gap-4">
                                                            <button type="button" onClick={() => addPoint(id, point)} className="btn btn-sm btn-outline-primary">
                                                                Add Point
                                                            </button>
                                                            <button type="button" onClick={() => deductPoint(id, point)} className="btn btn-sm btn-outline-danger ">
                                                                Deduct Point
                                                            </button>
                                                        </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} `}
                                        />
                                    )}
                                </div>
                            </div>
                        </div>
                        {pointLogModalOpen && (
                            <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4" onClick={() => setPointLogModalOpen(false)}>
                                <div className="max-h-[90vh] w-full max-w-6xl overflow-y-auto rounded-lg bg-white p-4 shadow-xl dark:bg-[#1e293b]" onClick={(e) => e.stopPropagation()}>
                                    <div className="mb-4 flex items-center justify-between">
                                        <h3 className="text-lg font-semibold">Point Logs: {selectedPointEmail}</h3>
                                        <button type="button"  onClick={() => setPointLogModalOpen(false)}>
                                        <CloseIcon />
                                        </button>
                                    </div>

                                    <DataTable
                                        className="table-hover whitespace-nowrap"
                                        records={pointLogRecords}
                                        minHeight={220}
                                        noRecordsText={isLoadingPointLog ? 'Memuat point logs...' : 'No data found'}
                                        columns={[
                                            {
                                                accessor: 'email',
                                                render: ({ user_id }) => <div>{user_id?.email || '-'}</div>,
                                            },
                                            {
                                                accessor: 'name',
                                                render: ({ user_id }) => <div>{user_id?.name || '-'}</div>,
                                            },
                                            {
                                                accessor: 'point_amount',
                                                render: ({ point_amount }) => <>{point_amount.toLocaleString('id-ID')}</>,
                                            },
                                            {
                                                accessor: 'description',
                                            },
                                            {
                                                accessor: 'activity',
                                                render: ({ createdAt }) => {
                                                    const createdAtDate = new Date(createdAt);
                                                    return (
                                                        <div className="text-xs">
                                                            <div>{createdAtDate.toLocaleDateString('id-ID')}</div>
                                                            <div>{createdAtDate.toLocaleTimeString('id-ID')}</div>
                                                        </div>
                                                    );
                                                },
                                            },
                                        ]}
                                    />
                                </div>
                            </div>
                        )}
                        <Transition appear show={pointModal} as={Fragment}>
                            <Dialog as="div" open={pointModal} onClose={() => setPointModal(false)} className="relative z-50">
                                <Transition.Child
                                    as={Fragment}
                                    enter="ease-out duration-300"
                                    enterFrom="opacity-0"
                                    enterTo="opacity-100"
                                    leave="ease-in duration-200"
                                    leaveFrom="opacity-100"
                                    leaveTo="opacity-0"
                                >
                                    <div className="fixed inset-0 bg-[black]/60" />
                                </Transition.Child>
                                <div className="fixed inset-0 overflow-y-auto">
                                    <div className="flex min-h-full items-center justify-center px-4 py-8">
                                        <Transition.Child
                                            as={Fragment}
                                            enter="ease-out duration-300"
                                            enterFrom="opacity-0 scale-95"
                                            enterTo="opacity-100 scale-100"
                                            leave="ease-in duration-200"
                                            leaveFrom="opacity-100 scale-100"
                                            leaveTo="opacity-0 scale-95"
                                        >
                                            <Dialog.Panel className="panel w-full max-w-lg overflow-hidden rounded-lg border-0 p-0 text-black dark:text-white-dark">
                                                <button
                                                    type="button"
                                                    onClick={() => setPointModal(false)}
                                                    className="absolute top-4 text-gray-400 outline-none hover:text-gray-800 dark:hover:text-gray-600 ltr:right-4 rtl:left-4"
                                                >
                                                    <svg
                                                        xmlns="http://www.w3.org/2000/svg"
                                                        width="24"
                                                        height="24"
                                                        viewBox="0 0 24 24"
                                                        fill="none"
                                                        stroke="currentColor"
                                                        strokeWidth="1.5"
                                                        strokeLinecap="round"
                                                        strokeLinejoin="round"
                                                    >
                                                        <line x1="18" y1="6" x2="6" y2="18"></line>
                                                        <line x1="6" y1="6" x2="18" y2="18"></line>
                                                    </svg>
                                                </button>
                                                <div className="bg-[#fbfbfb] py-3 text-lg font-medium dark:bg-[#121c2c] ltr:pl-5 ltr:pr-[50px] rtl:pl-[50px] rtl:pr-5">
                                                    {pointAction.action === 'add' ? 'Add Point' : 'Deduct Point'}
                                                </div>
                                                <div className="p-5">
                                                    <form>
                                                        <div className="mb-5">
                                                            <label htmlFor="name">Current Point</label>
                                                            <div className="flex">
                                                                <div className="font-semibold">{pointAction.current_point.toLocaleString('id-ID')}</div>
                                                                {pointAction.action && pointAction.action_amount > 0 && pointAction.action === 'add' && (
                                                                    <div className="ms-2 font-semibold text-success">
                                                                        + {parseInt(pointAction.action_amount).toLocaleString('id-ID')} ={' '}
                                                                        {(parseInt(pointAction.current_point) + parseInt(pointAction.action_amount)).toLocaleString('id-ID')} point
                                                                    </div>
                                                                )}
                                                                {pointAction.action && pointAction.action_amount > 0 && pointAction.action !== 'add' && (
                                                                    <div className="ms-2 font-semibold text-danger">
                                                                        - {parseInt(pointAction.action_amount).toLocaleString('id-ID')} ={' '}
                                                                        {(parseInt(pointAction.current_point) - parseInt(pointAction.action_amount)).toLocaleString('id-ID')} point
                                                                    </div>
                                                                )}
                                                            </div>
                                                        </div>
                                                        <div className="mb-5">
                                                            <label htmlFor="name">Point Amount</label>
                                                            <NumberFormatter
                                                                placeholder="Enter Point Amount"
                                                                className="form-input"
                                                                value={pointAction.action_amount}
                                                                onChange={(value: any) => changeValue(value.toString())}
                                                            />
                                                        </div>

                                                        <div className="mt-8 flex items-center justify-end">
                                                            <button type="button" className="btn btn-outline-danger" onClick={() => setPointModal(false)}>
                                                                Cancel
                                                            </button>
                                                            <button type="button" disabled={isRequestPoint} className="btn btn-primary ltr:ml-4 rtl:mr-4" onClick={savePointAction}>
                                                                {pointAction.action === 'add' ? 'Add' : 'Deduct'}
                                                            </button>
                                                        </div>
                                                    </form>
                                                </div>
                                            </Dialog.Panel>
                                        </Transition.Child>
                                    </div>
                                </div>
                            </Dialog>
                        </Transition>
                    </>
                )}
        </>
    );
};

export default PointIndex;
