
import FocusList from "./FocusList";

// 模拟 WPF 部分类型
interface DependencyObject {
    // 可根据实际情况添加更多属性和方法
}
//微软系统框架 需要重新实现TODO
interface FrameworkElement extends DependencyObject {
    // Focus(): boolean;
    // IsEnabled: boolean;
    // IsVisible: boolean;
    // Focusable: boolean;
    // 可根据实际情况添加更多属性和方法
}

interface RoutedEventArgs {
    Handled: boolean;
    Source: any;
    OriginalSource: any;
}

interface KeyEventArgs extends RoutedEventArgs {
    Key: string;
}

interface MouseEventArgs extends RoutedEventArgs {
    // 可根据实际情况添加更多属性和方法
}

// 模拟自定义类型


interface FocusAdorner {
    Close(): void;
}

interface AdornerLayer {
    Remove(adorner: FocusAdorner): void;
    Add(adorner: FocusAdorner): void;
}

interface TradePage extends FrameworkElement {
    Ready: (sender: any, e: any) => void;
}


enum FocusNavigation {
    Top,
    Backward,
    Forward
}

enum FocusHandledResult {
    Self,
    Forward,
    Backward,
    System
}

// 模拟附加属性存储
const attachedProperties = new WeakMap<DependencyObject, { [key: string]: any }>();

function getAttachedProperty(obj: DependencyObject, propertyName: string): any {
    const props = attachedProperties.get(obj);
    return props ? props[propertyName] : undefined;
}

function setAttachedProperty(obj: DependencyObject, propertyName: string, value: any) {
    let props = attachedProperties.get(obj);
    if (!props) {
        props = {};
        attachedProperties.set(obj, props);
    }
    props[propertyName] = value;
}

export default class FocusManager {
    private _preAdorder: FocusAdorner | null = null;
    private _focusAdornerLayer: AdornerLayer | null = null;
    public IsFocusContinue: boolean = false;
    private readonly _target: FrameworkElement;
    public _focusList: FocusList | null = null;
    private _currentFocusedElement: FrameworkElement | null = null;
    private static readonly DEFAULT_BUTTON_CLICK_TICK_OUT = -1;
    private _canAcceptUserInput = true;
    private _isOperator = false;

    get CurrentFocusedElement(): FrameworkElement | null {
        return this._currentFocusedElement;
    }

    private set CurrentFocusedElement(value: FrameworkElement | null) {
        if (value) {
            if (!this._focusAdornerLayer) {
                // 模拟获取装饰器层
                this._focusAdornerLayer = {} as AdornerLayer;
            }

            if (this._preAdorder) {
                this._focusAdornerLayer.Remove(this._preAdorder);
                this._preAdorder.Close();
            }

            if (getAttachedProperty(value, "IsFocusAdorner")) {
                this._preAdorder = {} as FocusAdorner;
                this._focusAdornerLayer.Add(this._preAdorder);
            }
        }
        if (this._currentFocusedElement !== value) {
            this._currentFocusedElement = value;
        }
    }

    get CanAcceptUserInput(): boolean {
        return this._canAcceptUserInput;
    }

    set CanAcceptUserInput(value: boolean) {
        this._canAcceptUserInput = value;
    }

    set CanFocusAdjustly(value: boolean) {
        // 模拟移除和添加事件处理程序
        if (!value) {
            // 移除 LayoutUpdated 事件处理程序
        } else {
            // 添加 LayoutUpdated 事件处理程序
        }
    }

    private constructor(target: FrameworkElement) {
        this._target = target;
        // 模拟 IsVisibleChanged 事件
        // target.IsVisibleChanged += (sender, e) => { ... };
    }

    get IsOperator(): boolean {
        if (this._isOperator) return this._isOperator;

        if (FocusList && this._currentFocusedElement) {
            // const ind = this._focusList.indexOf(this._currentFocusedElement | null);//FrameworkElement内容需要改
            // if (ind === 0 && this._currentFocusedElement instanceof TextBox) {
            //     const txt = this._currentFocusedElement as TextBox;
            //     this._isOperator = txt.Text.length !== 0;
            // }
        }

        return this._isOperator;
    }

