import React, { useEffect, useState, useRef, useCallback } from 'react';
import { getItemData, parseDescriptionSegments, loadItemDatabase } from '@/services/item-database';
import { cn } from '@/lib/utils';

interface ItemTooltipProps {
    itemId: number;
    showName?: boolean;
    iconSize?: number;
    className?: string;
}

/**
 * ItemTooltip component - Displays item icon with name and tooltip on hover
 * Shows item icon, name (colored by rarity), and full tooltip with description
 */
export function ItemTooltip({
    itemId,
    showName = true,
    iconSize = 20,
    className,
}: ItemTooltipProps) {
    const [dbLoaded, setDbLoaded] = useState(false);
    const wrapperRef = useRef<HTMLSpanElement>(null);
    const tooltipRef = useRef<HTMLDivElement | null>(null);
    const [tooltipVisible, setTooltipVisible] = useState(false);

    useEffect(() => {
        loadItemDatabase()
            .then(() => setDbLoaded(true))
            .catch(() => {});
    }, []);

    const itemData = dbLoaded ? getItemData(itemId) : null;
    const iconUrl = `/img/Icons/${itemId}.png`;

    const buildDescriptionHtml = useCallback(() => {
        if (!itemData?.rawDescription) return '';

        const segments = parseDescriptionSegments(itemData.rawDescription);
        return segments.map(segment => {
            const escapedText = segment.text
                .replace(/&/g, '&amp;')
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
                .replace(/"/g, '&quot;')
                .replace(/'/g, '&#039;');
            return `<span style="color: #${segment.color}">${escapedText}</span>`;
        }).join('');
    }, [itemData]);

    const updateTooltipPosition = useCallback((e: React.MouseEvent | MouseEvent) => {
        const tooltip = tooltipRef.current;
        if (!tooltip) return;

        const rect = tooltip.getBoundingClientRect();
        const viewportWidth = window.innerWidth;
        const viewportHeight = window.innerHeight;

        let left = e.clientX;
        let top = e.clientY + 15;

        // Adjust horizontal position
        if (left + rect.width > viewportWidth - 10) {
            left = viewportWidth - rect.width - 10;
        }
        if (left < 10) {
            left = 10;
        }

        // Adjust vertical position
        if (top + rect.height > viewportHeight - 10) {
            top = e.clientY - rect.height - 10;
        }

        tooltip.style.left = left + 'px';
        tooltip.style.top = top + 'px';
    }, []);

    const showTooltip = useCallback((e: React.MouseEvent) => {
        if (!itemData || tooltipVisible) return;

        setTooltipVisible(true);
        const tooltip = document.createElement('div');
        tooltip.className = 'max-w-sm p-3 bg-black/95 border border-gray-700 rounded-md shadow-lg';
        tooltip.style.cssText = `
            position: fixed;
            z-index: 9999;
            pointer-events: none;
        `;

        const descriptionHtml = buildDescriptionHtml();

        tooltip.innerHTML = `
            <div class="space-y-2">
                <div class="flex items-center gap-2">
                    <img src="${iconUrl}" alt="" class="w-8 h-8 object-contain" />
                    <div>
                        <p class="font-medium text-sm" style="color: #${itemData.color}; margin: 0;">
                            ${itemData.name}
                        </p>
                    </div>
                </div>
                ${itemData.rawDescription ? `
                    <div class="text-xs border-t border-border pt-2" style="white-space: pre-wrap; word-wrap: break-word;">${descriptionHtml}</div>
                ` : ''}
            </div>
        `;

        document.body.appendChild(tooltip);
        tooltipRef.current = tooltip;
        updateTooltipPosition(e);
    }, [itemData, tooltipVisible, buildDescriptionHtml, iconUrl, updateTooltipPosition]);

    const hideTooltip = useCallback(() => {
        if (tooltipRef.current && tooltipVisible) {
            document.body.removeChild(tooltipRef.current);
            tooltipRef.current = null;
            setTooltipVisible(false);
        }
    }, [tooltipVisible]);

    return (
        <span
            ref={wrapperRef}
            className={cn(
                'inline-flex items-center gap-2 px-1 py-0.5 rounded transition-colors',
                className
            )}
            style={{ display: 'inline-flex', verticalAlign: 'middle', alignItems: 'center' }}
            onMouseEnter={showTooltip}
            onMouseMove={updateTooltipPosition}
            onMouseLeave={hideTooltip}
        >
            <img
                src={iconUrl}
                alt={itemData?.name || `Item ${itemId}`}
                style={{
                    width: iconSize,
                    height: iconSize,
                    objectFit: 'contain',
                    verticalAlign: 'middle',
                    cursor: 'pointer',
                }}
                onError={(e) => {
                    (e.target as HTMLImageElement).style.display = 'none';
                }}
            />
            {showName && dbLoaded && itemData && (
                <span
                    className="font-medium text-sm"
                    style={{ color: `#${itemData.color}`, cursor: 'pointer' }}
                    data-item-name="true"
                    data-item-id={itemId}
                >
                    {itemData.name}
                </span>
            )}
        </span>
    );
}

/**
 * Hook for enhancing existing DOM elements with item tooltips
 * Use this when you need to enhance content that's already rendered (e.g., from CMS/HTML)
 */
export function useItemTooltipEnhancer(containerSelector: string) {
    const [dbLoaded, setDbLoaded] = useState(false);

    useEffect(() => {
        loadItemDatabase().then(() => setDbLoaded(true));
    }, []);

    useEffect(() => {
        if (!dbLoaded) return;

        const enhanceIcons = () => {
            const container = document.querySelector(containerSelector);
            if (!container) return;

            const itemIcons = container.querySelectorAll('img[src*="/img/Icons/"]');

            itemIcons.forEach((img) => {
                const element = img as HTMLImageElement;

                // Skip if already enhanced
                if (element.getAttribute('data-tooltip-enhanced') === 'true') return;

                // Get item ID from icon source
                const iconSrc = element.src || element.getAttribute('src') || '';
                const itemIdMatch = iconSrc.match(/\/img\/Icons\/(\d+)\.png/);

                if (!itemIdMatch) return;

                const itemId = parseInt(itemIdMatch[1]);
                const iconUrl = `/img/Icons/${itemId}.png`;
                const itemData = getItemData(itemId);

                if (!itemData) return;

                // Check if icon is already inside a wrapper with name
                const parentElement = element.parentElement;
                const isInWrapper = parentElement &&
                    parentElement.nodeType === Node.ELEMENT_NODE &&
                    (parentElement as HTMLElement).classList.contains('inline-flex') &&
                    (parentElement as HTMLElement).classList.contains('items-center') &&
                    parentElement.querySelector('[data-item-name]');

                if (isInWrapper) {
                    element.setAttribute('data-tooltip-enhanced', 'true');
                    return;
                }

                // Create new wrapper with icon and name
                const wrapper = document.createElement('span');
                wrapper.className = 'inline-flex items-center gap-2 px-1 py-0.5 rounded transition-colors';
                wrapper.style.cssText = 'position: relative; display: inline-flex; vertical-align: middle; align-items: center;';

                element.parentNode?.replaceChild(wrapper, element);
                wrapper.appendChild(element);

                // Reset icon style
                element.style.width = '20px';
                element.style.height = '20px';
                element.style.objectFit = 'contain';
                element.style.verticalAlign = 'middle';
                element.style.cursor = 'pointer';

                // Create name span
                const nameSpan = document.createElement('span');
                nameSpan.textContent = itemData.name || '';
                nameSpan.setAttribute('data-item-name', 'true');
                nameSpan.setAttribute('data-item-id', itemId.toString());
                nameSpan.className = 'font-medium text-sm';
                nameSpan.style.cssText = `color: #${itemData.color}; cursor: pointer;`;
                wrapper.appendChild(nameSpan);

                element.setAttribute('data-tooltip-enhanced', 'true');

                // Tooltip management
                let tooltipElement: HTMLElement | null = null;
                let tooltipVisible = false;

                const buildDescriptionHtml = () => {
                    if (!itemData.rawDescription) return '';
                    const segments = parseDescriptionSegments(itemData.rawDescription);
                    return segments.map(segment => {
                        const escapedText = segment.text
                            .replace(/&/g, '&amp;')
                            .replace(/</g, '&lt;')
                            .replace(/>/g, '&gt;')
                            .replace(/"/g, '&quot;')
                            .replace(/'/g, '&#039;');
                        return `<span style="color: #${segment.color}">${escapedText}</span>`;
                    }).join('');
                };

                const showTooltip = (e: Event) => {
                    const mouseEvent = e as MouseEvent;
                    if (tooltipVisible) return;

                    tooltipVisible = true;
                    tooltipElement = document.createElement('div');
                    tooltipElement.className = 'max-w-sm p-3 bg-black/95 border border-gray-700 rounded-md shadow-lg';
                    tooltipElement.style.cssText = `
                        position: fixed;
                        z-index: 9999;
                        pointer-events: none;
                    `;

                    const descriptionHtml = buildDescriptionHtml();

                    tooltipElement.innerHTML = `
                        <div class="space-y-2">
                            <div class="flex items-center gap-2">
                                <img src="${iconUrl}" alt="" class="w-8 h-8 object-contain" />
                                <div>
                                    <p class="font-medium text-sm" style="color: #${itemData.color}; margin: 0;">
                                        ${itemData.name}
                                    </p>
                                </div>
                            </div>
                            ${itemData.rawDescription ? `
                                <div class="text-xs border-t border-border pt-2" style="white-space: pre-wrap; word-wrap: break-word;">${descriptionHtml}</div>
                            ` : ''}
                        </div>
                    `;

                    document.body.appendChild(tooltipElement);
                    updateTooltipPosition(mouseEvent);
                };

                const updateTooltipPosition = (e: MouseEvent) => {
                    if (!tooltipElement) return;

                    const rect = tooltipElement.getBoundingClientRect();
                    const viewportWidth = window.innerWidth;
                    const viewportHeight = window.innerHeight;

                    let left = e.clientX;
                    let top = e.clientY + 15;

                    if (left + rect.width > viewportWidth - 10) {
                        left = viewportWidth - rect.width - 10;
                    }
                    if (left < 10) {
                        left = 10;
                    }
                    if (top + rect.height > viewportHeight - 10) {
                        top = e.clientY - rect.height - 10;
                    }

                    tooltipElement.style.left = left + 'px';
                    tooltipElement.style.top = top + 'px';
                };

                const hideTooltip = () => {
                    if (tooltipElement && tooltipVisible) {
                        document.body.removeChild(tooltipElement);
                        tooltipElement = null;
                        tooltipVisible = false;
                    }
                };

                // Attach events to both icon and name span
                element.addEventListener('mouseenter', showTooltip);
                element.addEventListener('mousemove', (e) => updateTooltipPosition(e as MouseEvent));
                element.addEventListener('mouseleave', hideTooltip);

                nameSpan.addEventListener('mouseenter', showTooltip);
                nameSpan.addEventListener('mousemove', (e) => updateTooltipPosition(e as MouseEvent));
                nameSpan.addEventListener('mouseleave', hideTooltip);
            });
        };

        enhanceIcons();

        const observer = new MutationObserver(() => {
            setTimeout(enhanceIcons, 100);
        });
        observer.observe(document.body, { childList: true, subtree: true });

        return () => observer.disconnect();
    }, [dbLoaded, containerSelector]);
}

/**
 * NewsItemTooltips - Component to enhance item icons in news content
 * Drop this component into any page with .prose content containing item icons
 */
export function NewsItemTooltips() {
    useItemTooltipEnhancer('.prose');
    return null;
}

/**
 * LogItemTooltips - Component to enhance item icons in log pages
 * Drop this component into log pages to ensure item tooltips work
 */
export function LogItemTooltips() {
    useItemTooltipEnhancer('body');
    return null;
}

export default ItemTooltip;
