import * as Blockly from 'blockly';

// ─── Pin I/O ──────────────────────────────────────────────

Blockly.Blocks['pin_set_mode'] = {
  init() {
    this.appendDummyInput()
      .appendField('set pin')
      .appendField(new Blockly.FieldNumber(2, 0, 48, 1), 'PIN')
      .appendField('as')
      .appendField(new Blockly.FieldDropdown([
        ['OUTPUT', 'OUT'],
        ['INPUT', 'IN'],
        ['INPUT_PULLUP', 'PULL_UP'],
      ]), 'MODE');
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(230);
    this.setTooltip('Configure a GPIO pin mode');
  },
};

Blockly.Blocks['pin_digital_write'] = {
  init() {
    this.appendDummyInput()
      .appendField('digital write pin')
      .appendField(new Blockly.FieldNumber(2, 0, 48, 1), 'PIN')
      .appendField('to')
      .appendField(new Blockly.FieldDropdown([
        ['HIGH', '1'],
        ['LOW', '0'],
      ]), 'VALUE');
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(230);
    this.setTooltip('Write HIGH or LOW to a digital pin');
  },
};

Blockly.Blocks['pin_digital_read'] = {
  init() {
    this.appendDummyInput()
      .appendField('digital read pin')
      .appendField(new Blockly.FieldNumber(2, 0, 48, 1), 'PIN');
    this.setOutput(true, 'Number');
    this.setColour(230);
    this.setTooltip('Read digital value from a pin (0 or 1)');
  },
};

// ─── PWM ──────────────────────────────────────────────────

Blockly.Blocks['pwm_init'] = {
  init() {
    this.appendDummyInput()
      .appendField('init PWM on pin')
      .appendField(new Blockly.FieldNumber(2, 0, 48, 1), 'PIN')
      .appendField('freq')
      .appendField(new Blockly.FieldNumber(1000, 1, 40000000, 1), 'FREQ')
      .appendField('Hz');
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(160);
    this.setTooltip('Initialize PWM on a pin with a frequency');
  },
};

Blockly.Blocks['pwm_set_duty'] = {
  init() {
    this.appendValueInput('DUTY')
      .setCheck('Number')
      .appendField('set PWM duty on pin')
      .appendField(new Blockly.FieldNumber(2, 0, 48, 1), 'PIN')
      .appendField('to');
    this.appendDummyInput()
      .appendField('(0-1023)');
    this.setInputsInline(true);
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(160);
    this.setTooltip('Set PWM duty cycle (0-1023)');
  },
};

Blockly.Blocks['pwm_set_freq'] = {
  init() {
    this.appendValueInput('FREQ')
      .setCheck('Number')
      .appendField('set PWM freq on pin')
      .appendField(new Blockly.FieldNumber(2, 0, 48, 1), 'PIN')
      .appendField('to');
    this.appendDummyInput()
      .appendField('Hz');
    this.setInputsInline(true);
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(160);
    this.setTooltip('Set PWM frequency in Hz');
  },
};

// ─── ADC ──────────────────────────────────────────────────

Blockly.Blocks['adc_read'] = {
  init() {
    this.appendDummyInput()
      .appendField('read ADC on pin')
      .appendField(new Blockly.FieldNumber(1, 0, 20, 1), 'PIN');
    this.setOutput(true, 'Number');
    this.setColour(30);
    this.setTooltip('Read analog value from ADC pin (0-4095)');
  },
};

// ─── Time ─────────────────────────────────────────────────

Blockly.Blocks['sleep_seconds'] = {
  init() {
    this.appendValueInput('SECONDS')
      .setCheck('Number')
      .appendField('sleep');
    this.appendDummyInput()
      .appendField('seconds');
    this.setInputsInline(true);
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(120);
    this.setTooltip('Pause execution for N seconds');
  },
};

Blockly.Blocks['sleep_ms'] = {
  init() {
    this.appendValueInput('MS')
      .setCheck('Number')
      .appendField('sleep');
    this.appendDummyInput()
      .appendField('milliseconds');
    this.setInputsInline(true);
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(120);
    this.setTooltip('Pause execution for N milliseconds');
  },
};

Blockly.Blocks['ticks_ms'] = {
  init() {
    this.appendDummyInput()
      .appendField('ticks (ms)');
    this.setOutput(true, 'Number');
    this.setColour(120);
    this.setTooltip('Get millisecond tick counter');
  },
};

// ─── WiFi ─────────────────────────────────────────────────

Blockly.Blocks['wifi_connect'] = {
  init() {
    this.appendDummyInput()
      .appendField('connect WiFi SSID')
      .appendField(new Blockly.FieldTextInput('MyNetwork'), 'SSID')
      .appendField('password')
      .appendField(new Blockly.FieldTextInput('password'), 'PASSWORD');
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(290);
    this.setTooltip('Connect to a WiFi network');
  },
};

Blockly.Blocks['wifi_get_ip'] = {
  init() {
    this.appendDummyInput()
      .appendField('WiFi IP address');
    this.setOutput(true, 'String');
    this.setColour(290);
    this.setTooltip('Get the current IP address');
  },
};

// ─── NeoPixel ─────────────────────────────────────────────

Blockly.Blocks['neopixel_init'] = {
  init() {
    this.appendDummyInput()
      .appendField('init NeoPixel on pin')
      .appendField(new Blockly.FieldNumber(48, 0, 48, 1), 'PIN')
      .appendField('with')
      .appendField(new Blockly.FieldNumber(1, 1, 1024, 1), 'NUM')
      .appendField('LEDs');
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(10);
    this.setTooltip('Initialize a NeoPixel strip');
  },
};