    // 附加属性相关方法
    static GetCanSkipPreviousFocus(d: DependencyObject): boolean {
        return getAttachedProperty(d, "CanSkipPreviousFocus") || false;
    }

    static SetCanSkipPreviousFocus(d: DependencyObject, value: boolean) {
        setAttachedProperty(d, "CanSkipPreviousFocus", value);
    }

    // 其他附加属性方法类似实现...

    private Registe() {
        const tmp = this._target as TradePage;
        if (tmp) {
            // tmp.Ready += this._target_Ready.bind(this);
        }

        // 模拟注册事件
        // this._target.PreviewKeyDown += this.OnPreviewKeyDown.bind(this);
        // this._target.PreviewMouseDown += this.OnPreviewMouseDown.bind(this);
        // this._target.LayoutUpdated += this._target_LayoutUpdated.bind(this);
    }

    private _target_Ready(sender: any, e: any) {
        const tmp = this._target as TradePage;
        if (tmp) {
            // tmp.Ready -= this._target_Ready.bind(this);
        }

        // this._focusList = FocusList.create(this._target);//TODO FrameworkElement 焦点控制先注释

        if (!this._focusAdornerLayer) {
            this._focusAdornerLayer = {} as AdornerLayer;
        }

        if (this._focusList) {
            // for (let i = 0; i < this._focusList.Count; i++) {
            //     const item = this._focusList[i];
            //     // FocusManager.SetManagerInstance(item, this);
            // }
        }

        this.ReSetFocus();
    }

    private _target_LayoutUpdated(sender: any, e: any) {
        // 模拟获取窗口
        const win = null;
        if (!win || !win.IsActive) return;

        if (this._currentFocusedElement && (getAttachedProperty(this._target, "AutoFocus"))) {
            this.CurrentFocusedElement = this._currentFocusedElement;
        }
        //TODO  || this._target.IsMouseOver) &&!this._target.IsKeyboardFocusWithin && this._currentFocusedElement.Focus() //TODO 没有FrameworkElement IsMouseOver方法
        // if (this._currentFocusedElement &&
        //     this._currentFocusedElement.IsFocused &&
        //     !this.IsEnableFocus(this._currentFocusedElement) &&
        //     !this._currentFocusedElement.IsEnabled &&
        //     this._currentFocusedElement.IsVisible) {
        //     this.CurrentFocusedElement = this._currentFocusedElement;
        //     this.MoveFocusHost(FocusNavigation.Forward);
        // }
    }

    private UnRegiste() {
        // 模拟移除事件处理程序
        // this._target.PreviewKeyDown -= this.OnPreviewKeyDown.bind(this);
        // this._target.PreviewMouseDown -= this.OnPreviewMouseDown.bind(this);
        // this._target.LayoutUpdated -= this._target_LayoutUpdated.bind(this);

        // FocusManager.SetManagerInstance(this._target, null);
    }

    public ReSetFocus() {
        this.MoveFocusHost(FocusNavigation.Top);
    }

    public SetFocus(target: FrameworkElement) {
        if (!target) throw new Error("element 不能为 null");
        //TODD焦点的控制涉及到FrameworkElement
        // // 模拟 UIInvoke
        // if (this._currentFocusedElement !== target &&
        //     this.RaiseFocusManagerEvent(target, "PreviewGotFocusEvent") &&
        //     this.RaiseFocusManagerEvent(target, "GotFocusEvent") &&
        //     target.Focus()) {
        //     this.CurrentFocusedElement = target;
        // } else if (this._currentFocusedElement) {
        //     this._currentFocusedElement.Focus();
        // } else {
        //     this.ReSetFocus();
        // }
    }

