// Define the possible types for Arduino proxy messages.
// These correspond to the case numbers in the Arduino switch statement.
import {ArduinoProxy} from "./ArduinoProxy";
import {ArduinoProxyPayloadType} from "./ArduinoProxyPayloadType";

/**
 * Represents a payload message to be sent to the Arduino proxy.
 */
export class ArduinoProxyPayload {
    // Private member to store the unique message ID.
    private _id: string = "";
    // Private member to store the message type.
    private readonly _type: ArduinoProxyPayloadType;
    // Private member to store the data payload for the message.
    private readonly _data: any; // Use 'any' as data structure varies by type.

    /**
     * Constructor for ArduinoProxyPayload.
     * @param type The type of the message (enum ArduinoProxyPayloadType).
     * @param data The data payload for the message. Structure depends on the type.
     * - For SET_PIN: { pin: number, mode: "DIGITAL"|"ANALOG", value: number (0/1 for DIGITAL, 0-255 for ANALOG) }
     * - For GET_VAL: { pin: number, mode: "DIGITAL"|"ANALOG" }
     * - For GET_SENSOR: { pin_data: number, pin_clock: number }
     * - For RESET: {} (empty object)
     */
    constructor(type: ArduinoProxyPayloadType, data: { pin?: number, value?: number, pin_data?: number, pin_clock?: number, mode?: "DIGITAL"|"ANALOG" }) {
        this._type = type;
        this._data = data; // Store the provided data object.
    }

    /**
     * Getter for the message type.
     * @returns The message type.
     */
    get type(): ArduinoProxyPayloadType {
        return this._type;
    }

    /**
     * Getter for the message data payload.
     * @returns The data payload object.
     */
    get data(): any { // Changed return type to any
        return this._data;
    }

    /**
     * Getter for the message ID.
     * @returns The message ID.
     */
    get id(): string {
        return this._id;
    }

    /**
     * Setter for the message ID. Used internally by ArduinoProxy.
     * @param value The unique message ID.
     */
    set id(value: string) {
        this._id = value;
    }

    /**
     * Sends this payload using the ArduinoProxy.
     * @returns A promise that resolves with the response payload or rejects on error/timeout.
     */
    public send(): Promise<ArduinoProxyPayload> {
        // Call the static sendRequest method of ArduinoProxy, passing this payload.
        return ArduinoProxy.sendRequest(this);
    }
}