import {useCallback, useEffect, useRef, useState} from "@wordpress/element";
import {__, sprintf} from "@wordpress/i18n";
import Container from "../../../../containers/content/container";
import ContentBodyInner from "../../../../containers/content/body-inner";
import Card from "./_components/card";
import {CartesianGrid, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis} from 'recharts';
import {handleError} from "../../../../../../../helpers/notifications";
import Button from "../../../../../../button/_";
import ConfigureCardsButton from "./_components/configure-cards-button";
import {GetChatbotAnalytics} from "../../../../../../../rest/chatbot-analytics";
import {getTimezoneOffset} from "../../../../../../../../helpers";

const FILTER_CHARTS_TIMES = [
    {
        label: __("All time", 'limb-chatbot'),
        value: null,
    },
    {
        label: __("Today", 'limb-chatbot'),
        value: 0,
    },
    {
        label: __("7 days", 'limb-chatbot'),
        value: 3600 * 24 * 6,
    },
    {
        label: __("30 days", 'limb-chatbot'),
        value: 3600 * 24 * 29,
    },
    {
        label: __("Year", 'limb-chatbot'),
        value: 3600 * 24 * 364,
    }
];

export const DASHBOARD_CARDS_LOCAL_KEY = 'lbaic.settings.chatbot.dashboard.cards';
export const DASHBOARD_CARDS_COUNT_LOCAL_KEY = 'lbaic.settings.chatbot.dashboard.all-cards-count';

const TIMEZONE_OFFSET = getTimezoneOffset();

/**
 * Get all cards count
 *
 * @return {number}
 */
const getAllCardsCount = () => {
    try {
        const count = localStorage.getItem(DASHBOARD_CARDS_COUNT_LOCAL_KEY);
        if (count) {
            return +count;
        }

        return 8;
    } catch (e) {
        handleError(e);
        return 8;
    }
}

/**
 * Get analytics types
 *
 * @return {string[]|null}
 */
const getCards = () => {
    try {
        const cards = localStorage.getItem(DASHBOARD_CARDS_LOCAL_KEY);
        return cards ? JSON.parse(cards) : [];
    } catch (e) {
        handleError(e);
        return null;
    }
}

/**
 * Get cards count
 * @return {number|*|number}
 */
const getCardsCount = (prev) => {
    return getCards()?.length || prev || getAllCardsCount();
}

/**
 * Get starting_from param
 *
 * @param {null|number} period Period in seconds
 * @return {string|null}
 */
const getStartAt = (period) => {
    if (period === null) {
        return null;
    }

    try {
        const date = new Date(Date.now() - period * 1000);
        date.setHours(0, 0, 0, 0);

        // Last 7 days
        if (period === 3600 * 24 * 6) {
            date.setDate(date.getDate() + 1);
        }
        // Last year
        else if (period === 3600 * 24 * 364) {
            date.setMonth(date.getMonth() + 1);
            // Reset month to the 1st day of the month
            date.setDate(1);
        }

        return date.toISOString().slice(0, 19).replace('T', ' ');
    } catch (e) {
        handleError(e);
        return null;
    }
}

