import {FormattedMessage, intlShape, defineMessages} from 'react-intl';
import PropTypes from 'prop-types';
import React from 'react';

import Box from '../box/box.jsx';
import PlayButton from '../../containers/play-button.jsx';
import styles from './library-item.css';
import classNames from 'classnames';

import bluetoothIconURL from './bluetooth.svg';
import internetConnectionIconURL from './internet-connection.svg';

import favoritedFilledUrl from './favorite/filled.svg';
import favoritedOutlineUrl from './favorite/outline.svg';
import deleteFilledUrl from './delete/filled.svg';
import downloadFilled from './download/filled.svg';

const getURLOrigin = (url) => {
    let urlObj;
    try {
        urlObj = new URL(url);
    } catch {
        // not a valid URL
        return String(url);
    }
    return urlObj.origin;
};
const getMSFormatted = (ms) => {
    return (ms / 1000).toFixed(2);
};

/* eslint-disable react/prefer-stateless-function */
class LibraryItemComponent extends React.PureComponent {
    render() {
        return this.props.featured ? (
            <div
                className={classNames(
                    styles.libraryItem,
                    styles.featuredItem,
                    {
                        [styles.disabled]: this.props.disabled
                    },
                    typeof this.props.extensionId === 'string' ? styles.libraryItemExtension : null,
                    this.props.hidden ? styles.hidden : null
                )}
                onClick={this.props.onClick}
            >
                <div className={styles.featuredImageContainer}>
                    {this.props.disabled ? (
                        <div className={styles.comingSoonText}>
                            <FormattedMessage
                                defaultMessage="Coming Soon"
                                description="Label for extensions that are not yet implemented"
                                id="gui.extensionLibrary.comingSoon"
                            />
                        </div>
                    ) : null}
                    <img
                        className={styles.featuredImage}
                        loading="lazy"
                        draggable={false}
                        src={this.props.iconURL}
                    />
                </div>
                {(this.props.insetIconURL && !this.props.customInsetColor) ? (
                    <div className={
                        this.props.twDeveloper ?
                            classNames(styles.libraryItemInsetImageContainer, styles.twLibraryItemInsetImageContainer)
                            : styles.libraryItemInsetImageContainer
                    }
                    >
                        <img
                            className={styles.libraryItemInsetImage}
                            src={this.props.insetIconURL}
                            draggable={false}
                        />
                    </div>
                ) : null}
                {(this.props.insetIconURL && this.props.customInsetColor) ? (
                    <div className={
                        styles.libraryItemInsetImageContainerNoBg
                    }
                        style={{ backgroundColor: this.props.customInsetColor }}
                    >
                        <img
                            className={styles.libraryItemInsetImage}
                            src={this.props.insetIconURL}
                        />
                    </div>
                ) : null}
                {(this.props.favoritable && !this.props.deletable) ? (
                    <button
                        // data-clearclick just makes it so the item
                        // doesnt get selected when clicking this element
                        data-clearclick="true"
                        data-activated={this.props.favorited === true}
                        className={styles.libraryItemFavorite}
                        onClick={() => this.props.onFavoriteClick(this.props.favorited)}
                    >
                        {this.props.favorited === true ? (
                            <img
                                data-usedimage="true"
                                data-clearclick="true"
                                src={favoritedFilledUrl}
                            />
                        ) : (
                            <img
                                data-usedimage="true"
                                data-clearclick="true"
                                src={favoritedOutlineUrl}
                            />
                        )}
                        <img
                            data-usedimage="false"
                            data-clearclick="true"
                            src={favoritedFilledUrl}
                        />
                    </button>
                ) : null}
                {this.props.deletable && (
                    <button
                        // data-clearclick just makes it so the item
                        // doesnt get selected when clicking this element
                        data-clearclick="true"
                        className={styles.libraryItemDelete}
                        onClick={this.props.onDeleteClick}
                    >
                        <img
                            data-clearclick="true"
                            src={deleteFilledUrl}
                        />
                    </button>
                )}
                <div
                    className={typeof this.props.extensionId === 'string' ?
                        classNames(styles.featuredExtensionText, styles.featuredText) : styles.featuredText
                    }
                >
                    <span className={styles.libraryItemName}>{this.props.name}</span>
                    <br />
                    <span className={styles.featuredDescription}>{this.props.description}</span>
                    {this.props.custom && (
                        <>
                            <br />
                            {this.props.extensionId.startsWith("data:") ? (
                                <span>
                                    {this.props._unsandboxed ?
                                        (
                                            <FormattedMessage
                                                defaultMessage="Custom Unsandboxed extension"
                                                description="Label for custom library extensions that are unsandboxed (not safe)"
                                                id="pm.extensionLibrary.customLibraryExtensionUnsandboxed"
                                            />
                                        ) : (
                                            <FormattedMessage
                                                defaultMessage="Custom Sandboxed extension"
                                                description="Label for custom library extensions that are sandboxed"
                                                id="pm.extensionLibrary.customLibraryExtensionSandboxed"
                                            />
                                        )}
                                </span>
                            ) : (
                                <span>
                                    <FormattedMessage
                                        defaultMessage="Added from a website"
                                        description="Label for custom library extensions that are added from a URL"
                                        id="pm.extensionLibrary.customLibraryExtensionWebsite"
                                    />
                                </span>
                            )}
                            {this.props.extensionId.startsWith("data:") ? (
                                <span className={styles.featuredDescription}>
                                    <FormattedMessage
                                        defaultMessage="Loaded from Text / File"
                                        description="Label for custom library extensions that are added from text or a file"
                                        id="pm.extensionLibrary.customLibraryExtensionTextOrFile"
                                    />
                                    <a
                                        data-clearclick="true"
                                        download="extension.js"
                                        href={this.props.extensionId}
                                    >
                                        <button
                                            data-clearclick="true"
                                            className={styles.inspectExtension}
                                        >
                                            <img
                                                data-clearclick="true"
                                                src={downloadFilled}
                                                alt="Download"
                                            />
                                        </button>
                                    </a>
                                </span>
                            ) : (
                                <a
                                    target='_blank'
                                    data-clearclick="true"
                                    href={this.props.extensionId}
                                    className={styles.featuredDescription}
                                >
                                    {getURLOrigin(this.props.extensionId)}
                                </a>
                            )}
                        </>
                    )}
                </div>
                {
                    this.props.bluetoothRequired ||
                        this.props.internetConnectionRequired ||
                        this.props.collaborator ||
                        this.props.extDeveloper ||
                        this.props.twDeveloper ||
                        this.props.eventSubmittor ||
                        this.props.credits
                        ? (
                            <div className={styles.featuredExtensionMetadata}>
                                <div className={styles.featuredExtensionRequirement}>
                                    {this.props.bluetoothRequired || this.props.internetConnectionRequired ? (
                                        <div>
                                            <div>
                                                <FormattedMessage
                                                    defaultMessage="Requires"
                                                    description="Label for extension hardware requirements"
                                                    id="gui.extensionLibrary.requires"
                                                />
                                            </div>
                                            <div
                                                className={styles.featuredExtensionMetadataDetail}
                                            >
                                                {this.props.bluetoothRequired ? (
                                                    <img src={bluetoothIconURL} />
                                                ) : null}
                                                {this.props.internetConnectionRequired ? (
                                                    <img src={internetConnectionIconURL} />
                                                ) : null}
                                            </div>
                                        </div>
                                    ) : null}
                                </div>
                                <div className={styles.featuredExtensionCollaboration}>
                                    {this.props.collaborator ? (
                                        <div className={styles.smallBottomMargin}>
                                            <div>
                                                <FormattedMessage
                                                    defaultMessage="Collaboration with"
                                                    description="Label for extension collaboration"
                                                    id="gui.extensionLibrary.collaboration"
                                                />
                                            </div>
                                            <div
                                                className={styles.featuredExtensionMetadataDetail}
                                            >
                                                {this.props.collaborator}
                                            </div>
                                        </div>
                                    ) : null}
                                    {this.props.twDeveloper ? (
                                        <div className={styles.smallBottomMargin}>
                                            <div>
                                                Originally for TurboWarp by
                                            </div>
                                            <div
                                                className={styles.featuredExtensionMetadataDetail}
                                            >
                                                {this.props.twDeveloper}
                                            </div>
                                        </div>
                                    ) : null}
                                    {this.props.extDeveloper ? (
                                        <div className={styles.smallBottomMargin}>
                                            <div>
                                                Created by
                                            </div>
                                            <div
                                                className={styles.featuredExtensionMetadataDetail}
                                            >
                                                {this.props.extDeveloper}
                                            </div>
                                        </div>
                                    ) : null}
                                    {this.props.eventSubmittor ? (
                                        <div className={styles.smallBottomMargin}>
                                            <div>
                                                Event Submission by
                                            </div>
                                            <div
                                                className={styles.featuredExtensionMetadataDetail}
                                            >
                                                {this.props.eventSubmittor}
                                            </div>
                                        </div>
                                    ) : null}
                                    {this.props.credits ? (
                                        <div className={styles.smallBottomMargin}>
                                            <div>
                                                Credits
                                            </div>
                                            <div
                                                className={styles.featuredExtensionMetadataDetail}
                                            >
                                                {this.props.credits}
                                            </div>
                                        </div>
                                    ) : null}
                                </div>
                            </div>
                        ) : null}
            </div>
        ) : (
            <Box
                className={classNames(
                    styles.libraryItem, {
                    [styles.hidden]: this.props.hidden,
                    [styles.libraryItemSound]: this.props.styleForSound,
                    [styles.libraryItemNew]: this.props.isNew,
                }
                )}
                role="button"
                tabIndex="0"
                onBlur={this.props.onBlur}
                onClick={this.props.onClick}
                onFocus={this.props.onFocus}
                onKeyPress={this.props.onKeyPress}
                onMouseEnter={this.props.showPlayButton ? null : this.props.onMouseEnter}
                onMouseLeave={this.props.showPlayButton ? null : this.props.onMouseLeave}
            >
                {this.props.isNew && (
                    <div className={styles.libraryItemNewBadge}>
                        NEW
                    </div>
                )}
                {/* Layers of wrapping is to prevent layout thrashing on animation */}
                <Box className={styles.libraryItemImageContainerWrapper}>
                    <Box
                        className={styles.libraryItemImageContainer}
                        onMouseEnter={this.props.showPlayButton ? this.props.onMouseEnter : null}
                        onMouseLeave={this.props.showPlayButton ? this.props.onMouseLeave : null}
                    >
                        <img
                            className={classNames(
                                styles.libraryItemImage, {
                                [styles.libraryItemWaveform]: this.props.styleForSound
                            }
                            )}
                            loading="lazy"
                            src={this.props.iconURL}
                            draggable={false}
                        />
                        {this.props.overlayURL && (
                            <img
                                className={classNames(
                                    styles.libraryItemImage, styles.libraryItemImageOverlay, {
                                    [styles.libraryItemWaveform]: this.props.styleForSound
                                }
                                )}
                                loading="lazy"
                                src={this.props.overlayURL}
                                draggable={false}
                            />
                        )}
                    </Box>
                </Box>
                {this.props.styleForSound ? (
                    <div className={styles.libraryItemSoundInfoContainer}>
                        <span className={classNames(styles.libraryItemName, styles.libraryItemSoundName)}>{this.props.name}</span>
                        <span className={classNames(styles.libraryItemName, styles.libraryItemSoundType)}>
                            {this.props.soundType}, {getMSFormatted(this.props.soundLength)}
                        </span>
                    </div>
                ) : (
                    <span className={styles.libraryItemName}>{this.props.name}</span>
                )}
                {this.props.showPlayButton ? (
                    <PlayButton
                        className={classNames({
                            [styles.libraryItemSoundPlayButton]: this.props.styleForSound,
                            [styles.libraryItemNewPlayButton]: this.props.isNew,
                        })}
                        isPlaying={this.props.isPlaying}
                        onPlay={this.props.onPlay}
                        onStop={this.props.onStop}
                    />
                ) : null}
            </Box>
        );
    }
}
/* eslint-enable react/prefer-stateless-function */


