import { type Family } from '../Definitions/index.js';
import { writeDebugFile, type ISY } from '../ISY.js';
import { ISYNode } from '../ISYNode.js';
import type { NodeDef } from '../Model/NodeDef.js';
import type { NodeInfo } from '../Model/NodeInfo.js';
import { ISYDeviceNode } from './ISYDeviceNode.js';

export abstract class DynamicNode<
	T extends Family.ZWave | Family.ZigBee | Family.ZMatter,
	D extends ISYNode.DriverSignatures,
	C,
	E extends ISYNode.EventSignatures,
> extends ISYDeviceNode<T, D, C, E> {
	nodeTypeId: string;

	abstract getNodeDef(nodeDefId: string): Promise<NodeDef>;

	async applyNodeDef(nodeDef?: NodeDef) {
		if (!nodeDef) {
			nodeDef = await this.getNodeDef(this.address);
			if (this.isy.isDebugEnabled)
				await writeDebugFile(
					JSON.stringify(nodeDef),
					`${this.address}_NodeDef.json`,
					this.isy.logger,
					this.isy.storagePath
				);
		}

		for (let st in this.drivers) {
			if (!(nodeDef?.sts?.st as Array<any>)?.find(s => s.id === st)) {
				this.logger(`Driver ${this.drivers[st].name} ${st} not found in nodeDef. Removing...`);
				delete this.drivers[st];
			}
		}

		for (let cmd in this.commands) {
			if (!(nodeDef?.cmds?.accepts?.cmd as Array<any>)?.find(c => c.id === cmd)) {
				try {
					//@ts-ignore
					this.logger(`Command ${this.commands[cmd]?.name} (${cmd}) not found in nodeDef. Removing...`);
					delete this.commands[cmd];
				} catch {
					this.logger(`Error removing command ${cmd}`);
				}
			}
		}
	}

	constructor(isy: ISY, node: NodeInfo<T>, nodeDef?: NodeDef) {
		super(isy, node);
		this.nodeTypeId = node.nodeTypeId;
	}

	/*override handleEvent(event: { control?: any; data?: any; node?: any; action?: any; fmtAct?: any; }): boolean {
		if(event.node !== this.address) {
			return false;
		}
		if()
		return false;
	}*/
}
