// Painel de configuracao injetado na pagina do jogo.
//
// Ele NAO guarda estado proprio: desenha o que o C# manda e, a cada mexida,
// escreve de volta no controle WinForms correspondente pela ponte. Assim os
// 145 pontos da automacao que leem `sellLootCheck.Checked` e companhia seguem
// lendo o mesmo lugar de sempre, e a aparencia mudou sem a logica mudar.
(function () {
  if (window.__idleHelperConfigInstalado) return;
  window.__idleHelperConfigInstalado = true;

  // Que campo entra em que aba, e o texto de cada um. O C# manda apenas
  // valores; os rotulos e a organizacao vivem aqui.
  const SECOES = {
    hunt: [
      { id: 'hunt', nome: 'Hunt', dica: 'Para onde o personagem vai caçar' },
      { id: 'lure', nome: 'Lure', dica: 'Quantas criaturas puxar por vez' },
      { id: 'venderLoot', nome: 'Vender loot e voltar', dica: 'Liga o ciclo: caça, sai pra vender quando encher e volta' },
      { id: 'capacidade', nome: 'Vender com cap ≤', dica: 'Capacidade livre que dispara a saída pra vender' },
      { id: 'blacklist', nome: 'Blacklist de venda', dica: 'Itens que nunca devem ser vendidos — pode editar rodando' },
      { id: 'consumo', nome: 'Consumo', dica: 'Itens com carga a acompanhar — pode editar rodando' }
    ],
    party: [
      { id: 'papel', nome: 'Meu papel', dica: 'Solo, líder ou membro da party' },
      { id: 'confirmarParty', nome: 'Confirmar party', dica: 'Aceita o convite automaticamente' },
      { id: 'splitarLoot', nome: 'Splitar loot', dica: 'Divide o gold com a party' },
      { id: 'usarPosicao', nome: 'Usar posicionamento', dica: 'Assume a posição calibrada ao entrar na hunt' },
      { id: 'definirPosicao', nome: 'Definir posição', dica: 'Escolhe o tile na grade do jogo' }
    ],
    stamina: [
      { id: 'treinarStamina', nome: 'Ir pro trainer ao zerar a stamina', dica: 'Manda o personagem treinar em vez de ficar parado' },
      { id: 'skill', nome: 'Skill', dica: 'O que treinar — e qual exercise weapon pedir no daily reward' },
      { id: 'fecharAoTreinar', nome: 'Fechar a aba ao zerar a stamina', dica: 'Libera a memória, mas perde o log e o gold desta conta' }
    ],
    geral: [
      { id: 'velocidade', nome: 'Velocidade', dica: 'Ritmo das ações do bot' },
      { id: 'antiIdle', nome: 'Anti-idle', dica: 'Evita a desconexão por inatividade' },
      { id: 'autoReconectar', nome: 'Auto reconectar', dica: 'Volta sozinho se a conexão cair' },
      { id: 'confirmarMorte', nome: 'Confirmar morte automaticamente', dica: 'Aceita a tela de morte e volta' },
      { id: 'notificacoes', nome: 'Notificações', dica: 'O que mandar pro Telegram' }
    ]
  };

  let estado = {};
  let secaoAtual = 'hunt';

  const raiz = document.createElement('div');
  raiz.id = 'idle-helper-config';

  const enviar = (msg) => window.chrome.webview.postMessage(JSON.stringify(msg));
  const mexer = (id, valor) => enviar({ idleHelper: 'config-set', campo: id, valor: valor });

  function linha(def) {
    const campo = estado[def.id];
    if (!campo) return null;

    const el = document.createElement('div');
    el.className = 'ih-linha' + (campo.ativo ? '' : ' travada');

    const rotulo = document.createElement('div');
    rotulo.className = 'ih-rotulo';

    const nome = document.createElement('span');
    nome.className = 'nome';
    nome.textContent = def.nome;

    const dica = document.createElement('span');
    dica.className = 'dica';
    dica.textContent = def.dica;

    rotulo.append(nome, dica);
    el.appendChild(rotulo);

    let controle;

    if (campo.tipo === 'bool') {
      controle = document.createElement('div');
      controle.className = 'ih-toggle' + (campo.valor ? ' ligado' : '');
      controle.addEventListener('click', () => {
        if (!campo.ativo) return;
        // Otimista: vira na hora e o C# confirma no próximo empurrão. Esperar
        // a ida e volta faria o toggle parecer emperrado.
        campo.valor = !campo.valor;
        controle.classList.toggle('ligado', campo.valor);
        mexer(def.id, campo.valor);
      });
    } else if (campo.tipo === 'lista') {
      controle = document.createElement('select');
      controle.className = 'ih-select';
      controle.disabled = !campo.ativo;

      campo.opcoes.forEach((texto, i) => {
        const op = document.createElement('option');
        op.value = String(i);
        op.textContent = texto;
        if (i === campo.valor) op.selected = true;
        controle.appendChild(op);
      });

      controle.addEventListener('change', () => mexer(def.id, Number(controle.value)));
    } else if (campo.tipo === 'numero') {
      controle = document.createElement('input');
      controle.className = 'ih-numero';
      controle.type = 'number';
      controle.min = campo.min;
      controle.max = campo.max;
      controle.value = campo.valor;
      controle.disabled = !campo.ativo;
      controle.addEventListener('change', () => mexer(def.id, Number(controle.value)));
    } else if (campo.tipo === 'botao') {
      controle = document.createElement('button');
      controle.className = 'ih-acao';
      controle.textContent = campo.texto.replace(/^[^A-Za-zÀ-ÿ]+/, '') || def.nome;
      controle.disabled = !campo.ativo;

      // Blacklist e Consumo abrem aqui dentro; o resto continua acionando o
      // botão WinForms correspondente pela ponte.
      controle.addEventListener('click', () => {
        if (LISTAS[def.id]) abrirLista(def.id);
        else if (def.id === 'notificacoes') abrirTelegram();
        else mexer(def.id, true);
      });
    }

    if (controle) {
      controle.dataset.campo = def.id;
      el.appendChild(controle);
    }
    return el;
  }

  function pintarCorpo() {
    const corpo = raiz.querySelector('#ih-corpo');
    if (!corpo) return;

    // Nada mudou desde o último desenho: não mexe. Recriar os campos a cada 5s
    // fecharia um <select> aberto na cara de quem está escolhendo.
    const defs = SECOES[secaoAtual] || [];
    const assinatura = secaoAtual + '|' + defs.map((d) => {
      const c = estado[d.id];
      return c ? d.id + ':' + c.valor + ':' + c.ativo : d.id + ':-';
    }).join('|');

    if (assinatura === corpoDesenhado) return;
    corpoDesenhado = assinatura;

    // Mesmo quando muda, o campo em foco é preservado: se o empurrão pegasse
    // você digitando na capacidade, o número seria sobrescrito no meio da
    // digitação. Volta com o cursor onde estava.
    const focado = document.activeElement;
    const idFocado = focado && corpo.contains(focado) ? focado.dataset.campo : null;
    const posicao = idFocado ? focado.selectionStart : null;
    const valorEmEdicao = idFocado ? focado.value : null;

    corpo.innerHTML = '';
    (SECOES[secaoAtual] || []).forEach((def) => {
      const el = linha(def);
      if (el) corpo.appendChild(el);
    });

    if (idFocado) {
      const novo = corpo.querySelector('[data-campo="' + idFocado + '"]');
      if (novo) {
        novo.value = valorEmEdicao;
        novo.focus();
        try { novo.setSelectionRange(posicao, posicao); } catch (e) {}
      }
    }
  }

  function pintarExecucao() {
    const iniciar = raiz.querySelector('[data-acao="iniciar"]');
    const parar = raiz.querySelector('[data-acao="parar"]');
    const rotulo = raiz.querySelector('#ih-estado');
    if (!iniciar || !parar || !rotulo) return;

    const podeIniciar = estado.iniciar ? estado.iniciar.ativo : false;
    iniciar.disabled = !podeIniciar;
    parar.disabled = estado.parar ? !estado.parar.ativo : true;

    // "Pode parar" é a leitura mais confiável de que está rodando: vem do
    // próprio botão, não de uma flag paralela que poderia divergir.
    const rodando = estado.parar ? estado.parar.ativo : false;
    rotulo.textContent = rodando ? 'Automação rodando' : 'Parada';
    rotulo.classList.toggle('rodando', rodando);
  }

  function montar() {
    if (document.getElementById('idle-helper-config')) return;
    if (!document.body) return;
    document.body.appendChild(raiz);
  }

  window.__idleHelperConfigAbrir = function (aberto) {
    raiz.classList.toggle('aberto', !!aberto);
  };

  // ---- Sub-painel das listas ---------------------------------------------
  // Blacklist e Consumo são listas de item, não ajustes. Por isso não viraram
  // abas ao lado de Hunt/Party/Stamina/Geral: são de natureza diferente, e
  // seis abas em 600px ficariam apertadas.
  const LISTAS = {
    blacklist: {
      nome: 'Blacklist de venda',
      dica: 'Itens que a Venda Rápida nunca deve vender',
      add: 'add-blacklist',
      rem: 'remove-blacklist',
      vazio: 'Nenhum item na blacklist. O botão direito num item do jogo também adiciona aqui.'
    },
    consumo: {
      nome: 'Rastrear consumo',
      dica: 'A cada venda, compara a quantidade com a anterior e avisa a diferença no Telegram',
      add: 'add-tracked',
      rem: 'remove-tracked',
      vazio: 'Nenhum item rastreado. Serve pra anéis e amuletos com carga.'
    }
  };

  // O que está desenhado agora, pra não redesenhar à toa. O C# reempurra o
  // estado a cada 5s; sem estas comparações a lista era recriada do zero toda
  // vez e, como cada item tem animação de entrada, TODOS re-animavam — a lista
  // piscava sem parar.
  let corpoDesenhado = null;
  let itensDesenhados = null;
  let listaAberta = null;

  function abrirLista(id) {
    const def = LISTAS[id];
    if (!def) return;

    listaAberta = id;
    itensDesenhados = null;   // a caixa pode estar com a outra lista
    raiz.querySelector('#ih-lista-nome').textContent = def.nome;
    raiz.querySelector('#ih-lista-dica').textContent = def.dica;
    raiz.querySelector('#ih-lista-tela').classList.add('aberta');
    raiz.querySelector('#ih-lista-campo').value = '';
    pintarItens();

    setTimeout(() => raiz.querySelector('#ih-lista-campo').focus(), 240);
  }

  function fecharLista() {
    listaAberta = null;
    raiz.querySelector('#ih-lista-tela').classList.remove('aberta');
  }

  function pintarItens() {
    if (!listaAberta) return;

    const caixa = raiz.querySelector('#ih-lista-itens');
    const def = LISTAS[listaAberta];
    const itens = (estado.__listas && estado.__listas[listaAberta]) || [];

    const assinatura = listaAberta + ' ' + itens.join(' ');
    if (assinatura === itensDesenhados) return;
    itensDesenhados = assinatura;

    caixa.innerHTML = '';

    if (!itens.length) {
      const vazio = document.createElement('div');
      vazio.className = 'ih-vazio';
      vazio.textContent = def.vazio;
      caixa.appendChild(vazio);
      return;
    }

    itens.forEach((item) => {
      const el = document.createElement('div');
      el.className = 'ih-item';

      // textContent, nunca innerHTML: o nome vem do jogo (foi digitado ou veio
      // do aria-label de um item) e não é nosso pra confiar como marcação.
      const nome = document.createElement('span');
      nome.textContent = item;

      const remover = document.createElement('button');
      remover.textContent = '×';
      remover.title = 'Remover';
      remover.addEventListener('click', () => enviar({
        idleHelper: 'lista', acao: def.rem, item: item
      }));

      el.append(nome, remover);
      caixa.appendChild(el);
    });
  }

  function adicionarItem() {
    if (!listaAberta) return;

    const campo = raiz.querySelector('#ih-lista-campo');
    const item = campo.value.trim();
    if (!item) return;

    enviar({ idleHelper: 'lista', acao: LISTAS[listaAberta].add, item: item });
    campo.value = '';
    campo.focus();
  }

  // ---- Telegram ------------------------------------------------------------
  const AVISOS = [
    ['loot', 'Venda de loot'],
    ['split', 'Split de gold'],
    ['goldRecebido', 'Gold recebido de outro player'],
    ['conexao', 'Conexão e reconexão'],
    ['nivel', 'Subir de nível'],
    ['alertas', 'Erros e avisos'],
    ['morte', 'Morte do personagem']
  ];

  const tg = (acao, extra) =>
    enviar(Object.assign({ idleHelper: 'telegram', acao: acao }, extra || {}));

  let tgAberto = false;
  let tgDesenhado = null;

  // Um pedido de link por vez. Sem isso, cada empurrão de estado dispararia
  // outro "vincular" e o servidor geraria um QR novo a cada 3 segundos —
  // trocando o código embaixo de quem já está escaneando.
  let tgPedindo = false;

  function abrirTelegram() {
    tgAberto = true;
    tgDesenhado = null;
    tgPedindo = false;
    raiz.querySelector('#ih-tg-tela').classList.add('aberta');
    tg('estado');
  }

  function fecharTelegram() {
    tgAberto = false;
    tgPedindo = false;
    raiz.querySelector('#ih-tg-tela').classList.remove('aberta');
    tg('parar-espera');   // sem a tela aberta, não há motivo pra continuar
  }

  // ih-acao, não "botao": esta é a folha do painel de config (config.css). A
  // classe "botao" existe só na barra lateral (chrome.html), e usá-la aqui
  // deixava o elemento sem estilo nenhum.
  function botao(texto, classe, aoClicar) {
    const b = document.createElement('button');
    b.className = 'ih-acao' + (classe ? ' ' + classe : '');
    b.textContent = texto;
    b.addEventListener('click', aoClicar);
    return b;
  }

  window.__idleHelperTelegram = function (d) {
    if (!tgAberto) return;

    const corpo = raiz.querySelector('#ih-tg-corpo');

    // Mesma guarda das outras telas: o C# reempurra sozinho, e recriar tudo
    // reiniciaria a animação dos cartões.
    const assinatura = JSON.stringify(d);
    if (assinatura === tgDesenhado) return;
    tgDesenhado = assinatura;

    corpo.innerHTML = '';

    // O rodapé vive FORA do corpo (pra não rolar junto), então o innerHTML
    // acima não o limpa — sem isto, cada redesenho empilharia outro par de
    // botões embaixo do anterior.
    const rodapeAntigo = raiz.querySelector('#ih-tg-tela .ih-tg-acoes');
    if (rodapeAntigo) rodapeAntigo.remove();

    if (d.erro) {
      const erro = document.createElement('div');
      erro.className = 'ih-tg-erro';
      erro.textContent = d.erro;
      corpo.appendChild(erro);

      // Falhou: solta a trava e oferece a tentativa, em vez de deixar a tela
      // parada em "Gerando o link…" pra sempre.
      tgPedindo = false;
      corpo.appendChild(botao('Tentar de novo', 'iniciar', () => {
        tgDesenhado = null;
        tgPedindo = true;
        tg('vincular');
      }));
      return;
    }

    if (d.vinculado) {
      // O alcance de cada metade é diferente e não é óbvio: o VÍNCULO é da
      // máquina (vale pra todos os perfis), mas as categorias abaixo são desta
      // conta. Sem dizer isso, desmarcar aqui e continuar recebendo das outras
      // abas pareceria bug.
      raiz.querySelector('#ih-tg-sub').textContent =
        'Estas opções valem só para esta conta';

      const estado = document.createElement('div');
      estado.className = 'ih-tg-estado';
      estado.textContent = '✓ Telegram vinculado';
      corpo.appendChild(estado);

      const alcance = document.createElement('div');
      alcance.className = 'ih-tg-passos';
      alcance.style.padding = '10px 2px 4px';
      alcance.innerHTML =
        'O vínculo vale pra <b>todos os perfis</b>. O que marcar aqui embaixo ' +
        'vale só pra <b>esta conta</b> — as outras abas têm as suas.';
      corpo.appendChild(alcance);

      AVISOS.forEach(([id, rotulo]) => {
        const linha = document.createElement('div');
        linha.className = 'ih-tg-linha';

        const nome = document.createElement('span');
        nome.textContent = rotulo;

        const toggle = document.createElement('div');
        const ligado = !!(d.avisos && d.avisos[id]);
        toggle.className = 'ih-toggle' + (ligado ? ' ligado' : '');
        toggle.addEventListener('click', () => {
          const novo = !toggle.classList.contains('ligado');
          toggle.classList.toggle('ligado', novo);
          if (d.avisos) d.avisos[id] = novo;
          tgDesenhado = null;   // o estado local mudou
          tg('marcar', { categoria: id, ligado: novo });
        });

        linha.append(nome, toggle);
        corpo.appendChild(linha);
      });

      // Irmão do corpo, não filho: o corpo é que rola, e dentro dele os botões
      // sumiriam abaixo do corte numa tela baixa.
      const acoes = document.createElement('div');
      acoes.className = 'ih-tg-acoes';
      acoes.append(
        botao('Enviar teste', '', () => tg('testar')),
        botao('Desvincular', 'parar', () => tg('desvincular'))
      );
      corpo.parentElement.appendChild(acoes);
      return;
    }

    // --- Ainda não vinculado ---
    raiz.querySelector('#ih-tg-sub').textContent = 'Vale para todos os perfis';

    const passos = document.createElement('div');
    passos.className = 'ih-tg-passos';
    // "com a câmera do celular", e não "com o Telegram": o scanner interno do
    // Telegram serve pra login e QR de contato, e costuma ignorar um deep link
    // t.me/bot?start=. A câmera nativa reconhece como link e abre o Telegram.
    passos.innerHTML =
      '<b>1.</b> Aperte o botão abaixo, ou aponte a <b>câmera do celular</b> ' +
      'pro QR (não o scanner do Telegram).<br>' +
      '<b>2.</b> Aperte <b>Iniciar</b> no bot do Telegram.<br>' +
      '<b>3.</b> Esta tela reconhece sozinha.';
    corpo.appendChild(passos);

    if (d.qr) {
      // O botão vem antes do QR: ele resolve num clique, no mesmo computador.
      // O QR é o plano B, pra quem prefere usar o Telegram do celular.
      corpo.appendChild(botao('Abrir no Telegram', 'iniciar',
        () => tg('abrir-telegram', { url: d.deepLink })));

      const ou = document.createElement('div');
      ou.className = 'ih-tg-passos';
      ou.style.textAlign = 'center';
      ou.style.padding = '14px 0 2px';
      ou.textContent = 'ou aponte a câmera do celular:';
      corpo.appendChild(ou);

      const img = document.createElement('img');
      img.className = 'ih-qr';
      img.src = 'data:image/png;base64,' + d.qr;
      img.alt = 'QR de vínculo';
      corpo.appendChild(img);

      const esperando = document.createElement('div');
      esperando.className = 'ih-esperando';
      esperando.textContent = 'Esperando você aceitar no celular…';
      esperando.style.marginTop = '12px';
      corpo.appendChild(esperando);
      return;
    }

    // Sem QR ainda: pede o link SOZINHO, como o diálogo antigo fazia. Um botão
    // "Gerar link" aqui seria um clique a mais pra chegar no mesmo lugar —
    // quem abriu esta tela já disse que quer vincular.
    const gerando = document.createElement('div');
    gerando.className = 'ih-esperando';
    gerando.textContent = 'Gerando o link…';
    corpo.appendChild(gerando);

    if (!tgPedindo) {
      tgPedindo = true;
      tgDesenhado = null;
      tg('vincular');
    }
  };

  window.__idleHelperConfigEstado = function (novo) {
    estado = novo || {};
    pintarExecucao();
    pintarCorpo();
    pintarItens();
  };

  window.__idleHelperConfigMontar = function (html, css) {
    raiz.innerHTML = html;

    if (!document.getElementById('idle-helper-config-css')) {
      const estilo = document.createElement('style');
      estilo.id = 'idle-helper-config-css';
      estilo.textContent = css;
      document.head.appendChild(estilo);
    }

    raiz.querySelector('#ih-fechar').addEventListener('click', fechar);
    raiz.querySelector('#ih-fundo').addEventListener('click', fechar);

    raiz.querySelectorAll('.ih-aba').forEach((aba) => {
      aba.addEventListener('click', () => {
        secaoAtual = aba.dataset.secao;
        raiz.querySelectorAll('.ih-aba').forEach((o) => o.classList.toggle('ativa', o === aba));
        pintarCorpo();
      });
    });

    raiz.querySelector('[data-acao="iniciar"]').addEventListener('click', () => mexer('iniciar', true));
    raiz.querySelector('[data-acao="parar"]').addEventListener('click', () => mexer('parar', true));

    raiz.querySelector('#ih-voltar').addEventListener('click', fecharLista);
    raiz.querySelector('#ih-tg-voltar').addEventListener('click', fecharTelegram);
    raiz.querySelector('#ih-lista-add').addEventListener('click', adicionarItem);
    raiz.querySelector('#ih-lista-campo').addEventListener('keydown', (e) => {
      if (e.key === 'Enter') { e.preventDefault(); adicionarItem(); }
    });

    montar();
    new MutationObserver(montar).observe(document.body, { childList: true, subtree: false });
  };

  window.__idleHelperConfigPerfil = function (nome) {
    const el = raiz.querySelector('#ih-perfil');
    if (el) el.textContent = nome;
  };

  function fechar() {
    raiz.classList.remove('aberto');

    // Fechar o painel inteiro também encerra a espera do vínculo: sem isso o
    // C# ficaria perguntando ao servidor a cada 3s pra ninguém.
    if (tgAberto) fecharTelegram();

    enviar({ idleHelper: 'config-fechado' });
  }

  // Esc fecha. Capturado no documento porque o foco costuma estar no canvas
  // do jogo, não dentro do painel.
  document.addEventListener('keydown', (e) => {
    if (e.key !== 'Escape' || !raiz.classList.contains('aberto')) return;

    e.stopPropagation();

    // Uma tela por vez: com um sub-painel aberto, Esc volta pra config em vez
    // de fechar as duas de uma vez.
    if (tgAberto) fecharTelegram();
    else if (listaAberta) fecharLista();
    else fechar();
  }, true);
})();
