// 模拟 WPF 相关类型和接口
interface IPage {
    OwnerContainer: PageContainer;
}

interface FrameworkElement {
    Loaded: EventEmitter;
    Unloaded: EventEmitter;
    IsEnabled: boolean;
    PointToScreen(point: { x: number; y: number }): { x: number; y: number };
    ActualWidth: number;
    ActualHeight: number;
}

interface PageContainer extends FrameworkElement {
    IsVisible: boolean;
    IsBusy: boolean;
    IsOverlay: boolean;
    Loaded: EventEmitter;
    Unloaded: EventEmitter;
    SizeChanged: EventEmitter;
}

interface Window {
    Owner: Window | null;
    Closing: EventEmitter;
    Left: number;
    Top: number;
    Width: number;
    Height: number;
    Show(): void;
    ShowDialog(): void;
    Hide(): void;
    Close(): void;
    WindowStartupLocation: 'CenterScreen' | 'CenterOwner';
    ShowInTaskbar: boolean;
    UpdateLayout(): void;
}

class EventEmitter {
    private listeners: ((...args: any[]) => void)[] = [];

    on(listener: (...args: any[]) => void) {
        this.listeners.push(listener);
    }

    off(listener: (...args: any[]) => void) {
        const index = this.listeners.indexOf(listener);
        if (index!== -1) {
            this.listeners.splice(index, 1);
        }
    }

    emit(...args: any[]) {
        this.listeners.forEach(listener => listener(...args));
    }
}

// 模拟 FocusManager
namespace Presentation {
    export namespace FocusManagers {
        export class FocusManager {
            static GetManagerInstance(page: any) {
                // 模拟实现
                return {
                    SetFocus(element: FrameworkElement) {
                        // 模拟设置焦点
                    }
                };
            }
        }
    }
}

// 模拟 TradePage
class TradePage extends FrameworkElement {
    Ready: EventEmitter = new EventEmitter();
    IsLoaded: boolean = false;
}

// 模拟 Native API
namespace NativeAPI {
    export function GetSystemMenu(hWnd: number, bRevert: boolean) {
        return 0;
    }

    export function EnableMenuItem(hMenu: number, uIDEnableItem: number, uEnable: number) {
        return true;
    }
}

abstract class PageDialogBase implements Window {
    // 常量
    private static readonly SC_CLOSE = 61536;
    private static readonly MF_DISABLED = 2;
    private static readonly MF_GRAYED = 1;

    // 字段
    private _dispatcherFrame: any;
    private _element: FrameworkElement | null = null;
    private _ownerContainer: PageContainer | null = null;
    private _ownerPage: IPage | null = null;
    private _defaultFocus: string = 'Return';

    // 属性
    public DefaultFocus: string = 'Return';
    public IsEnableFocusControl: boolean = true;
    public IsModal: boolean = true;
    public Owner: Window | null = null;
    public Left: number = 0;
    public Top: number = 0;
    public Width: number = 0;
    public Height: number = 0;
    public WindowStartupLocation: 'CenterScreen' | 'CenterOwner' = 'CenterScreen';
    public ShowInTaskbar: boolean = false;
    public Closing: EventEmitter = new EventEmitter();
    private _isVisible: boolean = false;

    // 静态构造函数模拟
    static {
        // 模拟设置默认样式键
    }

    constructor() {
        this.IsModal = true;
        this.WindowStartupLocation = 'CenterScreen';

        // 模拟 Loaded 事件
        const loadedEmitter = new EventEmitter();
        loadedEmitter.on(() => {
            // 去掉关闭按钮
            const hMenu = NativeAPI.GetSystemMenu(0, false);
            NativeAPI.EnableMenuItem(hMenu, PageDialogBase.SC_CLOSE, PageDialogBase.MF_DISABLED | PageDialogBase.MF_GRAYED);
        });

        // 模拟 PreviewKeyDown 事件
        const previewKeyDownEmitter = new EventEmitter();
        previewKeyDownEmitter.on((e: { Key: string; SystemKey: string; Handled: boolean }) => {
            if (e.Key === 'System' && e.SystemKey === 'F4') {
                e.Handled = true;
            }

            if (e.SystemKey === 'Space' && e.Handled) {
                e.Handled = true;
            }
        });
    }

    protected InternalOpen(ownerPage: IPage, element: FrameworkElement, ispageMessageExt: boolean | null = true, focusKey: string = 'Return') {
        this._ownerPage = ownerPage;
        this._ownerContainer = ownerPage.OwnerContainer;
        if (!this._ownerContainer.IsVisible) return;

        this._element = element;
        const ownerWindow = this.GetOwnerWindow(this._ownerContainer);
        this.Owner = ownerWindow || null;

        if (this.Owner) {
            this.Owner.Closing.on(() => this.Close());
        }

        this._defaultFocus = focusKey;

        if (ispageMessageExt === true) {
            this._element.Loaded.on((e: any) => this.ElementLoaded(this._element!, e));
        } else if (ispageMessageExt === false) {
            this._element.Loaded.on((e: any) => this.ElementLoadedExt(this._element!, e));
        }

        if (this.IsModal) {
            this._ownerContainer.Loaded.on(() => this.Show());
            this._ownerContainer.Unloaded.on(() => this.Hide());

            const topContainer = this.GetTopContainer(this.Owner);
            if (topContainer) topContainer.IsOverlay = true;

            this.ShowInTaskbar = false;
            this.ShowDialog();

            if (topContainer) topContainer.IsOverlay = false;
        } else {
            this.Show();
        }
    }

