// 假设以下接口和类的定义
interface IPage {
    OwnerContainer: PageContainer;
}

interface PageContainer {
    ActualWidth: number;
    ActualHeight: number;
    PointToScreen(point: { x: number; y: number }): { x: number; y: number };
    SizeChanged: Event;
}

interface TradePage {
    // 可根据实际情况补充属性和方法
}

interface ImageSource {
    // 可根据实际情况补充属性和方法
}

interface FocusManager {
    GetManagerInstance(tradePage: TradePage): FocusManager | null;
    SetFocus(element: HTMLElement): void;
    CanAcceptUserInput: boolean;
}

class PageDialogBase {
    // 可根据实际情况补充属性和方法
}

// 枚举定义
enum AnimationDirection {
    RightToLeft = 0,
    LeftToRight = 1,
    TopToBottom = 2,
    BottomToTop = 3
}

enum AnimationType {
    Start = 0,
    End = 1
}

export class PageMessageBoxMetro extends PageDialogBase {
    private static readonly Offset = 45;
    private static readonly ShortAnimationTime = 0.5;
    private static readonly LongAnimationTime = 1;

    private readonly _caption: string;
    private readonly _msg: object;
    private _animationEnable = true;
    private _buttonGroup: HTMLElement | null = null;
    private _endLocation = 0;
    private _rootGrid: HTMLElement | null = null;
    private _rootTradePage: TradePage | null = null;
    private _startLocation = 0;
    private _txtMsg: HTMLElement | null = null;
    private _txtTitle: HTMLElement | null = null;

    public MessageDialogResult: string = '';
    public OwnerPage: IPage | null = null;
    public ContentStr: object | null = null;
    public DefaultButton: string | null = null;
    public ButtonContents: string[] = [];
    public Direction: number = 0;
    public IsReverse: boolean = false;
    public IsCoverAll: boolean = false;
    public StateIcon: ImageSource | null = null;

    constructor(
        ownerPage: IPage,
        messageBoxText: object,
        caption: string,
        icon: ImageSource,
        direction: number,
        isreverse: boolean,
        iscoverall: boolean,
        animationenable: boolean,
        defaultButton: string | null = null,
        ...buttonConent: string[]
    ) {
        super();
        if (buttonConent.length === 0) {
            buttonConent = ['确定'];
        }
        this.ButtonContents = buttonConent;
        this.OwnerPage = ownerPage;
        this.ContentStr = messageBoxText;
        this.DefaultButton = defaultButton;
        this.StateIcon = icon;
        this.Direction = direction;
        this.IsReverse = isreverse;
        this.IsCoverAll = iscoverall;
        this._animationEnable = animationenable;
        this._msg = messageBoxText;
        this._caption = caption;
        // 模拟 InternalOpen 方法
        this.internalOpen(ownerPage, this);
    }

    private internalOpen(ownerPage: IPage, self: PageMessageBoxMetro) {
        // 模拟加载完成事件
        setTimeout(() => this.pageMessageBoxMetroLoaded(), 0);
    }

    public onApplyTemplate() {
        this._txtMsg = document.getElementById('TxtMessage');
        this._txtTitle = document.getElementById('TxtTitle');
        this._buttonGroup = document.getElementById('ButtonGroup');
        // 假设 rootTradePage 和 rootGrid 是 HTML 元素
        this._rootTradePage = null; // 需根据实际情况实现
        this._rootGrid = document.getElementById('rootGrid');
    }

    private pageMessageBoxMetroLoaded() {
        try {
            if (this._txtMsg) this._txtMsg.textContent = String(this._msg);
            if (this._txtTitle) this._txtTitle.textContent = this._caption;

            if (this.OwnerPage) {
                const ownerContainer = this.OwnerPage.OwnerContainer;
                const topContainer = this.getTopContainer() || ownerContainer;
                const width = this.IsCoverAll ? topContainer.ActualWidth : ownerContainer.ActualWidth + PageMessageBoxMetro.Offset;
                const maxHeight = topContainer.ActualHeight / 1.5;

                const handler = () => {
                    if (this._rootGrid) this._rootGrid.style.width = `${topContainer.ActualWidth * 0.6}px`;
                    if (this._animationEnable) {
                        this.getAnimationLocation(topContainer);
                        this.animationLocation(AnimationType.Start, AnimationDirection[this.Direction] as AnimationDirection);
                    } else {
                        const container = topContainer;
                        switch (AnimationDirection[this.Direction]) {
                            case AnimationDirection.BottomToTop:
                                this.setPosition(container.ActualWidth - width, container.ActualHeight - this.getHeight());
                                break;
                            case AnimationDirection.TopToBottom:
                                this.setPosition(container.ActualWidth - width, 0);
                                break;
                            case AnimationDirection.RightToLeft:
                                const pageContainerPointRight = container.PointToScreen({ x: 0, y: 0 });
                                this.setPosition(container.ActualWidth - width, pageContainerPointRight.y + (container.ActualHeight - this.getHeight()) / 2);
                                break;
                            case AnimationDirection.LeftToRight:
                                const pageContainerPointLeft = container.PointToScreen({ x: 0, y: 0 });
                                this.setPosition(container.ActualWidth - width, pageContainerPointLeft.y + (container.ActualHeight - this.getHeight()) / 2);
                                break;
                        }
                    }
                };

                // 模拟 SizeChanged 事件
                window.addEventListener('resize', handler);
                // 模拟 Closed 事件
                // 需根据实际情况实现关闭逻辑
                // this.Closed += () => window.removeEventListener('resize', handler);

                // 第一次加载，触发一次定位
                handler();

                if (this.ButtonContents) {
                    this.ButtonContents.forEach(item => {
                        const btn = document.createElement('button');
                        btn.textContent = item;
                        btn.style.margin = '10px 2px 10px 2px';
                        btn.addEventListener('click', () => {
                            this.MessageDialogResult = btn.textContent;
                            if (this._animationEnable) {
                                this.animationLocation(AnimationType.End, AnimationDirection[this.Direction] as AnimationDirection);
                            } else {
                                // 模拟关闭逻辑
                                this.close();
                            }
                        });
                        if (this._buttonGroup) this._buttonGroup.appendChild(btn);
                    });
                }

                if (this._buttonGroup && this._buttonGroup.children.length > 0) {
                    if (this._rootTradePage) {
                        setTimeout(() => {
                            let findButton: HTMLElement | null = null;
                            this.preOrder(document.body, this.DefaultButton, (result) => findButton = result as HTMLElement);
                            const focus = FocusManager.GetManagerInstance(this._rootTradePage);
                            if (focus && findButton) focus.SetFocus(findButton);
                        }, 0);
                    }
                } else {
                    document.addEventListener('keydown', (e) => {
                        this.close();
                        e.preventDefault();
                    });
                }
            }
        } catch (ex) {
            console.error('PageMessageBoxMetro加载发生异常！', ex);
        }
    }

