class OpcoesMetas {
  constructor(valor, operacao, percentual, item, id, idValor) {
    this.operacao = operacao;
    this.valor = valor;
    this.id = id;
    this.idValor = idValor;
    this.percentual = percentual;
    this.item = item;

    this.tipo = $('#txtSelectTipos').val();
    this.dt_inicio = $('#txtDtInicial').val();
    this.dt_final = $('#txtDtFinal').val();
    this.empresas = this.carregarEmpresasSelecionadas();
    this.dias = this.carregarDiasSelecionados();

    this.Metas = this.carregarDadosMetas();

    this.url = '/sisplan/metas/v1/opcoes?';
  }

  carregarDadosMetas() {
    return new Metas(
      this.tipo,
      $('#txtDescricaoMeta').val(),
      this.dt_inicio,
      this.dt_final,
      $('#txtIdMeta').val(),
      this.idValor
    );
  }

  carregarEmpresasSelecionadas() {
    return $('.empresa_selecionada:checked')
      .toArray()
      .map(input => input.id.split('-')[1])
      .toString();
  }

  carregarDiasSelecionados() {
    const dias = [];
    $('#tabelaDiasMeta').DataTable().rows().data().map((item, index) => {
      if ($($('.campoSel')[index]).prop('checked')) {
        dias.push(item.DATA.substring(0, 10));
      }
    });
    return dias;
  }

  validar() {
    const campos = [
      { nome: 'data inicial', valor: this.dt_inicio },
      { nome: 'data final', valor: this.dt_final },
      { nome: 'tipo', valor: this.tipo },
      { nome: 'operação', valor: this.operacao },
      { nome: 'valor', valor: this.valor },
      { nome: 'itens da meta', valor: this.item }
    ];

    for (const campo of campos) {
      if (!campo.valor || campo.valor === 0) {
        msgAlerta(`Campo ${campo.nome} não informado!`);
        return false;
      }
    }
    return true;
  }
  async iniciaEdicao() {
    this.limpaCamposOpcoes()

    $('#txtOperacaoMeta').val(this.operacao);
    $('#txtValorMeta').val(this.valor);
    $('#txtPercentual').val(this.percentual);
    $('#txtIdValorMetaSelecionado').val(this.idValor);


    const config = {
      LOJA: {
        campo: 'txtEmpresa',
        idKey: 'EMP_ID',
        nameKey: 'EMP_NOME',
      },
      PRODUTO: {
        campo: 'txtProduto',
        idKey: 'CODIGO',
        nameKey: 'DESCRICAO',
      },
      MATERIAL: {
        campo: 'txtMaterial',
        idKey: 'CODIGO',
        nameKey: 'DESCRICAO',
      },
      VENDEDOR: {
        campo: 'txtVendedor',
        idKey: 'CODREP',
        nameKey: 'NOME',
      },
      CLIENTE: {
        campo: 'txtCliente',
        idKey: 'CODCLI',
        nameKey: 'NOME',
      },
      GRUPO: {
        campo: 'txtGrupo',
        idKey: 'CODIGO',
        nameKey: 'DESCRICAO',
      },
      COLECAO: {
        campo: 'txtColecao',
        idKey: 'CODIGO',
        nameKey: 'DESCRICAO',
      },
    };

    const tipoConfig = config[this.tipo];
    if (tipoConfig) {
      const { campo, idKey, nameKey } = tipoConfig;
      const mappedItems = this.item.map(it => ({
        [idKey]: it.CODIGO,
        [nameKey]: it.NOME
      }));
      insereValorPesquisaVarios(campo, idKey, nameKey, mappedItems);
    }

    $('#btnGravarOpcoesMeta').html('Salvar');
    $('#btnCancelarSalvarOpcoesMeta').removeClass('d-none');
  }

  async editar() {
    const response = await requisicao('PUT', this.url, '', JSON.stringify(this), 15000);
    if (!response) return;

    if (response.status !== 200) {
      msgErro((await response.json()).mensagem);
      return;
    }

    await this.Metas.gravar()
    this.Metas.carregaValoresMeta();
    $('#txtIdValorMetaSelecionado').val('');
    criaMensagemSucesso('Valor da meta editada com sucesso!', () =>
      this.Metas.retornaItensValoresMetas()
    );
  }

  async buscarValoresMetas() {
    $('#tabelaOpcoesMetas').DataTable().rows().clear().draw(false);

    const response = await requisicao('GET', this.url, `ID=${this.idValor}&TIPO=${this.tipo}`, '', 150000);
    if (!response) return;

    const json = await response.json();
    if (response.status !== 200) {
      msgErro(json.mensagem);
      return;
    }

    return json;
  }

  async criaModalOpcoesMetas() {
    this.dadosOpcoesMetas = await this.buscarValoresMetas();
    this.dadosOpcoesMetas.forEach((item) => {
      $('#tabelaOpcoesMetas').DataTable().row.add(Object.values(item)).draw(false);
    });

    $('#modal-OpcoesMetas').modal('show');
    $('#tabelaOpcoesMetas').DataTable().columns.adjust().draw(false);
  }