    protected GetTopContainer(ownerWindow: Window | null): PageContainer | null {
        // 模拟实现
        return null;
    }

    private PreOrder(node: FrameworkElement, keyName: string, match: (obj: any) => boolean): any {
        // 模拟实现
        return null;
    }

    protected GetOwnerWindow(source: DependencyObject): Window | null {
        // 模拟实现
        return null;
    }

    public OnClosed() {
        if (this._dispatcherFrame) {
            this._dispatcherFrame.Continue = false;
        }

        if (this._element) {
            this._element.IsEnabled = true;
        }
    }

    public OnClosing(e: any) {
        if (this._ownerContainer) {
            this._ownerContainer.Loaded.off(() => this.Show());
            this._ownerContainer.Unloaded.off(() => this.Hide());

            if (this._element) {
                this._element.Loaded.off((e: any) => this.ElementLoaded(this._element!, e));
                this._element.Loaded.off((e: any) => this.ElementLoadedExt(this._element!, e));
                this._element.Unloaded.off(() => this.Hide());
            }
        }

        if (this.Owner) {
            this.Owner.Closing.off(() => this.Close());
        }
    }

    public Show() {
        this._isVisible = true;
    }

    public ShowDialog() {
        this._isVisible = true;
    }

    public Hide() {
        this._isVisible = false;
    }

    public Close() {
        this.OnClosing(null);
        this.OnClosed();
        this._isVisible = false;
    }

    private ContainerLoaded(sender: any, e: any) {
        this.Show();
    }

    private ContainerUnloaded(sender: any, e: any) {
        this.Hide();
    }

    private OwnerClosing(sender: any, e: any) {
        this.Close();
    }

    private ElementLoaded(sender: FrameworkElement, e: any) {
        if (this._ownerPage) {
            try {
                const pageContainerPoint = this._ownerContainer!.PointToScreen({ x: 0, y: 0 });
                this.Left = (this._ownerContainer!.ActualWidth - this.Width) / 2 + pageContainerPoint.x;
                this.Top = (this._ownerContainer!.ActualHeight - this.Height) / 2 + pageContainerPoint.y;
            } catch {
                this.WindowStartupLocation = 'CenterOwner';
            }

            const rootTradePage = new TradePage();
            const handler = () => {
                const findButton = this.PreOrder(this as unknown as FrameworkElement, this.DefaultFocus, (x: any) => {
                    const tempBtn = x as { Content: string | null };
                    if (tempBtn.Content) {
                        return tempBtn.Content === this.DefaultFocus;
                    }
                    return false;
                });

                const focus = Presentation.FocusManagers.FocusManager.GetManagerInstance(rootTradePage);
                if (focus && this.IsEnableFocusControl) focus.SetFocus(findButton as FrameworkElement);
            };

            if (rootTradePage.IsLoaded) {
                handler();
            } else {
                rootTradePage.Ready.on(handler);
            }
        }
    }

    private ElementLoadedExt(sender: FrameworkElement, e: any) {
        if (this._ownerPage) {
            const handler = () => {
                this.Width = this._ownerContainer!.ActualWidth;
                try {
                    const pageContainerPoint = this._ownerContainer!.PointToScreen({ x: 0, y: 0 });
                    this.Left = pageContainerPoint.x;
                    this.UpdateLayout();
                    this.Top = pageContainerPoint.y + (this._ownerContainer!.ActualHeight - this.Height) - 10;
                } catch {
                    this.WindowStartupLocation = 'CenterOwner';
                }
            };

            this._ownerContainer!.SizeChanged.off(handler);
            this._ownerContainer!.SizeChanged.on(handler);
            handler();

            const rootTradePage = new TradePage();
            rootTradePage.Ready.on(() => {
                const findButton = this.PreOrder(sender, this.DefaultFocus, (x: any) => {
                    const tempBtn = x as { Content: string | null };
                    if (tempBtn.Content) {
                        const startIndex = tempBtn.Content.lastIndexOf('(');
                        const sub = tempBtn.Content.substring(startIndex + 1, tempBtn.Content.length - startIndex - 2);
                        return sub === this.DefaultFocus;
                    }
                    return false;
                });

                const focus = Presentation.FocusManagers.FocusManager.GetManagerInstance(rootTradePage);
                if (focus && this.IsEnableFocusControl) focus.SetFocus(findButton as FrameworkElement);
            });
        }
    }

    private _rootTradePage: TradePage | null = null;

    public OnApplyTemplate() {
        this._rootTradePage = new TradePage();
    }

    public UpdateLayout() {
        // 模拟更新布局
    }
}

export default PageDialogBase;