/**
 * @fileoverview Factories para criação declarativa de blocos Blockly
 * @module blockly.blockFactory
 */

import * as Blockly from "blockly/core";

/**
 * Cria um bloco statement simples sem inputs
 * @param {string} tipo - ID único do bloco
 * @param {string} texto - Texto exibido no bloco
 * @param {number} cor - HSV hue (0-360) ou código de cor
 * @param {string} [tooltip] - Texto de ajuda (opcional)
 * @example
 * criarBlocoStatementSimples("robo_mover", "mover para FRENTE", 210);
 */
export const criarBlocoStatementSimples = (tipo, texto, cor, tooltip = "") => {
  Blockly.Blocks[tipo] = {
    init: function () {
      this.appendDummyInput().appendField(texto);
      this.setPreviousStatement(true, null);
      this.setNextStatement(true, null);
      this.setColour(cor);
      if (tooltip) this.setTooltip(tooltip);
    }
  };
};

/**
 * Cria um bloco statement com dropdown
 * @param {string} tipo - ID único do bloco
 * @param {string} textoAntes - Texto antes do dropdown
 * @param {Array<[string, string]>} opcoes - Opções do dropdown [[label, value], ...]
 * @param {string} nomeCampo - Nome do campo para recuperar valor
 * @param {number} cor - HSV hue ou código de cor
 * @param {string} [textoDepois] - Texto após o dropdown (opcional)
 * @param {string} [tooltip] - Texto de ajuda (opcional)
 * @example
 * criarBlocoStatementComDropdown("robo_virar", "virar para a", 
 *   [["DIREITA ↻", "DIREITA"], ["ESQUERDA ↺", "ESQUERDA"]], "DIRECAO", 210);
 */
export const criarBlocoStatementComDropdown = (
  tipo, 
  textoAntes, 
  opcoes, 
  nomeCampo, 
  cor, 
  textoDepois = "", 
  tooltip = ""
) => {
  Blockly.Blocks[tipo] = {
    init: function () {
      const input = this.appendDummyInput().appendField(textoAntes);
      input.appendField(new Blockly.FieldDropdown(opcoes), nomeCampo);
      if (textoDepois) input.appendField(textoDepois);
      this.setPreviousStatement(true, null);
      this.setNextStatement(true, null);
      this.setColour(cor);
      if (tooltip) this.setTooltip(tooltip);
    }
  };
};

/**
 * Cria um bloco statement com value input
 * @param {string} tipo - ID único do bloco
 * @param {string} textoAntes - Texto antes do input
 * @param {string} nomeInput - Nome do input de valor
 * @param {string|null} tipoCheck - Tipo esperado ("Number", "Boolean", null)
 * @param {number} cor - HSV hue ou código de cor
 * @param {string} [textoDepois] - Texto após o input (opcional)
 * @param {string} [tooltip] - Texto de ajuda (opcional)
 * @example
 * criarBlocoStatementComValor("robo_passos_set", "definir PASSOS para", 
 *   "VALOR", "Number", 330);
 */
export const criarBlocoStatementComValor = (
  tipo,
  textoAntes,
  nomeInput,
  tipoCheck,
  cor,
  textoDepois = "",
  tooltip = ""
) => {
  Blockly.Blocks[tipo] = {
    init: function () {
      const input = this.appendValueInput(nomeInput).setCheck(tipoCheck);
      input.appendField(textoAntes);
      if (textoDepois) input.appendField(textoDepois);
      this.setPreviousStatement(true, null);
      this.setNextStatement(true, null);
      this.setColour(cor);
      if (tooltip) this.setTooltip(tooltip);
    }
  };
};

/**
 * Cria um bloco expressão simples (retorna valor)
 * @param {string} tipo - ID único do bloco
 * @param {string} texto - Texto exibido no bloco
 * @param {string|null} tipoOutput - Tipo de saída ("Number", "Boolean", null)
 * @param {number} cor - HSV hue ou código de cor
 * @param {string} [tooltip] - Texto de ajuda (opcional)
 * @example
 * criarBlocoExpressaoSimples("robo_passos_get", "PASSOS", "Number", 330);
 */
