import { BaseSelfControl } from "../SelfModels/BaseSelfControl";
import { BasePageData, PropsOfPage, StackHeaderFields } from "../Page/BasePageData";
import { Callback } from "../Types";
import { StackFactory } from "./Stack";
import { PageEventType } from "../Page/Events";
import { INaming } from "../NamingCaption";
import { TabPageData } from "../Page/Tab/TabData";
import { IArmisaPageKey } from "../ArmisaImportPage";

export class MainStacksFactory {
    public initializeFormStartPage: boolean = false;
    public initializeHookStartPage: boolean = false;
    public initializeTabsOfStacks: boolean = false;
    public initializeStatusBarIcons: boolean = false;
    public initializeTabPage: boolean = false;
    public currentStackMainDivHeadRef: React.RefObject<HTMLDivElement> | undefined;
    public currentStackMainDivBodyRef: React.RefObject<HTMLDivElement> | undefined;
    public currentStackMainDivHead: HTMLDivElement | null = null;

    updateTextOfStackHeaderInitial = () => {
        let currentPageData: BasePageData;
        if (this.currentStack) {
            currentPageData = this.currentStack.pageData;
        } else {
            currentPageData = this.pageData;
        }
        if (currentPageData.selfState && currentPageData.selfState.inittializeStackHeaderText) {
            if (!(currentPageData.stackHeaderFields && currentPageData.stackHeaderFields.length)) {
                currentPageData.selfState.inittializeStackHeaderText().forEach((i: StackHeaderFields) => { currentPageData.addStackHeadersField(i) });
            }
        }
        if (currentPageData.stackHeaderFields && currentPageData.stackHeaderFields.length) {
            let stackHeaderText = '';
            currentPageData.stackHeaderFields.forEach(i => {
                const caption = i.caption ? i.caption + ':' : '';
                const field = currentPageData.selfState[i.fieldName];
                let value;
                if (field instanceof BaseSelfControl) {
                    value = field.value ? field.value.toString() : '';
                } else if (typeof field === 'string') {
                    value = field;
                } else if (typeof field === 'number') {
                    value = field.toString();
                }
                if (value) {
                    if (value.length > 20) {
                        value = (value as string).substring(0, 17) + '...';
                    }
                    if (stackHeaderText) {
                        stackHeaderText += ' - ' + caption + value;
                    } else {
                        stackHeaderText += caption + value;
                    }
                }
            });

            if (stackHeaderText) {
                if (!currentPageData.defaultCaptionOfPage) {
                    currentPageData.defaultCaptionOfPage = currentPageData.caption;
                }
                currentPageData.caption = stackHeaderText;
                this.trigger('stack.header.text.refresh');
            } else if (currentPageData.defaultCaptionOfPage) {
                currentPageData.caption = currentPageData.defaultCaptionOfPage;
                this.trigger('stack.header.text.refresh');
            }
        }

    }
    updateTextOfStackHeader = (changeHeadOfStack?: number) => {
        if (typeof changeHeadOfStack !== 'number') {
            return;
        }

        let currentPageData: BasePageData;
        if (this.currentStack) {
            currentPageData = this.currentStack.pageData;
        } else {
            currentPageData = this.pageData;
        }
        if (currentPageData.stackHeaderFields && currentPageData.stackHeaderFields.length) {
            let stackHeaderText = '';
            currentPageData.stackHeaderFields.forEach(i => {
                const caption = i.caption ? i.caption + ':' : '';
                const field = currentPageData.selfState[i.fieldName];
                let value;
                if (field instanceof BaseSelfControl) {
                    value = field.value ? field.value.toString() : '';
                }
                if (value) {
                    if (value.length > 20) {
                        value = (value as string).substring(0, 17) + '...';
                    }
                    if (stackHeaderText) {
                        stackHeaderText += ' - ' + caption + value;
                    } else {
                        stackHeaderText += caption + value;
                    }
                }
            });

            if (stackHeaderText) {
                if (!currentPageData.defaultCaptionOfPage) {
                    currentPageData.defaultCaptionOfPage = currentPageData.caption;
                }
                currentPageData.caption = stackHeaderText;
                this.trigger('stack.header.text.refresh');
            } else if (currentPageData.defaultCaptionOfPage) {
                currentPageData.caption = currentPageData.defaultCaptionOfPage;
                this.trigger('stack.header.text.refresh');
            }
        }
    }