    public MoveFocus(navigation: FocusNavigation, isRaiseEvent = true): boolean {
        if (isRaiseEvent) {
            return this.MoveFocusHost(navigation) ?? false;
        } else {
            let targetElement = this._currentFocusedElement;
            if (this._focusList && targetElement) {
                const index = 100;// this._focusList.IndexOf(targetElement);//TODO
                switch (navigation) {
                    case FocusNavigation.Top:
                        this.ReSetFocus();
                        break;
                    case FocusNavigation.Backward:
                        const ind = index > 0 ? index - 1 : 0;
                        targetElement = this._focusList[ind];
                        break;
                    case FocusNavigation.Forward:
                        targetElement = this._focusList[(index + 1) % this._focusList.count];
                        break;
                }

                if (targetElement && targetElement !== this._currentFocusedElement) {
                    this.SetFocus(targetElement);
                    return true;
                }
            }
            return false;
        }
    }

    public Refresh() {
        if (this._focusList) {
            this._focusList.refresh();
        }
    }

    private OnPreviewMouseDown(sender: any, e: RoutedEventArgs) {
        if (this._target !== sender) return;
        if (!this.CanAcceptUserInput) {
            e.Handled = true;
            return;
        }

        let clickedElement = e.Source as FrameworkElement;
        let originalElement = e.Source as FrameworkElement;

        if (!clickedElement) return;

        if (!getAttachedProperty(clickedElement, "OnlyMouseControlHandled") &&
            !getAttachedProperty(clickedElement, "IsInternalKeyboardControlling")) {
            let originalSourceElement = e.OriginalSource as FrameworkElement;
            if (originalSourceElement) {
                if (getAttachedProperty(originalSourceElement, "OnlyMouseControlHandled") ||
                    getAttachedProperty(originalSourceElement, "IsInternalKeyboardControlling")) {
                    clickedElement = originalSourceElement;
                } else {
                    // 模拟 FindVisualTreeAncestor
                    // if (originalSourceElement.FindVisualTreeAncestor(x => x is Window) == null) { ... }
                    // clickedElement = originalSourceElement.FindVisualTreeAncestor(d => ...);
                }
            }
        }

        // if (!clickedElement || clickedElement instanceof IPage) {
        //     e.Handled = true;
        //     return;
        // }

        const handled = getAttachedProperty(clickedElement, "OnlyMouseControlHandled");
        if (handled) {
            let flag = false;
            // 模拟判断条件
            // if (originalElement is ScrollViewer || ...) { ... }
            // const focusElements = originalElement.FindVisualTreeChildren();
            // if (focusElements.Contains(this._currentFocusedElement)) { ... }

            if (flag) {
                handled(clickedElement, e);
                return;
            }
        }

        if (this._focusList && this._currentFocusedElement) {
            // const currentIndex = this._focusList.IndexOf(this._currentFocusedElement);
            // let targetIndex = this._focusList.IndexOf(clickedElement);

            // if (targetIndex < 0) {
            //     while (true) {
            //         clickedElement = LogicalTreeHelper.GetParent(clickedElement) as FrameworkElement;
            //         if (!clickedElement || clickedElement instanceof IPage) {
            //             e.Handled = true;
            //             return;
            //         }
            //         targetIndex = this._focusList.IndexOf(clickedElement);
            //         if (targetIndex >= 0) break;
            //     }
            // }

            // if (currentIndex === targetIndex) {
            //     if (this.ButtonClickTick(this._currentFocusedElement)) {
            //         e.Handled = true;
            //     }

            //     const funcFocusHandled = getAttachedProperty(this._currentFocusedElement, "MouseFocusHandled");
            //     if (funcFocusHandled) {
            //         const result = funcFocusHandled(this._currentFocusedElement, e as MouseEventArgs);
            //         // 处理结果
            //     }
            //     return;
            // }

            //   const result = this.MoveFocusHost(targetIndex > currentIndex ? FocusNavigation.Forward : FocusNavigation.Backward, clickedElement);
            if (result === false) {
                e.Handled = true;
            } else if (!this._isOperator) {
                this._isOperator = true;
            }
        }
    }

