import { reactive, watch } from '@vue/reactivity';

// 定义 PropertyChangedEventHandler 类型
type PropertyChangedEventHandler = (sender: any, propertyName: string) => void;

class ObservableObject {
    // 存储属性更改事件的处理函数
    private _propertyChangedHandlers: PropertyChangedEventHandler[] = [];

    // 添加事件处理函数
    onPropertyChanged(handler: PropertyChangedEventHandler) {
        this._propertyChangedHandlers.push(handler);
    }

    // 移除事件处理函数
    offPropertyChanged(handler: PropertyChangedEventHandler) {
        const index = this._propertyChangedHandlers.indexOf(handler);
        if (index > -1) {
            this._propertyChangedHandlers.splice(index, 1);
        }
    }

    // 获取属性名称
    static getPropertyName<T>(getter: () => T): string {
        const propertyName = Object.keys(new Proxy({}, {
            get(target, prop) {
                return prop;
            }
        })).find(prop => getter() === prop);
        return propertyName || '';
    }

    // 触发属性更改事件
    protected raisePropertyChanged(propertyName: string) {
        this._propertyChangedHandlers.forEach(handler => {
            handler(this, propertyName);
        });
    }

    // 通过表达式触发属性更改事件
    protected raisePropertyChangedByExpression<T>(getter: () => T) {
        const propertyName = ObservableObject.getPropertyName(getter);
        if (propertyName) {
            this.raisePropertyChanged(propertyName);
        }
    }

    // 创建响应式对象
    createReactive<T extends object>(obj: T): object {//TODO这里由T泛型改为 object
        const reactiveObj = reactive(obj);
        // 监听所有属性的变化
        watch(() => Object.values(reactiveObj), () => {
            Object.keys(reactiveObj).forEach(key => {
                this.raisePropertyChanged(key);
            });
        }, { deep: true });
        return reactiveObj;
    }
}

export default ObservableObject;