  async gravarOpcoes() {
    this.empresas = this.empresas.split(',').map(e => `'${e}'`).toString();

    const response = await requisicao('POST', this.url, '', JSON.stringify(this));
    if (!response) return;

    const json = await response.json();
    if (response.status !== 200) {
      msgErro(json.mensagem);
      return;
    }

    await this.Metas.gravar()
    this.Metas.carregaValoresMeta();
    this.limpaCamposOpcoes()
    criaMensagemSucesso('Valor da meta gravada com sucesso!');
  }

  async deletarOpcoes() {
    const response = await requisicao('DELETE', this.url, `ID_VALOR=${this.idValor}`, '', 15000);
    if (!response) return;

    const json = await response.json();
    if (response.status !== 200) {
      msgErro(json.mensagem);
      return;
    }

    this.Metas.carregaValoresMeta();
    criaMensagemSucesso('Valor da meta deletado com sucesso!');
  }

  async buscaDiasMeta() {
    const opcoes = this;
    const valorMeta = this.valor;

    const select = {
      tabela: 'METADIAS',
      camposSelect: ['ANO.DIA_SEMANA', 'METADIAS.DIA', 'METADIAS.ID ID_METADIAS', 'METADIAS.VALOR'],
      leftJoin: [{ tabela: 'ANO', condicao: 'ANO.DATA = METADIAS.DIA' }],
      where: [`METADIAS.ID_VALOR = ${this.idValor} AND METADIAS.ID_META = ${this.id}`],
      orderBy: ['METADIAS.DIA']
    };

    const dados = await retornaJsonPesquisaPadrao(JSON.stringify(select));
    if (!dados.length) {
      msgAlerta('Valor sem dias cadastrados.');
      return;
    }

    const colunas = Object.keys(dados[0]).map(k => ({ data: k }));
    colunas.push({
      data: 'Valor',
      render: (data, type, row, meta) => {
        const valorDefault = row.VALOR || TruncaDecimaisNova(2, valorMeta / dados.length);
        const valorFinal = meta.row === dados.length - 1
          ? TruncaDecimaisNova(2, valorDefault + (valorMeta - (valorDefault * dados.length)))
          : valorDefault;

        return `<input type="number" class="form-control txtValorDias" value="${valorFinal}">`;
      }
    });

    criaDataTablePadrao('#tabelaDiasValor', false, false, false, false, true, false, '400px', dados, colunas, [2, 3], [1]);

    $('#txtSomaTotal').val(valorMeta);

    $('.txtValorDias').on('blur', function () {
      const total = $('.txtValorDias').toArray().reduce((acc, el) => acc + TruncaDecimaisNova(2, $(el).val()), 0);
      const diferenca = TruncaDecimaisNova(2, valorMeta - total);

      if (diferenca < 0) {
        msgAlerta(`Total ultrapassou o valor da meta! \nTotal: ${total} \nMeta: ${valorMeta}`);
        $('#btnVoltarValoresDiarios').trigger('click');
        return;
      }

      $('#txtSomaTotal').val(total);
      $('#txtDiferenca').val(diferenca);
    });

    $('#btnVoltarValoresDiarios').on('click', () => {
      const data = $('#tabelaDiasValor').DataTable().rows().data();
      $('.txtValorDias').each((i, el) => {
        $(el).val(data[i].VALOR);
      });
    });

    $('#btnConfirmarVincularDias').on('click', async () => {
      $.LoadingOverlay('show');
      event.preventDefault();
      try {
        await opcoes.gravarValoresDiasMeta();
      } finally {
        $.LoadingOverlay('hide');
      }
    });

    $('#modalDiasValor').modal('show');
  }

  async gravarValoresDiasMeta() {
    const data = $('#tabelaDiasValor').DataTable().rows().data().toArray();
    const total = $('.txtValorDias').toArray().reduce((acc, el) => acc + TruncaDecimaisNova(2, $(el).val()), 0);
    const totalTruncado = TruncaDecimaisNova(2, total);

    if (totalTruncado > this.valor || totalTruncado < this.valor) {
      msgAlerta(`Total inválido!\nTotal: ${totalTruncado} \nMeta: ${this.valor}`);
      return;
    }

    const payload = {
      IdValor: this.idValor,
      IdMeta: this.id,
      Dias: data.map((dia, i) => ({
        IdDia: dia.ID_METADIAS,
        Valor: $($('.txtValorDias')[i]).val()
      }))
    };

    const response = await requisicao('POST', '/sisplan/metas/v1/valoresdias?', '', JSON.stringify(payload), 15000);
    if (!response) return;

    if (response.status !== 200) {
      const json = await response.json();
      msgErro(json.mensagem);
      return;
    }

    criaMensagemSucesso('Valores diários gravados com sucesso!');
    $('#modalDiasValor').modal('hide');
  }

  limpaCamposOpcoes() {
    ['Empresa', 'Vendedor', 'Produto', 'Material', 'Colecao', 'Grupo', 'Cliente'].forEach(campo => {
      limpaValor(`#txt${campo}`);
    })

    $('#txtOperacaoMeta').val('');
    $('#txtValorMeta').val('');
    $('#txtPercentual').val('');
    $('#txtIdValorMetaSelecionado').val('');
  }

}
