const { __ } = wp.i18n;
const { useState, useEffect, useContext, useRef } = wp.element;
import { AppContext } from "../../AppContext";
import Icon from '../Icon';


const FontPicker = ( { value, onFontChange, onFontPreview, googleFonts, ...props } ) => {

    const isPro = useContext( AppContext );

    const proLabel = ( value ) => {
        return isPro ? value : value + " (Pro)";
    }

    const [expanded, setExpanded] = useState( false );
    const [searchValue, setSearchValue] = useState( "" );
    const [theFont, setTheFont] = useState( value );
    const [initialFont, setInitialFont] = useState( value );
    const [recentFonts, setRecentFonts] = useState( [] );

    const loadedFonts = useRef( [] );

    let gFonts = null;
    

    let fonts = [
        {
            id: 1,
            label: 'Standard Fonts',
            attrid: 'safi-fonts-std',
            type: 'std',
            options: [
                { value: 'Arial', label: 'Arial, sans serif' },
                { value: 'Arial Black', label: 'Arial Black, sans serif' },
                { value: 'Comic Sans MS', label: 'Comic Sans MS, cursive' },
                { value: 'Courier', label: 'Courier, monospace' },
                { value: 'Georgia', label: 'Georgia, serif' },
                { value: 'Garamond', label: 'Garamond, serif' },
                { value: 'Impact', label: 'Impact, sans-serif' },
                { value: 'Lucida Console', label: 'Lucida Console, monospace' },
                { value: 'Lucida Sans Unicode', label: 'Lucida Sans Unicode, sans-serif' },
                { value: 'MS Sans Serif', label: 'MS Sans Serif, sans-serif' },
                { value: 'Tahoma', label: 'Tahoma, sans-serif' },
                { value: 'Times New Roman', label: 'Times New Roman, serif' },
                { value: 'Trebuchet MS', label: 'Trebuchet MS, sans-serif' },
                { value: 'Verdana', label: 'Verdana, sans-serif' },
            ]
        },
        {
            id: 2,
            label: proLabel( "Google fonts" ),
            options: [],
            type: 'gf',
            attrid: 'safi-fonts-gf',
        }
    ];

    

    const myInterval = useRef();
    const scrolling = useRef( false );
    const clickBlurListener = useRef();

    // Load recent fonts from localStorage on component mount
    useEffect( () => {
        const savedFonts = localStorage.getItem( 'SAFI_FONTS' );
        if ( savedFonts ) {
            try {
                setRecentFonts( JSON.parse( savedFonts ) );
            } catch ( error ) {
                console.error( 'Error parsing saved fonts:', error );
                setRecentFonts( [] );
            }
        }
    }, [] );

    // Save font to recent fonts list
    const saveFontToRecent = ( fontData ) => {
        if ( !fontData || !fontData.font ) return;

        // Create a unique identifier for the font
        const fontToSave = {
            font: fontData.font,
            type: fontData.type,
            label: getFontLabel( fontData.font, fontData.type )
        };
        
        // Get current recent fonts
        let updatedFonts = [...recentFonts];
        
        // Remove font if it already exists (compare by font name)
        updatedFonts = updatedFonts.filter( f => f.font !== fontToSave.font );
        
        // Add new font to the beginning
        updatedFonts.unshift( fontToSave );
        
        // Keep only the latest 8
        updatedFonts = updatedFonts.slice( 0, 8 );
        
        setRecentFonts( updatedFonts );
        localStorage.setItem( 'SAFI_FONTS', JSON.stringify( updatedFonts ) );
    };

    // Helper function to get font label
    const getFontLabel = ( fontName, fontType ) => {
        if ( fontType === 'std' ) {
            const stdFont = fonts[0].options.find( f => f.value === fontName );
            return stdFont ? stdFont.label : fontName;
        }
        return fontName; // For Google fonts, just return the font name
    };

    useEffect( () => {
        if ( expanded === true ) {
            const panel = document.querySelector( '.safi-popover-container' );
            searchInputRef.current.focus();
            clickBlurListener.current = handleBlur;

            
            window.addEventListener( "click", clickBlurListener.current );
        }
        else {
            
            window.removeEventListener( "click", clickBlurListener.current );
            clickBlurListener.current = null;
        }
    }, [expanded] );

    useEffect( () => {
        return () => {
            clearInterval( myInterval.current );
            window.removeEventListener( "click", clickBlurListener.current );
            clickBlurListener.current = null;
        }
    }, [] )

    useEffect( () => {
        setTheFont( value );
    }, [value] )

    const handleScroll = ( e ) => {
        scrolling.current = e;
        setTimeout( () => {
            scrolling.current = false;
        }, 500 );
    }

    

    const handleFontSelect = ( font ) => {
        setTheFont( font.font );
        onFontChange( font );
        
        // Save to recent fonts
        saveFontToRecent( font );

        setExpanded( false );
    }

    const handleFontPreview = ( font ) => {
        onFontPreview( font );
    }

    const handleSearch = ( e ) => {
        const value = e.target.value;
        setSearchValue( value );

        if ( !isPro ) {
            return;
        }
        const filteredFonts = fonts[1].options.filter( item => value === "" || item.value.search( new RegExp( value, "i" ) ) !== -1 );
        let fontFamilies = filteredFonts.slice( 0, 10 ).map( font => font.value );

        if ( value.length < 2 ) {
            return;
        }

        fontFamilies = fontFamilies.filter( item => loadedFonts.current.includes( item ) === false )
        loadedFonts.current = [...new Set( [...loadedFonts.current, ...fontFamilies] )];

        if ( !fontFamilies.length > 0 ) {
            return;
        }

        WebFont.load( {
            google: {
                families: fontFamilies
            },
        } );
    }

    const handleMouseLeave = () => {
        if (expanded === false ){
            return;
        }

        handleFontPreview( {
            font: initialFont,
        } )
    }

    const renderRecentFonts = () => {
        if ( recentFonts.length === 0 ) return null;

        const filteredRecentFonts = recentFonts.filter( item => 
            searchValue === "" || item.font.search( new RegExp( searchValue, "i" ) ) !== -1 
        );

        if ( filteredRecentFonts.length === 0 && searchValue !== "" ) return null;

        return (
            <div className="safi-group">
                <span id="safi-fonts-recent" className="safi-group-label flex flex-center">
                    {__( "Recent Fonts", "wpjoli-safi" )}
                </span>
                {filteredRecentFonts.map( ( item, index ) => (
                    <div
                        key={index}
                        className="safi-dropdown-item flex items-center"
                        title={item.label}
                        data-value={item.font}
                        data-type={item.type}
                        style={{ fontFamily: item.font }}
                        onClick={() => handleFontSelect( {
                            type: item.type,
                            font: item.font,
                        } )}
                        onMouseEnter={() => handleFontPreview( {
                            font: item.font,
                        } )}
                    >
                        <div className="dropdown-label">{item.label}</div>
                    </div>
                ) )}
            </div>
        );
    };

    const renderSegments = () => {
        return (
            <>
                {renderRecentFonts()}
                {fonts.map( ( group ) => {
                    const filteredFonts = group.options.filter( item => searchValue === "" || item.value.search( new RegExp( searchValue, "i" ) ) !== -1 );
                    return (
                        <div key={group.id} className="safi-group">
                            <span id={group.attrid} htmlFor="" className="safi-group-label flex flex-center">{group.label}</span>
                            {filteredFonts.map( ( item, index ) => {
                                return <div
                                    key={index}
                                    className={`safi-dropdown-item flex items-center`}
                                    title={item.label}
                                    data-value={item.value}
                                    data-type={group.type}
                                    style={{ fontFamily: ( item.value !== null ? item.value : 'initial' ) }}
                                    onClick={() => handleFontSelect( {
                                        type: group.type,
                                        font: item.value,
                                    } )}
                                    onMouseEnter={() => handleFontPreview( {
                                        font: item.value,
                                    } )}
                                >
                                    <div className="dropdown-label">{item.label}</div>
                                </div>
                            } )}
                            {!isPro && group.type === "gf" &&
                                <a href={window.SAFI.gopro_url} target="_blank" className="flex flex-center" style={{ marginBottom: "16px" }}>
                                    <button id="safi-go-pro" className="safi-tb-btn safi-btn-primary">
                                        {__( "Upgrade to Pro now !", "wpjoli-safi" )}
                                    </button>
                                </a>
                            }
                        </div>
                    )
                } )}
            </>
        );
    }

    const expandPanel = ( e ) => {
        if ( e.target.type === "text" ) {
            return;
        }
        setExpanded( !expanded );
    }

    const handleBlur = ( e ) => {
        if ( e.target.closest( ".safi-font-picker" ) !== null ) {
            return;
        }
        setExpanded( false );
    }

    const searchInputRef = useRef( null );
    
    return (
        <div>
            <div
                className="safi-popover-wrap safi-font-picker safi-dyn-dropdown"
                onClick={expandPanel}
            >
                <div className="safi-selected-font"
                    style={{
                        fontFamily: ( theFont !== null ? theFont : 'initial' ),
                        display: ( expanded ? 'none' : 'initial' ),
                    }}
                >{theFont}</div>
                <input
                    type="text"
                    id="safi-font-filter"
                    value={searchValue}
                    onChange={handleSearch}
                    placeholder={__( "Search font...", "wpjoli-safi" )}
                    ref={searchInputRef}
                    style={{
                        display: ( !expanded ? 'none' : 'initial' ),
                    }}
                />
                <div id="font-picker-dropdown" className="safi-popover-toggle" title="Insert content-based text" >
                    <Icon icon={expanded ? 'expand_less' : 'expand_more'} onIconClick={expandPanel} />
                </div>
                <div
                    className={`safi-popover-container` + ( expanded ? '' : ' --hidden' )}
                    tabIndex="0"
                    onScroll={handleScroll}
                    onMouseLeave={handleMouseLeave}
                >
                    {renderSegments()}
                </div>
            </div>
        </div>
    );
};

export default FontPicker;