LibraryItemComponent.propTypes = {
    intl: intlShape,
    bluetoothRequired: PropTypes.bool,
    collaborator: PropTypes.string,
    credits: PropTypes.string,
    twDeveloper: PropTypes.string,
    extDeveloper: PropTypes.string,
    eventSubmittor: PropTypes.string,
    description: PropTypes.oneOfType([
        PropTypes.string,
        PropTypes.node
    ]),
    disabled: PropTypes.bool,
    extensionId: PropTypes.string,
    featured: PropTypes.bool,
    isNew: PropTypes.bool,
    hidden: PropTypes.bool,
    iconURL: PropTypes.string,
    overlayURL: PropTypes.string,
    insetIconURL: PropTypes.string,
    styleForSound: PropTypes.bool,
    soundType: PropTypes.string,
    soundLength: PropTypes.number,
    customInsetColor: PropTypes.string,
    internetConnectionRequired: PropTypes.bool,
    isPlaying: PropTypes.bool,
    name: PropTypes.oneOfType([
        PropTypes.string,
        PropTypes.node
    ]),
    onBlur: PropTypes.func.isRequired,
    onClick: PropTypes.func.isRequired,
    onFocus: PropTypes.func.isRequired,
    onKeyPress: PropTypes.func.isRequired,
    onMouseEnter: PropTypes.func.isRequired,
    onMouseLeave: PropTypes.func.isRequired,
    onPlay: PropTypes.func.isRequired,
    onStop: PropTypes.func.isRequired,
    showPlayButton: PropTypes.bool,

    favoritable: PropTypes.bool,
    favorited: PropTypes.bool,
    deletable: PropTypes.bool,
    custom: PropTypes.bool,
    onFavoriteClick: PropTypes.func,
    onDeleteClick: PropTypes.func,
    _id: PropTypes.string,
    _unsandboxed: PropTypes.bool
};

LibraryItemComponent.defaultProps = {
    disabled: false,
    showPlayButton: false
};

export default LibraryItemComponent;
