import { Component, h, Prop, Event, EventEmitter } from '@stencil/core'
import { HistoryItem, HistoryItemSelection } from './user-dashboard-list-item'
import { getServiceConfigByType } from '../../shared/services'
import { format } from 'date-fns'

export type rowVariant = 'odd' | 'even'

@Component({
    tag: 'gd-user-dashboard-list-item',
    styleUrl: 'gd-user-dashboard-list-item.scss',
    shadow: true,
})
export class GdUserDashboardListItem {
    /**
     * the history item to render
     */
    @Prop() item: HistoryItem

    /**
     * if history item url is a valid url, clicking on it will immediately navigate to that url
     * if set to false, the application will need to use the labelClick event to handle navigation
     */
    @Prop() followUrl: boolean = false

    /**
     * whether the item should be selectable (have a checkbox)
     */
    @Prop() selectable: boolean = true

    /**
     * whether the item should be selected
     */
    @Prop() selected: boolean = false

    /**
     * if item should show who shared it
     */
    @Prop() showSharedBy: boolean = false

    /**
     * if item should show edit button
     */
    @Prop() allowEdit: boolean = false

    /**
     * if item should show favorite button
     */
    @Prop() allowFavorite: boolean = true

    /**
     * if item should show delete button
     */
    @Prop() allowDelete: boolean = true

    /**
     * Is item odd or even entry in a list of items. Used to set alternating background colors for lists
     */
    @Prop() alternateRow: rowVariant

    /**
     * the application can use the labelClick handler to customize user dashboard item clicks
     * ex. if application stores JSON in history item URL field that represents a dialog to display instead of a page
     */
    @Event() labelClick: EventEmitter<HistoryItem>

    /**
     * used by the application to save changes that have been made to the history item
     */
    @Event() updateItem: EventEmitter<HistoryItem>

    /**
     * used by the application to delete the history item
     */
    @Event() deleteItem: EventEmitter<HistoryItem>

    /**
     * used by the dashboard to handle editing a history item
     */
    @Event() editItem: EventEmitter<HistoryItem>

    /**
     * notifies the dashboard that this item has been selected
     */
    @Event() itemSelected: EventEmitter<HistoryItemSelection>

    /**
     * renders the user dashboard list item
     */
    render() {
        const serviceConfig = getServiceConfigByType(this.item?.serviceType)

        // format created date or fallback to all zeroes (fallback should only happen with test data)
        const createdDate = this.item?.created ? format(new Date(this.item.created), 'MM-dd-yyyy hh:mm:ss') : '00-00-0000 00:00:00'

        return (
            <bs-list-group-item actionable={true} bg-color={this.alternateRow == 'odd' ? '#f3f3f3' : 'fafafa'} class="anim-shadow">
                <div class="container-fluid" style={{ paddingLeft: '0', paddingRight: '0' }}>
                    <div class="row">
                        {this.selectable && (
                            <div class="px-3">
                                <bs-form-check type="checkbox" size={16} checked={this.selected} onBsInput={e => this.handleItemSelect(e.detail.checked)} />
                            </div>
                        )}

                        <div class="col">
                            <div class="mb-3 d-flex align-items-center">
                                <span class="date">
                                    {createdDate}

                                    {this.showSharedBy && <span class="sharedby">Shared by: {this.item?.sharedBy}</span>}
                                </span>

                                <bs-icon class="mx-4" icon={`fab ${serviceConfig.icon}`} size={16} />

                                <a class="label" href={this.item?.url} title={serviceConfig.description} onClick={event => this.handleLabelClick(event)}>
                                    {this.item?.label || this.item?.url}
                                </a>
                            </div>

                            <div class="tags">
                                {this.item?.tags && (
                                    <gd-tag-input
                                        defaultValue={this.item?.tags}
                                        variant="pills"
                                        placeholder="Add tag..."
                                        onTagsChange={(e: any) => this.handleTagsChange(e.detail)}
                                    />
                                )}
                            </div>
                        </div>

                        <div class="col-2">
                            <div class="buttons mb-3 d-flex align-items-center justify-content-end">
                                {this.allowEdit && (
                                    <bs-button class="edit ml-3" variant="link" onClick={() => this.editItem.emit(this.item)} title="Edit">
                                        <bs-icon icon="fab fa-edit" size={16} style={{ color: '#333' }} class="anim-scale"></bs-icon>
                                    </bs-button>
                                )}

                                {this.allowFavorite && (
                                    <bs-button class="favorite ml-3" variant="link" onClick={() => this.handleToggleFavorite()} title="Favorite">
                                        <bs-icon
                                            icon={`${this.item?.favorite ? 'fab' : 'fas'} fa-heart`}
                                            size={16}
                                            style={{ color: this.item?.favorite ? '#333' : '#333' }}
                                            class="anim-scale"
                                        ></bs-icon>
                                    </bs-button>
                                )}

                                {this.allowDelete && (
                                    <bs-button class="delete ml-3" variant="link" onClick={() => this.handleDelete()} title="Delete">
                                        <bs-icon icon="fab fa-trash-alt" size={16} style={{ color: '#333' }} class="anim-scale"></bs-icon>
                                    </bs-button>
                                )}
                            </div>
                        </div>
                    </div>
                </div>
            </bs-list-group-item>
        )
    }

    /**
     * if needed, will block the link click and use the labelClick event instead. labelClick is used if:
     *  - the followUrl prop is false
     *
     * @param event
     */
    private handleLabelClick(event) {
        if (!this.followUrl) {
            event.preventDefault() // stop browser from following the link
            this.labelClick.emit(this.item)
            return // not really needed, but lets explicitly return
        }
    }

    /**
     * updates visual favorite state and emits toggle event
     */
    private handleToggleFavorite() {
        this.updateItem.emit({
            ...this.item,
            favorite: !this.item.favorite,
        })
    }

    /**
     * emits delete event after user confirmation
     */
    private handleDelete() {
        if (!confirm('Are you sure you want to delete this history item?')) {
            return
        }

        this.deleteItem.emit(this.item)
    }

    // emits update event with updated tags
    private handleTagsChange(tags) {
        this.updateItem.emit({
            ...this.item,
            tags,
        })
    }

    // emits itemSelected event with selected state
    private handleItemSelect(checked) {
        this.itemSelected.emit({
            selected: checked,
            historyItem: this.item,
        })
    }
}
