import {useEffect, useState, useRef, useCallback} from "@wordpress/element";
import {__, sprintf} from "@wordpress/i18n";
import {formatDate, parseDateString} from "../../../../../../helpers";
import Tooltip from "../../../tooltip";

/**
 * RealTimeRelativeTime Component
 *
 * Displays relative time that updates in real-time:
 * - Minutes ago (up to 59 minutes)
 * - Hours ago (up to 23 hours)
 * - Days ago (up to 6 days)
 * - Weeks ago (up to 51 weeks)
 * - Months ago (up to 11 months)
 * - Full date format (1 year or more)
 *
 * @param {Object} props Component props
 * @param {string} props.dateString The date string to display relative time for
 * @param {string} props.className Optional CSS class name
 * @param {string} props.dateFormat Optional date format for full dates (default: 'MMM D, YYYY, HH:mm')
 * @param {number} props.updateInterval Optional update interval in milliseconds (default: 60000 for 1 minute)
 * @param {boolean} props.showTooltip Optional whether to show tooltip with full date (default: true)
 */
export default function RealTimeRelativeTime({
                                                 dateString,
                                                 className = '',
                                                 tooltipProps,
                                                 dateFormat = 'MMM D, YYYY, HH:mm',
                                                 utc = true,
                                                 updateInterval = 60000, // 1 minute
                                                 showTooltip = true
                                             }) {
    const [displayText, setDisplayText] = useState('');
    const [isFullDate, setIsFullDate] = useState(false);
    const intervalRef = useRef(null);
    const dateRef = useRef(null);

    /**
     * Calculate relative time text
     * @param {Date} date The date to calculate relative time for
     * @returns {Object} Object with text and isFullDate flag
     */
    const calculateRelativeTime = useCallback((date) => {
        const now = new Date();
        const diffInMs = now - date;
        const diffInMinutes = Math.floor(diffInMs / (1000 * 60));
        const diffInHours = Math.floor(diffInMs / (1000 * 60 * 60));
        const diffInDays = Math.floor(diffInMs / (1000 * 60 * 60 * 24));
        const diffInWeeks = Math.floor(diffInDays / 7);
        const diffInMonths = Math.floor(diffInDays / 30);
        const diffInYears = Math.floor(diffInDays / 365);

        // More than 1 year - show full date
        if (diffInYears >= 1) {
            return {
                text: sprintf(__('%dy ago', 'limb-chatbot'), diffInYears),
                isFullDate: false
            };
        }

        // More than 1 month - show months
        if (diffInMonths >= 1) {
            return {
                text: sprintf(__('%dmo ago', 'limb-chatbot'), diffInMonths),
                isFullDate: false
            };
        }

        // More than 1 week - show weeks
        if (diffInWeeks >= 1) {
            return {
                text: sprintf(__('%dw ago', 'limb-chatbot'), diffInWeeks),
                isFullDate: false
            };
        }

        // More than 1 day - show days
        if (diffInDays >= 1) {
            return {
                text: sprintf(__('%dd ago', 'limb-chatbot'), diffInDays),
                isFullDate: false
            };
        }

        // More than 1 hour - show hours
        if (diffInHours >= 1) {
            return {
                text: sprintf(__('%dh ago', 'limb-chatbot'), diffInHours),
                isFullDate: false
            };
        }

        // Less than 1 hour - show minutes
        if (diffInMinutes >= 1) {
            return {
                text: sprintf(__('%dm ago', 'limb-chatbot'), diffInMinutes),
                isFullDate: false
            };
        }

        // Less than 1 minute - show "just now"
        return {
            text: __('Just now', 'limb-chatbot'),
            isFullDate: false
        };
    }, [dateFormat]);

    /**
     * Update the display text
     */
    const updateDisplay = useCallback(() => {
        if (!dateRef.current) return;

        const result = calculateRelativeTime(dateRef.current);
        setDisplayText(result.text);
        setIsFullDate(result.isFullDate);
    }, [calculateRelativeTime]);

    /**
     * Calculate the appropriate interval for the first update only
     * @param {Date} date The date to calculate interval for
     * @returns {number} Interval in milliseconds
     */
    const calculateFirstInterval = useCallback((date) => {
        try {
            const diffInMs = new Date() - date;

            return updateInterval - diffInMs % updateInterval;
        } catch (e) {
            console.error(e);
        }

        return updateInterval;
    }, [updateInterval]);

    /**
     * Initialize the component
     */
    useEffect(() => {
        if (!dateString) {
            setDisplayText('');
            return;
        }

        // Parse the date string
        const date = parseDateString(dateString, utc);
        if (!date) {
            setDisplayText(__('Invalid date', 'limb-chatbot'));
            return;
        }

        dateRef.current = date;
        updateDisplay();

        // Calculate first interval based on time difference
        const firstInterval = calculateFirstInterval(date);

        // Schedule first update with calculated interval
        const firstTimeout = setTimeout(() => {
            updateDisplay();

            // After first update, switch to regular interval
            intervalRef.current = setInterval(updateDisplay, updateInterval);
        }, firstInterval);

        // Cleanup function
        return () => {
            clearTimeout(firstTimeout);
            if (intervalRef.current) {
                clearInterval(intervalRef.current);
                intervalRef.current = null;
            }
        };
    }, [dateString, updateInterval, updateDisplay, calculateFirstInterval]);

    if (!displayText) {
        return null;
    }

    const fullDate = dateRef.current ? formatDate(dateRef.current, dateFormat) : '';

    const display = (
        <span className={className}>{displayText}</span>
    );

    if (showTooltip && !isFullDate) {
        return <Tooltip
            title={fullDate}
            tooltipPosition='top'
            arrowPosition='left'
            {...tooltipProps}
        >
            {display}
        </Tooltip>
    } else {
        return display;
    }
}
