// 模拟 IFieldPolicy 接口
interface IFieldPolicy {
    Run(sender: HTMLElement, content: any): void;
    Clone(): any;
}

// 模拟 TipAdornerPlacement 类型
type TipAdornerPlacement = string;

// 模拟 TipAdorner 类
class TipAdorner {
    Placement: TipAdornerPlacement;
    Message: string;
    element: HTMLElement;

    constructor(element: HTMLElement, _adornerLayer: any) {
        this.element = element;
    }
}

// 模拟 AdornerLayer 类
class AdornerLayer {
    private adorners: any[] = [];

    static GetAdornerLayer(element: HTMLElement): AdornerLayer {
        return new AdornerLayer();
    }

    GetAdorners(element: HTMLElement): any[] {
        return this.adorners.filter(ad => ad.element === element);
    }

    Add(adorner: any) {
        this.adorners.push(adorner);
    }

    Remove(adorner: any) {
        const index = this.adorners.indexOf(adorner);
        if (index !== -1) {
            this.adorners.splice(index, 1);
        }
    }
}

export class ShowTipPolicy implements IFieldPolicy {
    private _adorner: TipAdorner | null = null;
    Placement: TipAdornerPlacement;

    Run(sender: HTMLElement, content: any): void {
        const element = sender;
        if (!element) return;

        const adornerLayer = AdornerLayer.GetAdornerLayer(element);
        if (adornerLayer) {
            const adorners = adornerLayer.GetAdorners(element);
            if (adorners) {
                adorners.forEach(ad => {
                    if (ad instanceof TipAdorner) {
                        adornerLayer.Remove(ad);
                    }
                });
            }

            this._adorner = new TipAdorner(element, adornerLayer);
            this._adorner.Placement = this.Placement;
            this._adorner.Message = content === null ? "输入错误" : content.toString();
            adornerLayer.Add(this._adorner);

            element.addEventListener('blur', this.OnLostFocus.bind(this));

            if (element.tagName === 'INPUT') {// && element.type === 'text' TODO报错暂时注掉
                (element as HTMLInputElement).select();
            }
        }
    }

    private OnLostFocus(e: Event) {
        const element = e.target as HTMLElement;
        if (!element) return;

        element.removeEventListener('blur', this.OnLostFocus.bind(this));

        const adornerLayer = AdornerLayer.GetAdornerLayer(element);
        if (!adornerLayer || !this._adorner) return;

        adornerLayer.Remove(this._adorner);
        this._adorner = null;
    }

    Clone(): any {
        throw new Error('方法未实现');
    }
}