    constructor(
        public pageData: BasePageData,
    ) {
    }

    public stacks: StackFactory[] = [];
    public currentStack?: StackFactory;

    gotoMainStack = () => {
        if (!this.currentStack) {
            return;
        }
        this.currentStack.stackWillUnMount();
        this.currentStack.pageData.stackHeaderFields = undefined;
        this.currentStack = undefined;

        this.trigger('stack.get.active');
    }

    selectThisStack = (stack: StackFactory) => {
        if (this.currentStack === stack) {
            return;
        }
        if (this.currentStack) {
            this.currentStack.stackWillUnMount();
            stack.pageData.stackHeaderFields = undefined;
        }

        this.currentStack = stack as any;
        this.trigger('stack.get.active', stack);
    };

    closeThisStack = (stack: StackFactory) => {
        stack.stackWillUnMount();
        stack.isDeleted = this.stacks.filter((s) => s.isDeleted).length + 1;
        let notDeleted = this.stacks.filter((s) => !s.isDeleted);
        if (notDeleted.length) {
            this.currentStack = notDeleted[notDeleted.length - 1] as any;
            this.currentStack!.pageData.stackHeaderFields = undefined;
        } else {
            this.currentStack = undefined;
        }
        stack.pageData.stackHeaderFields = undefined;

        this.trigger('stack.closed', stack);
    };

    trigger = (eventName: PageEventType, ...args: any) => {
        this.pageData.Eventing.triggerControl(eventName, `stack-${this.pageData.id}-0`, args);
    }

    on = (eventName: PageEventType, callBack: Callback) => {
        this.pageData.Eventing.onControl(eventName, `stack-${this.pageData.id}-0`, callBack);
    }

    removeOn = (eventName: PageEventType) => {
        this.pageData.Eventing.removeOnControl(eventName, `stack-${this.pageData.id}-0`);
    }


    addNewStack: {
        (pageKey: IArmisaPageKey, props?: PropsOfPage, caption?: INaming, stackHeaderFields?: undefined): void;
        (pageKey: IArmisaPageKey, props?: PropsOfPage, caption?: string, stackHeaderFields?: undefined): void;
        (pageKey: IArmisaPageKey, props?: PropsOfPage, caption?: undefined, stackHeaderFields?: StackHeaderFields[]): void;
    } = (...args: [any, (PropsOfPage | undefined), (INaming | string | undefined), (StackHeaderFields[] | undefined)]): void => {
        const [pageKey, props, caption, stackHeaderFields] = args;
        const newTab = new TabPageData(this.pageData.mainStateManager);
        const stackFactory = new StackFactory(newTab, this);

        newTab.pageKey = pageKey;
        newTab.props = props;
        if (typeof caption === 'string') {
            newTab.caption = caption;
        } else if (caption instanceof Array) {
            newTab.caption = this.pageData.mainStateManager.getCaptionNaming(caption);
        } else {
            // newTab.caption = this.pageData.mainStateManager.MenuIteming.getCaptionOfPage(newTab.pageKey);
        }

        if (stackHeaderFields) {
            if (stackHeaderFields instanceof Array) {
                stackHeaderFields.forEach(i => {
                    if (i instanceof StackHeaderFields) {
                        newTab.addStackHeadersField(i);
                    }
                })
            }
        }

        if (props) {
            if (props.headId) {
                newTab.caption += ` ${props.headId}`;
            }
        }

        newTab.mainStacksFactory = this;
        this.stacks.push(stackFactory);
        this.currentStack = stackFactory;
        this.trigger('stack.add.new', newTab);
    }

    static buildNew(pageData: BasePageData) {
        return new MainStacksFactory(pageData);
    }
}