    private OnPreviewKeyDown(sender: any, e: KeyEventArgs) {
        if (this._target !== sender) return;
        if (!this.CanAcceptUserInput) {
            e.Handled = true;
            return;
        }
        if (!this._currentFocusedElement) return;

        if (this._currentFocusedElement instanceof ButtonBase && (e.Key === "Enter" || e.Key === "Space")) {
            if (this.ButtonClickTick(this._currentFocusedElement)) {
                e.Handled = true;
            }
        }

        const funcFocusHandled = getAttachedProperty(this._currentFocusedElement, "FocusHandled");
        if (funcFocusHandled) {
            const pressKey = HotKeyHelper.GetKeyName(e.Key);
            const result = funcFocusHandled(this._currentFocusedElement, e);
            // 处理结果
        }

        let pressKey = "";
        // 模拟按键判断
        // if (e.Key == Key.Up || ...) { ... }

        let result: boolean | null = true;
        if (pressKey === "DOWN") {
            e.Handled = true;
            result = this.MoveFocusHost(FocusNavigation.Forward);
            if (!this._isOperator) this._isOperator = true;
        } else if (pressKey === "UP") {
            e.Handled = true;
            result = this.MoveFocusHost(FocusNavigation.Backward);
            if (!this._isOperator) this._isOperator = true;
        }

        if (result === false) {
            e.Handled = true;
        }
    }

    private ButtonClickTick(clickElement: FrameworkElement): boolean {
        const clickTick = getAttachedProperty(clickElement, "ButtonClickTick") || 0;
        const clickTickOut = getAttachedProperty(clickElement, "ButtonClickTickOut") || FocusManager.DEFAULT_BUTTON_CLICK_TICK_OUT;

        if (clickTick === 0) {
            setAttachedProperty(clickElement, "ButtonClickTick", Date.now());
        } else {
            const tLeft = (Date.now() - clickTick) / 1000;
            if (tLeft <= clickTickOut) {
                return true;
            } else {
                setAttachedProperty(clickElement, "ButtonClickTick", Date.now());
            }
        }

        return false;
    }

    private RaiseFocusManagerEvent(target: DependencyObject, routedEvent: string): boolean {
        this.IsFocusContinue = true;
        if (!target) return false;
        // 模拟事件触发
        return this.IsFocusContinue;
    }

