import { Component, h, Event, EventEmitter, State, Prop, Element, Watch } from '@stencil/core'
import { defer } from '../../shared/utils'

export type ShareOptions = {
    description: string
}

export type Share = {
    options: ShareOptions
    historyItemIds: string[]
    generateShareUrl: Promise<string>
}

@Component({
    tag: 'gd-user-dashboard-share-dialog',
    styleUrl: 'gd-user-dashboard-share-dialog.scss',
    shadow: true,
})
export class GdUserDashboardShareDialog {
    /**
     * the history items to share
     */
    @Prop() historyItemIds: string[] = []

    /**
     * when to show the dialog
     */
    @Prop() show: boolean = false

    /**
     * event emitted when the dialog is closed
     */
    @Event() closed: EventEmitter<void>

    /**
     * event emitted to share items
     */
    @Event() share: EventEmitter<Share>

    /**
     * a set of options that will be used to share the history items
     */
    @State() shareOptions: ShareOptions

    /**
     * the generated share URL
     */
    @State() shareUrl: string

    /**
     * a visual state to show loading
     */
    @State() working: boolean = false

    @State() copiedToClipboard: boolean = false

    @State() showErrors: boolean = false

    @Element() el: HTMLElement

    shareUrlEl: any

    @Watch('show')
    setShareOptions() {
        if (this.show) {
            this.shareOptions = { description: '' }
        }
    }

    handleChange(event) {
        this.shareOptions[event.detail.target.name] = event.detail.target.value
    }

    handleClose() {
        if (this.working) return
        this.showErrors = false
        this.copiedToClipboard = false
        this.shareUrl = ''
        this.el.shadowRoot.querySelector('bs-modal').closeDialog()
    }

    async shareItems() {
        this.showErrors = true

        if (!this.shareOptions?.description) return

        this.working = true

        // create a new promise that will be resolved by the application
        let generateShareUrl = defer()

        // notify the application using the component to share these history items
        this.share.emit({
            options: this.shareOptions,
            historyItemIds: this.historyItemIds,
            generateShareUrl,
        })

        try {
            // wait for a response from the application
            this.shareUrl = await generateShareUrl
        } catch (err) {
            console.error('Encountered a problem generating the share URL ', err)
        } finally {
            this.working = false
        }
    }

    copyShareUrlToClipboard() {
        if (!this.shareUrlEl) return

        this.shareUrlEl.shadowRoot.querySelector('textarea').select()
        document.execCommand('copy')
        this.copiedToClipboard = true
    }

    /**
     * renders the dialog
     */
    render() {
        return (
            <bs-modal show={this.show} onClose={() => this.closed.emit()}>
                {this.shareUrl ? (
                    <bs-modal-header modal-title={`<bs-icon size="20" class="mr-2" icon="fab fa-link"></bs-icon> Shared Link`} />
                ) : (
                    <bs-modal-header modal-title={`<bs-icon size="20" class="mr-2" icon="fab fa-share"></bs-icon> Share ${this.historyItemIds.length} Items`} />
                )}

                <bs-modal-body>
                    {this.shareUrl ? (
                        <bs-form-row>
                            <bs-form-group>
                                <bs-form-label>Share URL</bs-form-label>

                                <bs-form-control 
                                    controlId="shareUrl" 
                                    as="textarea" 
                                    name="shareUrl"
                                    value={this.shareUrl}
                                    readOnly
                                    ref={(el) => this.shareUrlEl = el}
                                />

                                {this.copiedToClipboard && <span>Copied to clipboard!</span>}
                                {!this.copiedToClipboard && <a href="javascript:;" onClick={this.copyShareUrlToClipboard.bind(this)}>Copy to clipboard</a>}
                            </bs-form-group>
                        </bs-form-row>
                    ) : (
                        <bs-form-row>
                            <bs-form-group>
                                <bs-form-label>Description</bs-form-label>

                                <bs-form-control
                                    control-id="description"
                                    as="input"
                                    name="description"
                                    type="text"
                                    value={this.shareOptions?.description}
                                    required
                                    onBsInput={this.handleChange.bind(this)}
                                    is-invalid={this.showErrors && !this.shareOptions?.description}
                                />

                                {this.showErrors && !this.shareOptions?.description && <div class="text-danger">Description required</div>}
                            </bs-form-group>
                        </bs-form-row>
                    )}
                </bs-modal-body>

                {this.shareUrl ? (
                    <bs-modal-footer>
                        <bs-button variant="secondary" onClick={this.handleClose.bind(this)}>
                            Close
                        </bs-button>
                    </bs-modal-footer>
                ) : (
                    <bs-modal-footer>
                        <bs-button variant="secondary" onClick={this.handleClose.bind(this)} disabled={this.working}>
                            Cancel
                        </bs-button>

                        {this.working ? (
                            <bs-button variant="primary" disabled>
                                <bs-spinner aria-hidden="true" size="sm"></bs-spinner>
                                <span class="ml-2">Generating link...</span>
                            </bs-button>
                        ) : (
                            <bs-button variant="primary" onClick={this.shareItems.bind(this)}>
                                Generate Link
                            </bs-button>
                        )}
                    </bs-modal-footer>
                )}
            </bs-modal>
        )
    }
}
