import * as React from 'react';
import { inject, injectable } from 'inversify';
import { WindowService } from '@theia/core/lib/browser/window/window-service';
import { Installable } from '../../../common/protocol/installable';
import { ArduinoComponent } from '../../../common/protocol/arduino-component';
import { ComponentListItem } from './component-list-item';

@injectable()
export class ListItemRenderer<T extends ArduinoComponent> {

    @inject(WindowService)
    protected windowService: WindowService;

    protected onMoreInfoClick = (event: React.SyntheticEvent<HTMLAnchorElement, Event>) => {
        const { target } = event.nativeEvent;
        if (target instanceof HTMLAnchorElement) {
            this.windowService.openNewWindow(target.href, { external: true });
            event.nativeEvent.preventDefault();
        }
    }

    renderItem(
        input: ComponentListItem.State & { item: T },
        install: (item: T) => Promise<void>,
        uninstall: (item: T) => Promise<void>,
        onVersionChange: (version: Installable.Version) => void
    ): React.ReactNode {

        const { item } = input;
        let nameAndAuthor: JSX.Element;
        if (item.name && item.author) {
            const name = <span className='name'>{item.name}</span>;
            const author = <span className='author'>{item.author}</span>;
            nameAndAuthor = <span>{name} by {author}</span>
        } else if (item.name) {
            nameAndAuthor = <span className='name'>{item.name}</span>;
        } else if ((item as any).id) {
            nameAndAuthor = <span className='name'>{(item as any).id}</span>;
        } else {
            nameAndAuthor = <span className='name'>Unknown</span>;
        }
        const onClickUninstall = () => uninstall(item);
        const installedVersion = !!item.installedVersion && <div className='version-info'>
            <span className='version'>Version {item.installedVersion}</span>
            <span className='installed' onClick={onClickUninstall} />
        </div>;

        const summary = <div className='summary'>{item.summary}</div>;
        const description = <div className='summary'>{item.description}</div>;

        const moreInfo = !!item.moreInfoLink && <a href={item.moreInfoLink} onClick={this.onMoreInfoClick}>More info</a>;
        const onClickInstall = () => install(item);
        const installButton = item.installable &&
            <button className='theia-button install' onClick={onClickInstall}>INSTALL</button>;

        const onSelectChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
            const version = event.target.value;
            if (version) {
                onVersionChange(version);
            }
        }

        const versions = (() => {
            const { availableVersions } = item;
            if (availableVersions.length === 0) {
                return undefined;
            } else if (availableVersions.length === 1) {
                return <label>{availableVersions[0]}</label>
            } else {
                return <select
                    className='theia-select'
                    value={input.selectedVersion}
                    onChange={onSelectChange}>
                    {
                        item.availableVersions
                            .filter(version => version !== item.installedVersion) // Filter the version that is currently installed.
                            .map(version => <option value={version} key={version}>{version}</option>)
                    }
                </select>;
            }
        })();

        return <div className='component-list-item noselect'>
            <div className='header'>
                {nameAndAuthor}
                {installedVersion}
            </div>
            <div className='content'>
                {summary}
                {description}
            </div>
            <div className='info'>
                {moreInfo}
            </div>
            <div className='footer'>
                {installButton}
                {versions}
            </div>
        </div>;
    }

}