    private MoveFocusHost(navigation: FocusNavigation = FocusNavigation.Forward, target: FrameworkElement | null = null): boolean | null {
        if (!this._focusList) {
            //  this._focusList = FocusList.create(this._target);
        }

        let currentElement = this._currentFocusedElement;
        let targetElement: FrameworkElement | null = null;

        //         if (this._focusList) {
        //             for (let i = 0; i < this._focusList.count; i++) {
        //                 // if (!currentElement || !this._focusList.contains(currentElement)) {
        //                 //     navigation = FocusNavigation.Top;
        //                 // }

        //                 if (this._focusList && currentElement) {
        //                     // // const index = this._focusList.IndexOf(currentElement);
        //                     // switch (navigation) {
        //                     //     case FocusNavigation.Top:
        //                     //         targetElement = this._focusList[i];
        //                     //         break;
        //                     //     case FocusNavigation.Backward:
        //                     //         const ind = index > 0 ? index - 1 : 0;
        //                     //         targetElement = this._focusList[ind];
        //                     //         break;
        //                     //     case FocusNavigation.Forward:
        //                     //         targetElement = this._focusList[(index + 1) % this._focusList.Count];
        //                     //         break;
        //                     //     default:
        //                     //         throw new Error("MoveFocus：无效的参数！");
        //                     // }
        //                 }

        //                 if (!targetElement) return false;
        //                 if (targetElement === currentElement) return null;

        //                 if (navigation !== FocusNavigation.Forward) {
        //                     // const tmpTarget = target || targetElement;
        //                     // if (this.IsEnableFocus(tmpTarget)) {
        //                     //     tmpTarget.Focus();
        //                     //     if (this.RaiseFocusManagerEvent(tmpTarget, "PreviewGotFocusEvent") &&
        //                     //         this.RaiseFocusManagerEvent(tmpTarget, "GotFocusEvent")) {
        //                     //         this.CurrentFocusedElement = tmpTarget;
        //                     //         if (tmpTarget instanceof ButtonBase && navigation !== FocusNavigation.Top) {
        //                     //             return !this.ButtonClickTick(tmpTarget);
        //                     //         }
        //                     //         return true;
        //                     //     } else {
        //                     //         return false;
        //                     //     }
        //                     // } else if (!target) {
        //                     //     // currentElement = tmpTarget;
        //                     // }
        //                     // continue;
        //                 } else {
        //                     return false;
        //                 }
        //             } else if (target && FocusManager.GetCanSkipPreviousFocus(target)) {
        //                 targetElement = target;
        //             } else {
        //                 if (currentElement &&
        //                     this.IsEnableFocus(currentElement) &&
        //                     (!this.RaiseFocusManagerEvent(currentElement, "PreviewLostFocusEvent") ||
        //                         !this.RaiseFocusManagerEvent(currentElement, "LostFocusEvent"))) {
        //                     return false;
        //                 }
        //             }

        //             if (this.IsEnableFocus(targetElement)) {
        //                 targetElement.Focus();
        //                 if (this.RaiseFocusManagerEvent(targetElement, "PreviewGotFocusEvent") &&
        //                     this.RaiseFocusManagerEvent(targetElement, "GotFocusEvent")) {
        //                     this.CurrentFocusedElement = targetElement;
        //                 } else {
        //                     return false;
        //                 }
        //             } else {
        //                 currentElement = targetElement;
        //                 continue;
        //             }

        //             if (!target || target === targetElement ||
        //                 (target && FocusManager.GetCanSkipPreviousFocus(target))) {
        //                 if (target === targetElement && target instanceof ButtonBase) {
        //                     return !this.ButtonClickTick(target);
        //                 }
        //                 return true;
        //             } else {
        //                 currentElement = targetElement;
        //                 continue;
        //             }
        //         }
        //     }

        // return false;
        //     }

        //     private IsEnableFocus(ele: FrameworkElement): boolean {
        //     return null;//ele.IsEnabled && ele.IsVisible && (ele.Focusable || getAttachedProperty(ele, "IsInternalKeyboardControlling"));
        // }

        //     public MoveFocusElement(target: FrameworkElement): boolean {
        //     if (this._focusList && this._currentFocusedElement) {
        //         // const currentIndex = this._focusList.IndexOf(this._currentFocusedElement);
        //         // let targetIndex = this._focusList.IndexOf(target);

        //         // if (targetIndex < 0) {
        //         //     while (true) {
        //         //         target = LogicalTreeHelper.GetParent(target) as FrameworkElement;
        //         //         if (!target || target instanceof IPage) {
        //         //             return false;
        //         //         }
        //         //         targetIndex = this._focusList.IndexOf(target);
        //         //         if (targetIndex >= 0) break;
        //         //     }
        //         // }

        //         // if (currentIndex === targetIndex) return true;

        //         // const result = this.MoveFocusHost(targetIndex > currentIndex ? FocusNavigation.Forward : FocusNavigation.Backward, target);
        //         return result === true;
        //     }
        return false;
    }
}

// 模拟其他类和工具函数
class TextBox extends FrameworkElement {
    Text = "";
}

class ButtonBase extends FrameworkElement { }

class LogicalTreeHelper {
    static GetParent(element: FrameworkElement): FrameworkElement | null {
        return null;
    }
}

class HotKeyHelper {
    static GetKeyName(key: string): string {
        return key;
    }
}

// 其他模拟类和工具函数可按需添加
//TODO 焦点控制 后续处理