Blockly.Blocks['neopixel_set_color'] = {
  init() {
    this.appendDummyInput()
      .appendField('set NeoPixel #')
      .appendField(new Blockly.FieldNumber(0, 0, 1023, 1), 'INDEX');
    this.appendValueInput('R').setCheck('Number').appendField('R');
    this.appendValueInput('G').setCheck('Number').appendField('G');
    this.appendValueInput('B').setCheck('Number').appendField('B');
    this.setInputsInline(true);
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(10);
    this.setTooltip('Set NeoPixel color (R, G, B values 0-255)');
  },
};

Blockly.Blocks['neopixel_show'] = {
  init() {
    this.appendDummyInput()
      .appendField('NeoPixel show');
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(10);
    this.setTooltip('Push color data to NeoPixel strip');
  },
};

// ─── I2C ──────────────────────────────────────────────────

Blockly.Blocks['i2c_init'] = {
  init() {
    this.appendDummyInput()
      .appendField('init I2C  SDA pin')
      .appendField(new Blockly.FieldNumber(8, 0, 48, 1), 'SDA')
      .appendField('SCL pin')
      .appendField(new Blockly.FieldNumber(9, 0, 48, 1), 'SCL')
      .appendField('freq')
      .appendField(new Blockly.FieldNumber(400000, 1, 1000000, 1), 'FREQ');
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(200);
    this.setTooltip('Initialize I2C bus');
  },
};

Blockly.Blocks['i2c_scan'] = {
  init() {
    this.appendDummyInput()
      .appendField('I2C scan devices');
    this.setOutput(true, 'Array');
    this.setColour(200);
    this.setTooltip('Scan for I2C devices, returns list of addresses');
  },
};

Blockly.Blocks['i2c_writeto'] = {
  init() {
    this.appendValueInput('DATA')
      .setCheck(null)
      .appendField('I2C write to address')
      .appendField(new Blockly.FieldNumber(0, 0, 127, 1), 'ADDR')
      .appendField('data');
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(200);
    this.setTooltip('Write data bytes to an I2C device');
  },
};

Blockly.Blocks['i2c_readfrom'] = {
  init() {
    this.appendDummyInput()
      .appendField('I2C read from address')
      .appendField(new Blockly.FieldNumber(0, 0, 127, 1), 'ADDR')
      .appendField('bytes')
      .appendField(new Blockly.FieldNumber(1, 1, 256, 1), 'NBYTES');
    this.setOutput(true, null);
    this.setColour(200);
    this.setTooltip('Read N bytes from an I2C device');
  },
};

// ─── Print ────────────────────────────────────────────────

Blockly.Blocks['print_text'] = {
  init() {
    this.appendValueInput('TEXT')
      .setCheck(null)
      .appendField('print');
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(60);
    this.setTooltip('Print to serial output');
  },
};

// ─── Sound ───────────────────────────────────────────────

Blockly.Blocks['sound_play_tone_speaker'] = {
  init() {
    this.appendDummyInput().appendField('play tone on speaker');
    this.appendValueInput('FREQ')
      .setCheck('Number')
      .appendField('freq');
    this.appendDummyInput().appendField('Hz');
    this.appendValueInput('DURATION')
      .setCheck('Number')
      .appendField('for');
    this.appendDummyInput()
      .appendField('ms')
      .appendField(new Blockly.FieldDropdown([
        ['wait', 'TRUE'],
        ['continue', 'FALSE'],
      ]), 'WAIT');
    this.setInputsInline(true);
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(300);
    this.setTooltip('Play a tone on the built-in speaker (micro:bit v2). "continue" runs code while tone plays.');
  },
};

Blockly.Blocks['sound_stop_speaker'] = {
  init() {
    this.appendDummyInput().appendField('stop speaker');
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(300);
    this.setTooltip('Stop sound on the built-in speaker (micro:bit v2)');
  },
};

Blockly.Blocks['sound_play_tone'] = {
  init() {
    this.appendDummyInput()
      .appendField('play tone on pin')
      .appendField(new Blockly.FieldNumber(0, 0, 48, 1), 'PIN');
    this.appendValueInput('FREQ')
      .setCheck('Number')
      .appendField('freq');
    this.appendDummyInput().appendField('Hz');
    this.appendValueInput('DURATION')
      .setCheck('Number')
      .appendField('for');
    this.appendDummyInput()
      .appendField('ms')
      .appendField(new Blockly.FieldDropdown([
        ['wait', 'TRUE'],
        ['continue', 'FALSE'],
      ]), 'WAIT');
    this.setInputsInline(true);
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(300);
    this.setTooltip('Play a tone via PWM on a specific pin. "continue" runs code while tone plays.');
  },
};

Blockly.Blocks['sound_stop'] = {
  init() {
    this.appendDummyInput()
      .appendField('stop sound on pin')
      .appendField(new Blockly.FieldNumber(0, 0, 48, 1), 'PIN');
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(300);
    this.setTooltip('Stop sound on a specific pin');
  },
};

// ─── micro:bit Display ────────────────────────────────────

// Helper to add one row of 5 checkboxes (Pxy = pixel at row x, col y)
function addMicrobitDisplayRow(block, row) {
  const input = block.appendDummyInput(`ROW${row}`);
  for (let col = 0; col < 5; col++) {
    const name = `P${row}${col}`;
    input.appendField(new Blockly.FieldCheckbox(false), name);
  }
}

Blockly.Blocks['microbit_display_all'] = {
  init() {
    this.appendDummyInput()
      .appendField('micro:bit display 5×5');
    for (let row = 0; row < 5; row++) {
      addMicrobitDisplayRow(this, row);
    }
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(10);
    this.setTooltip('Click LEDs to set the 5×5 display (micro:bit only). On = 9, off = 0.');
  },
};
