import { z } from 'zod';
import {
  configDiskSensorBallShooterModuleOptionsSchema,
  configureBallSensorDiskThrowerModuleOptionsSchema,
  flagConfigurationOptionsSchema,
  flagShowMediaOptionsSchema,
  playSoundOptionsSchema,
  rgbConfigurationOptionsSchema,
  rgbShowEffectOptionsSchema,
  screenCountdownParamsSchema,
  screenFinishViewInputSchema,
  screenUpdateGameViewInputSchema,
  speedChangeOptionsSchema,
  speedConfigurationSchema,
  starLaserConfigureModuleOptionsSchema,
  starLaserSendActionsOptionsSchema,
} from '../hardware';
import { arithmeticExpressionSchema } from '../utils';

// Helper for arithmetic expressions
const arithmeticOrNumberSchema = z.union([z.number(), arithmeticExpressionSchema]);

// --- Speed Commands ---
export const changeSpeedActionCommandOptionsSchema = speedChangeOptionsSchema.omit({ speed: true }).extend({
  speed: arithmeticOrNumberSchema,
});

export const speedModuleCommandSchema = z.union([
  z.object({ module: z.literal('speed'), action: z.literal('activate') }),
  z.object({ module: z.literal('speed'), action: z.literal('deactivate') }),
  z.object({ module: z.literal('speed'), action: z.literal('change'), params: changeSpeedActionCommandOptionsSchema }),
  z.object({ module: z.literal('speed'), action: z.literal('configure'), params: speedConfigurationSchema }),
]);

// --- Sound Commands ---
export const playSoundActionCommandOptionsSchema = playSoundOptionsSchema.omit({ durationMs: true }).extend({
  durationMs: arithmeticOrNumberSchema.optional(),
});

export const soundModuleCommandSchema = z.object({
  module: z.literal('sound'),
  action: z.literal('play'),
  params: playSoundActionCommandOptionsSchema,
});

// --- Ball Sensor / Disk Thrower ---
export const ballSensorDiskThrowerModuleCommandSchema = z.union([
  z.object({ module: z.literal('ballSensorDiskThrower'), action: z.literal('activateSensor') }),
  z.object({ module: z.literal('ballSensorDiskThrower'), action: z.literal('deactivateSensor') }),
  z.object({
    module: z.literal('ballSensorDiskThrower'),
    action: z.literal('configureModule'),
    params: configureBallSensorDiskThrowerModuleOptionsSchema,
  }),
  z.object({ module: z.literal('ballSensorDiskThrower'), action: z.literal('throwDisk') }),
  z.object({ module: z.literal('ballSensorDiskThrower'), action: z.literal('activateDiskThrower') }),
  z.object({ module: z.literal('ballSensorDiskThrower'), action: z.literal('deactivateDiskThrower') }),
]);

// --- Disk Sensor / Ball Shooter ---
export const diskSensorBallShooterModuleCommandSchema = z.union([
  z.object({
    module: z.literal('diskSensorBallShooter'),
    action: z.literal('configure'),
    params: configDiskSensorBallShooterModuleOptionsSchema,
  }),
  z.object({ module: z.literal('diskSensorBallShooter'), action: z.literal('prepareShooter') }),
  z.object({ module: z.literal('diskSensorBallShooter'), action: z.literal('shootBall') }),
  z.object({ module: z.literal('diskSensorBallShooter'), action: z.literal('activateSensor') }),
  z.object({ module: z.literal('diskSensorBallShooter'), action: z.literal('deactivateSensor') }),
  z.object({ module: z.literal('diskSensorBallShooter'), action: z.literal('calibrateSensor') }),
]);

// --- Flag ---
export const flagModuleCommandSchema = z.union([
  z.object({ module: z.literal('flag'), action: z.literal('activate') }),
  z.object({ module: z.literal('flag'), action: z.literal('deactivate') }),
  z.object({ module: z.literal('flag'), action: z.literal('configure'), params: flagConfigurationOptionsSchema }),
  z.object({
    module: z.literal('flag'),
    action: z.literal('showMediaIndefinitely'),
    params: flagShowMediaOptionsSchema,
  }),
  z.object({
    module: z.literal('flag'),
    action: z.literal('showMediaTemporarily'),
    params: flagShowMediaOptionsSchema,
  }),
]);

// --- RGB ---
export const rgbModuleCommandSchema = z.union([
  z.object({ module: z.literal('rgb'), action: z.literal('configure'), params: rgbConfigurationOptionsSchema }),
  z.object({ module: z.literal('rgb'), action: z.literal('showEffect'), params: rgbShowEffectOptionsSchema }),
]);

// --- Star Laser ---
export const leftStarBackLaserModuleCommandSchema = z.union([
  z.object({
    module: z.literal('leftStarBackLaser'),
    action: z.literal('action'),
    params: starLaserSendActionsOptionsSchema,
  }),
  z.object({
    module: z.literal('leftStarBackLaser'),
    action: z.literal('configure'),
    params: starLaserConfigureModuleOptionsSchema,
  }),
]);

export const rightStarFrontLaserModuleCommandSchema = z.union([
  z.object({
    module: z.literal('rightStarFrontLaser'),
    action: z.literal('action'),
    params: starLaserSendActionsOptionsSchema,
  }),
  z.object({
    module: z.literal('rightStarFrontLaser'),
    action: z.literal('configure'),
    params: starLaserConfigureModuleOptionsSchema,
  }),
]);

// --- Screen (New) ---
export const screenModuleCommandSchema = z.union([
  z.object({ module: z.literal('screen'), action: z.literal('showHomeView') }),
  z.object({
    module: z.literal('screen'),
    action: z.literal('showCountdownView'),
    params: screenCountdownParamsSchema,
  }),
  z.object({
    module: z.literal('screen'),
    action: z.literal('updateGameView'),
    params: screenUpdateGameViewInputSchema,
  }),
  z.object({
    module: z.literal('screen'),
    action: z.literal('showScreenVictoryView'),
    params: screenFinishViewInputSchema,
  }),
  z.object({
    module: z.literal('screen'),
    action: z.literal('showScreenDefeatView'),
    params: screenFinishViewInputSchema,
  }),
]);

// --- Steering Wheel ---
export const steeringWheelModuleCommandSchema = z.union([
  z.object({ module: z.literal('steeringWheel'), action: z.literal('turnLedOn') }),
  z.object({ module: z.literal('steeringWheel'), action: z.literal('turnLedOff') }),
]);

// --- All Commands Union ---
export const allCommandsConfigSchema = z.union([
  ballSensorDiskThrowerModuleCommandSchema,
  diskSensorBallShooterModuleCommandSchema,
  flagModuleCommandSchema,
  rgbModuleCommandSchema,
  speedModuleCommandSchema,
  leftStarBackLaserModuleCommandSchema,
  rightStarFrontLaserModuleCommandSchema,
  screenModuleCommandSchema,
  steeringWheelModuleCommandSchema,
  soundModuleCommandSchema,
]);
