import { ObservableMap, action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { Utils, returnZero } from '../../../Utils';
import { Doc, DocListCast, Field } from '../../../fields/Doc';
import { Id } from '../../../fields/FieldSymbols';
import { NumCast, ScriptCast, StrCast, BoolCast } from '../../../fields/Types';
import { DragManager } from '../../util/DragManager';
import { SelectionManager } from '../../util/SelectionManager';
import { StyleProp } from '../StyleProvider';
import { DocumentView } from '../nodes/DocumentView';
import './CollectionCardDeckView.scss';
import { CollectionSubView } from './CollectionSubView';
import { Transform } from '../../util/Transform';
import { indexes } from 'd3';

@observer
export class CollectionCardView extends CollectionSubView() {
    @observable selectedNodeIndex = -1;

    @observable hoveredNodeIndex = -1;

    @action
    setHoveredNodeIndex = (index: number) => {
        if (!this.isSelected(index)){
        this.hoveredNodeIndex = index;
        }
    };

    translateHover = (index: number): number => {
        if (this.hoveredNodeIndex == index && !this.isSelected(index)) {
            return -50;
        }
        return 0;
    };

    @action
    setSelectedNodeIndex = (index: number) => {
        const docs = DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]);
        console.log('goodnight');

        if (SelectionManager.IsSelected(docs[index])) {
            console.log('good mornings');
            this.setSelectedNodeIndex(index);
        }
    };

    isSelected = (index: number): boolean => {
        const docs = DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]);

        return SelectionManager.IsSelected(docs[index]);
    };

    inactiveDocs = () => {
        const docs = DocListCast(this.Document[this.fieldKey ?? Doc.LayoutFieldKey(this.Document)]);

        return docs.filter(d => !SelectionManager.IsSelected(d));
    }

    middleIndex = Math.floor(this.inactiveDocs().length / 2);


    // verticalOffset = (index: number) => {

    //     const distanceFromMiddle = Math.abs(index - this.middleIndex);
    //     // Adjust '4' to control the curvature; larger values create a flatter arc.
    //     return Math.pow(distanceFromMiddle, 2)* (Math.floor(64/this.inactiveDocs().length)); // Example quadratic function
    //   };




    constructor(props: any) {
        super(props);
        makeObservable(this);
        // this.rotationDegree(7);
    }

    private _dropDisposer?: DragManager.DragDropDisposer;

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

    protected createDashEventsTarget = (ele: HTMLDivElement | null) => {
        this._dropDisposer?.();
        if (ele) {
            this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc);
        }
    };

    panelWidth = () => this._props.PanelWidth() / this.childLayoutPairs.length;
    panelHeight = () => this.panelWidth() * 1.5;
    onChildDoubleClick = () => ScriptCast(this.layoutDoc.onChildDoubleClick);
    isContentActive = () => this._props.isSelected() || this._props.isContentActive() || this._props.isAnyChildContentActive();
    isChildContentActive = () => (this.isContentActive() ? true : false);


    rotate = (amCards: number, index: number) => {
        const possRotate = -30 + index * (30 / ((amCards - (amCards % 2)) / 2));

        if (amCards % 2 == 0 && possRotate == 0) {
            console.log('whaddup');
            return possRotate + Math.abs(-30 + (index - 1) * (30 / ((amCards - 1) / 2)));
        }

        return possRotate;
    };

    // translateY = (amCards: number, index: number) => {
    //     // Assuming you want a default value when index > amCards/2
    //     // Adjust the logic as necessary for your use case
    //     if (index <= amCards / 2) {
    //         return -((50 / ((amCards - (amCards % 2)) / 2)) * index);
    //     } else {
    //         // Return a default or calculated value for indices greater than amCards/2
    //         // This is just an example; adjust the logic as needed
    //         return -((50 / ((amCards - (amCards % 2)) / 2)) * (amCards - index - 1));
    //     }
    // };


    translateSelected = (index: number): number => {
        if (this.isSelected(index)){
            const middleOfPanel = this._props.PanelWidth() / 2;
            const scaledNodeWidth = this.panelWidth() * 1.25;
            
            // Calculate the position of the node's left edge before scaling
            const nodeLeftEdge = index * this.panelWidth();
            // Find the center of the node after scaling
            const scaledNodeCenter = nodeLeftEdge + (scaledNodeWidth / 2);
            
            // Calculate the translation needed to align the scaled node's center with the panel's center
            const translation = middleOfPanel - scaledNodeCenter;
    
            return translation;
        }
    
        return 0;
    };

    @computed get sortedDocs() {
        const field = StrCast(this.layoutDoc.sortField);
        const desc = BoolCast(this.layoutDoc.sortDesc);
        const docs = !field
            ? this.childDocs
            : [...this.childDocs].sort((docA, docB) => {
                  const aStr = Field.toString(docA[field] as Field);
                  const bStr = Field.toString(docB[field] as Field);
                  var out = 0;
                  if (aStr < bStr) out = -1;
                  if (aStr > bStr) out = 1;
                  if (desc) out *= -1;
                  return out;
              });
        return { docs };
    }



    @observable docRefs = new ObservableMap<Doc, DocumentView>();

    @computed get content() {
        // const currentIndex = NumCast(this.layoutDoc._carousel_index);
        const amCards = this.inactiveDocs().length;
        // const myInactives = 
        const displayDoc = (childPair: { layout: Doc; data: Doc }, screenToLocalTransform: () => Transform) => {
            return (
                <DocumentView
                    {...this._props}
                    ref={action((r: DocumentView) => r?.ContentDiv && this.docRefs.set(childPair.layout, r))}
                    Document={childPair.layout}
                    TemplateDataDocument={childPair.data}
                    // onClickScript={this.toggleIcon}
                    //suppressSetHeight={true}
                    NativeWidth={returnZero}
                    NativeHeight={returnZero}
                    layout_fitWidth={undefined}
                    onDoubleClickScript={this.onChildDoubleClick}
                    renderDepth={this._props.renderDepth + 1}
                    LayoutTemplate={this._props.childLayoutTemplate}
                    LayoutTemplateString={this._props.childLayoutString}
                    // focus={this.focus}
                    ScreenToLocalTransform={screenToLocalTransform} //makes sure the box wrapper thing is in the right spot
                    isContentActive={this.isChildContentActive}
                    isDocumentActive={this._props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this._props.isDocumentActive : this.isContentActive}
                    PanelWidth={this.panelWidth}
                    PanelHeight={this.panelHeight}
                />
            );
        };

        return this.childLayoutPairs.map((childPair, index) => {
            const isSelected = this.isSelected(index);
            const isHovered = this.hoveredNodeIndex === index;
            const inactiveIndex = this.inactiveDocs().indexOf(childPair.layout);
            // const yOffset = this.verticalOffset(index);


            const childScreenToLocal = () => {
                const dref = this.docRefs.get(childPair.layout);
                const { translateX, translateY } = Utils.GetScreenTransform(dref?.ContentDiv);
                // the document view may center its contents and if so, will prepend that onto the screenToLocalTansform.  so we have to subtract that off
                return new Transform(-translateX + (dref?.centeringX || 0), -translateY + (dref?.centeringY || 0), 1).scale(1 / (isSelected ? 1.25 : 1)).rotate(!isSelected ? -this.rotate(amCards, inactiveIndex) : 0);
            };

            return (
                <div
                    key={childPair.layout[Id]}
                    className={`card-item${isSelected ? '-active' : ''}`}
                    style={{
                        width: this.panelWidth(),
                        height: this.panelHeight(),
                        transform: 
                            `
                            rotate(${!isSelected ? this.rotate(amCards, inactiveIndex) : 0}deg) 
                            translateY(${isHovered ? this.translateHover(index) : isSelected ? 50 : 0}px)
                            translateX(${isSelected ? ((this._props.PanelWidth() / 2) - ((this.panelWidth())/2) - (this.panelWidth()/2)) : 0}px)

                            scale(${isSelected ? 1.25 : 1})
                            
                            ` //scale has to be applied last or selected offset gets messed up

                    ,
                    }}





                    // onClick={() => this.setSelectedNodeIndex(index)}

                    onMouseEnter={() => this.setHoveredNodeIndex(index)}
                    >
                    {/* {this.lol(childPair.data, index)} */}

                    {displayDoc(childPair, childScreenToLocal)}
                </div>
            );
        });
    }

    @computed get translateWrapperX() {

        if (this.inactiveDocs().length != this.childLayoutPairs.length){
            return this.panelWidth()/2
        }

        return 0;
    }

    render() {
        return (
            <div
                className="collectionCardView-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),
                }}>
                <div
                    className="card-wrapper"
                    style={{ transform: `translateX(${this.translateWrapperX}px)`,
                    //  height: this.panelHeight() 
                    }}
                    onMouseLeave={() => this.setHoveredNodeIndex(-1)}
                >
                    {this.content}
                </div>

                {/* {this.focusContent} */}


            </div>
        );
    }
}