export const criarBlocoExpressaoSimples = (tipo, texto, tipoOutput, cor, tooltip = "") => {
  Blockly.Blocks[tipo] = {
    init: function () {
      this.appendDummyInput().appendField(texto);
      this.setOutput(true, tipoOutput);
      this.setColour(cor);
      if (tooltip) this.setTooltip(tooltip);
    }
  };
};

/**
 * Cria um bloco expressão com dropdown
 * @param {string} tipo - ID único do bloco
 * @param {string} textoAntes - Texto antes do dropdown
 * @param {Array<[string, string]>} opcoes - Opções do dropdown
 * @param {string} nomeCampo - Nome do campo
 * @param {string|null} tipoOutput - Tipo de saída
 * @param {number} cor - HSV hue ou código de cor
 * @param {string} [textoDepois] - Texto após o dropdown (opcional)
 * @param {string} [tooltip] - Texto de ajuda (opcional)
 * @example
 * criarBlocoExpressaoComDropdown("robo_bloqueado", "caminho bloqueado à",
 *   [["FRENTE", "FRENTE"], ["DIREITA", "DIREITA"]], "SENTIDO", "Boolean", 270);
 */
export const criarBlocoExpressaoComDropdown = (
  tipo,
  textoAntes,
  opcoes,
  nomeCampo,
  tipoOutput,
  cor,
  textoDepois = "",
  tooltip = ""
) => {
  Blockly.Blocks[tipo] = {
    init: function () {
      const input = this.appendDummyInput().appendField(textoAntes);
      input.appendField(new Blockly.FieldDropdown(opcoes), nomeCampo);
      if (textoDepois) input.appendField(textoDepois);
      this.setOutput(true, tipoOutput);
      this.setColour(cor);
      if (tooltip) this.setTooltip(tooltip);
    }
  };
};

/**
 * Cria um bloco com value input e statement input (como if/else)
 * @param {string} tipo - ID único do bloco
 * @param {Object} config - Configuração do bloco
 * @param {string} config.textoCondicao - Label do value input
 * @param {Array<{nome: string, texto: string}>} config.statements - Statements [{nome: "FACA", texto: "faça"}, ...]
 * @param {number} config.cor - Cor do bloco
 * @param {string} [config.tooltip] - Texto de ajuda (opcional)
 * @example
 * criarBlocoCondicional("robo_if", {
 *   textoCondicao: "se",
 *   statements: [{nome: "FACA", texto: "faça"}],
 *   cor: 210
 * });
 */
export const criarBlocoCondicional = (tipo, config) => {
  Blockly.Blocks[tipo] = {
    init: function () {
      this.appendValueInput("CONDICAO")
        .setCheck("Boolean")
        .appendField(config.textoCondicao);
      
      config.statements.forEach(stmt => {
        this.appendStatementInput(stmt.nome)
          .setCheck(null)
          .appendField(stmt.texto);
      });
      
      this.setPreviousStatement(true, null);
      this.setNextStatement(true, null);
      this.setColour(config.cor);
      if (config.tooltip) this.setTooltip(config.tooltip);
    }
  };
};

/**
 * Cria um bloco de negação (operador unário)
 * @param {string} tipo - ID único do bloco
 * @param {string} texto - Texto do operador (ex: "não")
 * @param {number} cor - Cor do bloco
 * @param {string} [tooltip] - Texto de ajuda (opcional)
 * @example
 * criarBlocoNegacao("robo_not", "não", 210, "Inverte o resultado do sensor");
 */
export const criarBlocoNegacao = (tipo, texto, cor, tooltip = "") => {
  Blockly.Blocks[tipo] = {
    init: function () {
      this.appendValueInput("BOOL")
        .setCheck("Boolean")
        .appendField(texto);
      this.setOutput(true, "Boolean");
      this.setColour(cor);
      if (tooltip) this.setTooltip(tooltip);
    }
  };
};