    private animationLocation(type: AnimationType, direction: AnimationDirection) {
        const duration = this.IsReverse ? PageMessageBoxMetro.ShortAnimationTime : PageMessageBoxMetro.LongAnimationTime;
        const element = document.querySelector('.page-message-box-metro') as HTMLElement;
        if (!element) return;

        const keyframes: Keyframe[] = [];
        switch (type) {
            case AnimationType.Start:
                keyframes.push({
                    [this.getAnimationProperty(direction)]: `${this._startLocation}px`,
                    easing: 'ease-in'
                });
                break;
            case AnimationType.End:
                keyframes.push({
                    [this.getAnimationProperty(direction)]: `${this._endLocation}px`,
                    easing: 'ease-in'
                });
                break;
        }

        const animation = element.animate(keyframes, {
            duration: duration * 1000,
            fill: 'forwards'
        });

        animation.onfinish = () => {
            if (type === AnimationType.End) {
                this.close();
            } else if (type === AnimationType.Start) {
                if (this._rootTradePage) {
                    const focus = FocusManager.GetManagerInstance(this._rootTradePage);
                    if (focus) focus.CanAcceptUserInput = true;
                }
            }
        };
    }

    private getAnimationProperty(direction: AnimationDirection): string {
        switch (direction) {
            case AnimationDirection.LeftToRight:
            case AnimationDirection.RightToLeft:
                return 'left';
            case AnimationDirection.TopToBottom:
            case AnimationDirection.BottomToTop:
                return 'top';
            default:
                return 'left';
        }
    }

    private getAnimationLocation(container: PageContainer) {
        const width = this.getWidth();
        const height = this.getHeight();
        switch (AnimationDirection[this.Direction]) {
            case AnimationDirection.BottomToTop:
                this.setPosition(container.ActualWidth - width, container.ActualHeight);
                this._startLocation = container.ActualHeight - height;
                this._endLocation = this.IsReverse ? container.ActualHeight : -height;
                break;
            case AnimationDirection.TopToBottom:
                this.setPosition(container.ActualWidth - width, -height);
                this._startLocation = 0;
                this._endLocation = this.IsReverse ? -height : container.ActualHeight;
                break;
            case AnimationDirection.RightToLeft:
                const pageContainerPointRight = container.PointToScreen({ x: 0, y: 0 });
                this.setPosition(container.ActualWidth, pageContainerPointRight.y + (container.ActualHeight - height) / 2);
                this._startLocation = container.ActualWidth - width;
                this._endLocation = this.IsReverse ? container.ActualWidth : -width;
                break;
            case AnimationDirection.LeftToRight:
                const pageContainerPointLeft = container.PointToScreen({ x: 0, y: 0 });
                this.setPosition(-width, pageContainerPointLeft.y + (container.ActualHeight - height) / 2);
                this._startLocation = container.ActualWidth - width;
                this._endLocation = this.IsReverse ? -width : container.ActualWidth;
                break;
        }
    }

    private preOrder(node: HTMLElement, nodeName: string | null, callback: (result: HTMLElement | null) => void) {
        const buttons = Array.from(node.querySelectorAll('button'));
        const filteredButtons = buttons.filter(btn => btn.style.display !== 'none');
        const findResult = nodeName ? filteredButtons.find(btn => btn.textContent === nodeName) : filteredButtons[0];
        callback(findResult || null);
    }

    private getTopContainer(): PageContainer | null {
        // 需根据实际情况实现
        return null;
    }

    private getWidth(): number {
        const element = document.querySelector('.page-message-box-metro') as HTMLElement;
        return element ? element.offsetWidth : 0;
    }

    private getHeight(): number {
        const element = document.querySelector('.page-message-box-metro') as HTMLElement;
        return element ? element.offsetHeight : 0;
    }

    private setPosition(left: number, top: number) {
        const element = document.querySelector('.page-message-box-metro') as HTMLElement;
        if (element) {
            element.style.left = `${left}px`;
            element.style.top = `${top}px`;
        }
    }

    private close() {
        const element = document.querySelector('.page-message-box-metro') as HTMLElement;
        if (element) element.remove();
    }
}