import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { computed } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc, Opt } from '../../../fields/Doc';
import { NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { emptyFunction, returnFalse, returnZero, StopEvent } from '../../../Utils';
import { DragManager } from '../../util/DragManager';
import { DocumentView, DocumentViewProps } from '../nodes/DocumentView';
import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
import { StyleProp } from '../StyleProvider';
import './CollectionCarouselView.scss';
import { CollectionSubView } from './CollectionSubView';

@observer
export class CollectionCarouselView extends CollectionSubView() {
    private _dropDisposer?: DragManager.DragDropDisposer;

    componentWillUnmount() {
        this._dropDisposer?.();
    }

    protected createDashEventsTarget = (ele: HTMLDivElement | null) => {
        //used for stacking and masonry view
        this._dropDisposer?.();
        if (ele) {
            this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc);
        }
    };

    advance = (e: React.MouseEvent) => {
        e.stopPropagation();
        this.layoutDoc._itemIndex = (NumCast(this.layoutDoc._itemIndex) + 1) % this.childLayoutPairs.length;
    };
    goback = (e: React.MouseEvent) => {
        e.stopPropagation();
        this.layoutDoc._itemIndex = (NumCast(this.layoutDoc._itemIndex) - 1 + this.childLayoutPairs.length) % this.childLayoutPairs.length;
    };
    captionStyleProvider = (doc: Doc | undefined, captionProps: Opt<DocumentViewProps>, property: string): any => {
        // first look for properties on the document in the carousel, then fallback to properties on the container
        const childValue = doc?.['caption-' + property] ? this.props.styleProvider?.(doc, captionProps, property) : undefined;
        return childValue ?? this.props.styleProvider?.(this.layoutDoc, captionProps, property);
    };
    panelHeight = () => this.props.PanelHeight() - (StrCast(this.layoutDoc._showCaption) ? 50 : 0);
    onContentDoubleClick = () => ScriptCast(this.layoutDoc.onChildDoubleClick);
    onContentClick = () => ScriptCast(this.layoutDoc.onChildClick);
    @computed get content() {
        const index = NumCast(this.layoutDoc._itemIndex);
        const curDoc = this.childLayoutPairs?.[index];
        const captionProps = { ...this.props, fieldKey: 'caption', setHeight: undefined };
        const marginX = NumCast(this.layoutDoc['caption-xMargin']);
        const marginY = NumCast(this.layoutDoc['caption-yMargin']);
        const showCaptions = StrCast(this.layoutDoc._showCaption);
        return !(curDoc?.layout instanceof Doc) ? null : (
            <>
                <div className="collectionCarouselView-image" key="image">
                    <DocumentView
                        {...this.props}
                        NativeWidth={returnZero}
                        NativeHeight={returnZero}
                        onDoubleClick={this.onContentDoubleClick}
                        onClick={this.onContentClick}
                        hideCaptions={showCaptions ? true : false}
                        renderDepth={this.props.renderDepth + 1}
                        LayoutTemplate={this.props.childLayoutTemplate}
                        LayoutTemplateString={this.props.childLayoutString}
                        Document={curDoc.layout}
                        DataDoc={curDoc.layout.resolvedDataDoc as Doc}
                        PanelHeight={this.panelHeight}
                        bringToFront={returnFalse}
                    />
                </div>
                <div
                    className="collectionCarouselView-caption"
                    key="caption"
                    onWheel={StopEvent}
                    style={{
                        display: showCaptions ? undefined : 'none',
                        borderRadius: this.props.styleProvider?.(this.layoutDoc, captionProps, StyleProp.BorderRounding),
                        marginRight: marginX,
                        marginLeft: marginX,
                        width: `calc(100% - ${marginX * 2}px)`,
                    }}>
                    <FormattedTextBox key={index} {...captionProps} allowScroll={true} fieldKey={showCaptions} styleProvider={this.captionStyleProvider} Document={curDoc.layout} DataDoc={undefined} />
                </div>
            </>
        );
    }
    @computed get buttons() {
        return (
            <>
                <div key="back" className="carouselView-back" onClick={this.goback}>
                    <FontAwesomeIcon icon={'chevron-left'} size={'2x'} />
                </div>
                <div key="fwd" className="carouselView-fwd" onClick={this.advance}>
                    <FontAwesomeIcon icon={'chevron-right'} size={'2x'} />
                </div>
            </>
        );
    }

    render() {
        return (
            <div
                className="collectionCarouselView-outer"
                ref={this.createDashEventsTarget}
                style={{
                    background: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor),
                    color: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Color),
                }}>
                {this.content}
                {this.props.Document._chromeHidden ? null : this.buttons}
            </div>
        );
    }
}
