#include "zbus_message.h"

#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/shell/shell.h>
#include <zephyr/zbus/zbus.h>

LOG_MODULE_REGISTER(led_shell, LOG_LEVEL_INF);

/**
 * @brief Parse and publish an LED command to leds_chan.
 *
 * Usage:
 *   led set <id> <on|off>
 *
 * @param shell  Shell instance
 * @param argc   Argument count (must be 3: "set", id, state)
 * @param argv   Argument vector
 * @return 0 on success, negative errno on failure
 */
static int cmd_led_set(const struct shell *shell, size_t argc, char **argv)
{
	struct leds_message msg;
	int ret;

	/* Parse LED id */
	char *endptr;
	long id = strtol(argv[1], &endptr, 10);

	if (*endptr != '\0' || id < 0 || id > 1) {
		shell_error(shell, "Invalid LED id '%s'. Use 0 or 1.", argv[1]);
		return -EINVAL;
	}

	/* Parse state */
	if (strcmp(argv[2], "on") == 0) {
		msg.led_value = true;
	} else if (strcmp(argv[2], "off") == 0) {
		msg.led_value = false;
	} else {
		shell_error(shell, "Invalid state '%s'. Use 'on' or 'off'.", argv[2]);
		return -EINVAL;
	}

	msg.led_id = (uint8_t)id;

	ret = zbus_chan_pub(&leds_chan, &msg, K_MSEC(200));
	if (ret != 0) {
		shell_error(shell, "Failed to publish LED command: %d", ret);
		return ret;
	}

	shell_print(shell, "LED%d turned %s", msg.led_id, msg.led_value ? "ON" : "OFF");
	return 0;
}

/**
 * @brief Turn on all LEDs.
 */
static int cmd_led_all_on(const struct shell *shell, size_t argc, char **argv)
{
	struct leds_message msg;
	int ret;

	for (uint8_t i = 0; i <= 1; i++) {
		msg.led_id    = i;
		msg.led_value = true;

		ret = zbus_chan_pub(&leds_chan, &msg, K_MSEC(200));
		if (ret != 0) {
			shell_error(shell, "Failed to turn on LED%d: %d", i, ret);
			return ret;
		}
	}

	shell_print(shell, "All LEDs turned ON");
	return 0;
}

/**
 * @brief Turn off all LEDs.
 */
static int cmd_led_all_off(const struct shell *shell, size_t argc, char **argv)
{
	struct leds_message msg;
	int ret;

	for (uint8_t i = 0; i <= 1; i++) {
		msg.led_id    = i;
		msg.led_value = false;

		ret = zbus_chan_pub(&leds_chan, &msg, K_MSEC(200));
		if (ret != 0) {
			shell_error(shell, "Failed to turn off LED%d: %d", i, ret);
			return ret;
		}
	}

	shell_print(shell, "All LEDs turned OFF");
	return 0;
}

/* Subcommands for the "led" root command */
SHELL_STATIC_SUBCMD_SET_CREATE(sub_led,
	SHELL_CMD_ARG(set, NULL,
		"Set a single LED state.\n"
		"Usage: led set <id> <on|off>\n"
		"  id  : 0 or 1\n"
		"  state: on | off",
		cmd_led_set, 3, 0),
	SHELL_CMD(allon, NULL,
		"Turn all LEDs on.\n"
		"Usage: led allon",
		cmd_led_all_on),
	SHELL_CMD(alloff, NULL,
		"Turn all LEDs off.\n"
		"Usage: led alloff",
		cmd_led_all_off),
	SHELL_SUBCMD_SET_END
);

SHELL_CMD_REGISTER(led, &sub_led,
	"LED control commands.\n"
	"  led set <id> <on|off>  - Set LED state\n"
	"  led allon              - Turn all LEDs on\n"
	"  led alloff             - Turn all LEDs off",
	NULL);