export default function Dashboard({notifications, navigate}) {
    // Actions states
    const [loading, setLoading] = useState(0);
    const [dashboardData, setDashboardData] = useState(null);
    const [selectedCardName, setSelectedCardName] = useState(null);
    const [selectedTimeIndex, setSelectedTimeIndex] = useState(2); // 7 Days

    const previousCardsCountRef = useRef(getAllCardsCount());
    const [shimmerCardsCount, setShimmerCardsCount] = useState(getCardsCount(previousCardsCountRef.current));

    useEffect(() => {
        getDashboardData();
    }, [selectedTimeIndex]);

    /**
     * Get dashboard data
     *
     * @return {Promise<void>}
     */
    const getDashboardData = useCallback(async (params = {}) => {
        // Update shimmer cards count
        setShimmerCardsCount(getCardsCount(previousCardsCountRef.current));
        // Get data from API
        setLoading(prev => prev + 1);
        try {
            const reqParams = {
                ...params,
                utc: TIMEZONE_OFFSET,
            };
            // Start at
            if (!('starting_from' in reqParams)) {
                const startAt = getStartAt(FILTER_CHARTS_TIMES[selectedTimeIndex].value);
                if (startAt) {
                    reqParams.starting_from = startAt;
                }
            }
            const analyticsTypes = getCards();
            if (analyticsTypes?.length) {
                reqParams.include = analyticsTypes;
            }
            // Get data
            const res = await GetChatbotAnalytics('default', reqParams);

            setDashboardData(res);
            // Update selected card state
            if (res?.length > 0) {
                if (!selectedCardName) {
                    setSelectedCardName(res[0].name);
                } else if (!res.find(item => item.name === selectedCardName)) {
                    setSelectedCardName(res[0].name);
                }

                previousCardsCountRef.current = res.length;
            } else {
                previousCardsCountRef.current = getAllCardsCount();
            }
        } catch (e) {
            handleError(e, notifications.set, {
                title: __("Failed to fetch dashboard data.", 'limb-chatbot'),
                description: e.message ? __(e.message, 'limb-chatbot') : __("Please check and try again.", 'limb-chatbot'),
            });
        }
        setLoading(prev => prev - 1);
    }, [selectedTimeIndex, notifications.set]);

    // Get selected card data or use empty data
    const selectedCardData = dashboardData?.find(item => item.name === selectedCardName) || null;
    const chartData = selectedCardData?.analytics;
    const chartLabel = selectedCardData?.label;

    // Create an array for shimmer cards when loading
    const shimmerCards = Array.from({length: shimmerCardsCount}, (_, i) => ({name: `shimmer-${i}`}));

    return (
        <>
            <ContentBodyInner>
                <Container className="lbaic-settings-dashboard">
                    <div className="lbaic-settings-dashboard-actions">
                        <ConfigureCardsButton
                            chatbotUuid="default"
                            notifications={notifications}
                            updateDashboard={getDashboardData}
                        />
                        <div className="lbaic-settings-divider-vertical"/>
                        {FILTER_CHARTS_TIMES.map((item, i) => {
                            const isSelected = selectedTimeIndex === i;

                            return (
                                <Button
                                    key={i}
                                    type={isSelected ? "primary" : "secondary"}
                                    label={item.label}
                                    onClick={() => setSelectedTimeIndex(i)}
                                />
                            )
                        })}
                    </div>
                    <div className="lbaic-settings-divider lbaic-settings-divider-gap"/>
                    <div className="lbaic-settings-dashboard-grid">
                        {loading > 0 ? (
                            // Show shimmer cards while loading
                            shimmerCards.map(shimmerCard => (
                                <Card
                                    key={shimmerCard.name}
                                    card={shimmerCard}
                                    isSelected={false}
                                    onClick={() => {
                                    }}
                                    loading={true}
                                />
                            ))
                        ) : (
                            // Show actual cards when data is loaded
                            dashboardData?.map((card, index) => (
                                <Card
                                    key={index}
                                    card={card}
                                    isSelected={selectedCardName === card.name}
                                    onClick={() => setSelectedCardName(card.name)}
                                    loading={false}
                                    navigate={navigate}
                                />
                            ))
                        )}
                    </div>
                    <div className="lbaic-settings-dashboard-card">
                        <div className="lbaic-settings-dashboard-card-header">
                            {selectedCardName ? (
                                <p className="lbaic-settings-dashboard-card-header-label">{sprintf(__("%s over time", 'limb-chatbot'), chartLabel || '')}</p>
                            ) : (
                                <div
                                    className="lbaic-settings-dashboard-card-header-label-skeleton lbaic-settings-dashboard-card-shimmer"/>
                            )}
                        </div>
                        <div className="lbaic-settings-dashboard-card-body">
                            {selectedCardName ? (
                                <ResponsiveContainer width="100%" height={300}>
                                    <LineChart data={chartData}>
                                        <CartesianGrid strokeDasharray="3 3" stroke="#f0f0f0"/>
                                        <XAxis
                                            dataKey="time"
                                            stroke="#999999"
                                            style={{fontSize: 'var(--lbaic-settings-fs-12)'}}
                                        />
                                        <YAxis
                                            stroke="#999999"
                                            style={{fontSize: 'var(--lbaic-settings-fs-12)'}}
                                        />
                                        <Tooltip
                                            contentStyle={{
                                                backgroundColor: 'var(--lbaic-settings-white)',
                                                border: '1px solid var(--lbaic-settings-dashboard-card-border-color)',
                                                borderRadius: '6px',
                                                fontSize: 'var(--lbaic-settings-fs-12)',
                                            }}
                                            formatter={(value, name, item) => {
                                                return [
                                                    value, // Value
                                                    item?.payload?.time || name // Label
                                                ];
                                            }}
                                            labelFormatter={(label, items) => {
                                                return chartLabel;
                                            }}
                                        />
                                        <Line
                                            type="monotone"
                                            dataKey='value'
                                            stroke="var(--lbaic-settings-primary)"
                                            strokeWidth={2}
                                            dot={{fill: 'var(--lbaic-settings-primary)', r: 4}}
                                            activeDot={{r: 6}}
                                        />
                                    </LineChart>
                                </ResponsiveContainer>
                            ) : (
                                // Chart Skeleton Loading
                                <div className="lbaic-settings-dashboard-chart-skeleton">
                                    {/* Y-axis labels */}
                                    <div className="lbaic-settings-dashboard-chart-skeleton-y-axis">
                                        <div
                                            className="lbaic-settings-dashboard-chart-skeleton-label lbaic-settings-dashboard-card-shimmer"></div>
                                        <div
                                            className="lbaic-settings-dashboard-chart-skeleton-label lbaic-settings-dashboard-card-shimmer"></div>
                                        <div
                                            className="lbaic-settings-dashboard-chart-skeleton-label lbaic-settings-dashboard-card-shimmer"></div>
                                        <div
                                            className="lbaic-settings-dashboard-chart-skeleton-label lbaic-settings-dashboard-card-shimmer"></div>
                                        <div
                                            className="lbaic-settings-dashboard-chart-skeleton-label lbaic-settings-dashboard-card-shimmer"></div>
                                    </div>

                                    {/* Chart area */}
                                    <div className="lbaic-settings-dashboard-chart-skeleton-content">
                                        {/* Grid lines and chart skeleton */}
                                        <div className="lbaic-settings-dashboard-chart-skeleton-grid">
                                            {/* Horizontal grid lines */}
                                            <div className="lbaic-settings-dashboard-chart-skeleton-grid-line"></div>
                                            <div className="lbaic-settings-dashboard-chart-skeleton-grid-line"
                                                 style={{top: '25%'}}></div>
                                            <div className="lbaic-settings-dashboard-chart-skeleton-grid-line"
                                                 style={{top: '50%'}}></div>
                                            <div className="lbaic-settings-dashboard-chart-skeleton-grid-line"
                                                 style={{top: '75%'}}></div>

                                            {/* Shimmer bars/line placeholder */}
                                            <div className="lbaic-settings-dashboard-chart-skeleton-bars">
                                                <div
                                                    className="lbaic-settings-dashboard-chart-skeleton-bar lbaic-settings-dashboard-card-shimmer"
                                                    style={{height: '45%'}}></div>
                                                <div
                                                    className="lbaic-settings-dashboard-chart-skeleton-bar lbaic-settings-dashboard-card-shimmer"
                                                    style={{height: '65%'}}></div>
                                                <div
                                                    className="lbaic-settings-dashboard-chart-skeleton-bar lbaic-settings-dashboard-card-shimmer"
                                                    style={{height: '55%'}}></div>
                                                <div
                                                    className="lbaic-settings-dashboard-chart-skeleton-bar lbaic-settings-dashboard-card-shimmer"
                                                    style={{height: '80%'}}></div>
                                                <div
                                                    className="lbaic-settings-dashboard-chart-skeleton-bar lbaic-settings-dashboard-card-shimmer"
                                                    style={{height: '70%'}}></div>
                                                <div
                                                    className="lbaic-settings-dashboard-chart-skeleton-bar lbaic-settings-dashboard-card-shimmer"
                                                    style={{height: '60%'}}></div>
                                            </div>
                                        </div>

                                        {/* X-axis labels */}
                                        <div className="lbaic-settings-dashboard-chart-skeleton-x-axis">
                                            <div
                                                className="lbaic-settings-dashboard-chart-skeleton-label lbaic-settings-dashboard-card-shimmer"></div>
                                            <div
                                                className="lbaic-settings-dashboard-chart-skeleton-label lbaic-settings-dashboard-card-shimmer"></div>
                                            <div
                                                className="lbaic-settings-dashboard-chart-skeleton-label lbaic-settings-dashboard-card-shimmer"></div>
                                            <div
                                                className="lbaic-settings-dashboard-chart-skeleton-label lbaic-settings-dashboard-card-shimmer"></div>
                                            <div
                                                className="lbaic-settings-dashboard-chart-skeleton-label lbaic-settings-dashboard-card-shimmer"></div>
                                            <div
                                                className="lbaic-settings-dashboard-chart-skeleton-label lbaic-settings-dashboard-card-shimmer"></div>
                                        </div>
                                    </div>
                                </div>
                            )}
                        </div>
                    </div>
                </Container>
            </ContentBodyInner>
        </>
    );
}
