let predictionsPanel;
const wheelSingleZero = [0, 32, 15, 19, 4, 21, 2, 25, 17, 34, 6, 27, 13, 36, 11,
  30, 8, 23, 10, 5, 24, 16, 33, 1, 20, 14, 31, 9, 22, 18, 29, 7, 28, 12, 35, 3, 26];

const wheelDoubleZero = [0, 28, 9, 26, 30, 11, 7, 20, 32, 17, 5, 22, 34, 15, 3,
  24, 36, 13, 1, 38, 27, 10, 25, 29, 12, 8, 19, 31, 18, 6, 21, 33, 16, 4, 23, 35, 14, 2];

function api_button_on_click_event(button) {
  button.addEventListener('click', () => {
    const popup = document.createElement('div');
    popup.classList.add('api-popup');
    popup.style.position = 'fixed';
    popup.style.top = '100px';
    popup.style.left = '100px';
    popup.style.backgroundColor = 'white';
    popup.style.padding = '20px';
    popup.style.border = '1px solid black';
    popup.style.zIndex = 1000;
    popup.style.maxHeight = '80vh';
    popup.style.overflowY = 'auto';

        const closeButton = document.createElement('button');
    closeButton.textContent = 'Close';
    closeButton.style.marginTop = '10px';
    closeButton.addEventListener('click', () => {
      popup.remove();
    });
    popup.appendChild(closeButton);



    const title = document.createElement('h1');
    title.innerText = 'Live Spin Numbers';
    popup.appendChild(title);

    const liveLink = document.createElement('a');
liveLink.href = 'spins.php';
liveLink.target = '_blank';
liveLink.textContent = 'Show Live Numbers';
liveLink.style.display = 'block';
liveLink.style.marginTop = '20px';
popup.appendChild(liveLink);

    const content = document.createElement('div');
    popup.appendChild(content);

    apis.forEach(api => {
      const section = document.createElement('div');
      section.style.marginBottom = '20px';

      const titleContainer = document.createElement('div');
      titleContainer.style.display = 'flex';
      titleContainer.style.justifyContent = 'space-between';
      titleContainer.style.alignItems = 'center';

      const title = document.createElement('h2');
      title.textContent = api.name;

      const refreshEntryButton = document.createElement('button');
      refreshEntryButton.textContent = 'Refresh';
      refreshEntryButton.style.marginLeft = '10px';
      refreshEntryButton.addEventListener('click', async () => {
        try {
          const response = await fetch(api.file);
          if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`);
          const updatedData = await response.json();
          const updatedNumbers = updatedData
            .map(entry => entry.data?.result?.outcome?.number)
            .filter(n => typeof n === 'number')
            .join(', ');

          const textbox = document.getElementById(`textbox-${api.name}`);
          if (textbox) {
            textbox.value = updatedNumbers;
          }
        } catch (error) {
          console.error(`Failed to refresh data for ${api.name}:`, error);
        }
      });

      titleContainer.appendChild(title);
      titleContainer.appendChild(refreshEntryButton);

      const textbox = document.createElement('textarea');
      textbox.id = `textbox-${api.name}`;
      textbox.style.width = '100%';
      textbox.style.height = '80px';
      textbox.style.marginTop = '10px';
      textbox.placeholder = 'Click Refresh to load data';

      const logButton = document.createElement('button');
      logButton.textContent = 'Add All Numbers to the Tool';
      logButton.style.marginTop = '10px';
      logButton.addEventListener('click', () => {
        applyAPI(api.name);
      });

      
 
      const manualAddText = document.createElement('span');
      manualAddText.textContent = 'Add all numbers once, then manually add numbers with the keypad on the right side of the roulette board.';
      manualAddText.style.display = 'block';
      manualAddText.style.marginTop = '5px';

      section.appendChild(titleContainer);
      section.appendChild(textbox);
      section.appendChild(logButton);
      section.appendChild(manualAddText);

      content.appendChild(section);
    });



    document.body.appendChild(popup);

    // Make popup draggable
    makeDraggable(popup);
  });
}

function applyAPI(name) {
  const textbox = document.getElementById(`textbox-${name}`);
  if (textbox && textbox.value.trim() !== '') {
    const numbers = textbox.value
      .split(',')
      .map(n => parseInt(n.trim()))
      .filter(n => !isNaN(n))
      .reverse(); // Reverse the order before applying

    if (Array.isArray(numbers)) {
      numbers.forEach(num => {
        // Assume numberPadSpin is your function that processes each number
        numberPadSpin(num);
      });
    }
  }
}


function makeDraggable(elmnt) {
  let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
  elmnt.onmousedown = dragMouseDown;

  function dragMouseDown(e) {
    e = e || window.event;
    e.preventDefault();
    pos3 = e.clientX;
    pos4 = e.clientY;
    document.onmouseup = closeDragElement;
    document.onmousemove = elementDrag;
  }

  function elementDrag(e) {
    e = e || window.event;
    e.preventDefault();
    pos1 = pos3 - e.clientX;
    pos2 = pos4 - e.clientY;
    pos3 = e.clientX;
    pos4 = e.clientY;
    elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
    elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
  }

  function closeDragElement() {
    document.onmouseup = null;
    document.onmousemove = null;
  }
}
//-----------------------------------------------------------------------------------------------------------------------------------
// AI Section
//------------------------------------------------------------------------------------------------------------------------------------

function getWheelNeighbors(number, wheelLayout) {
  const index = wheelLayout.findIndex(n => n === number || (n === '00' && number === 37));
  if (index === -1) return [];

  const neighbors = [];
  for (let i = -3; i <= 3; i++) {
    let neighborIndex = (index + i + wheelLayout.length) % wheelLayout.length;
    neighbors.push(wheelLayout[neighborIndex]);
  }
  return neighbors;
}

function getOutsideBet(n) {
  const red = [1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36];
  const black = [2, 4, 6, 8, 10, 11, 13, 15, 17, 20, 22, 24, 26, 28, 29, 31, 33, 35];

  return {
    color: red.includes(n) ? 'Red' : black.includes(n) ? 'Black' : 'Green',
    oddEven: n === 0 ? 'None' : n % 2 === 0 ? 'Even' : 'Odd',
    highLow: n === 0 ? 'None' : n <= 18 ? 'Low (1-18)' : 'High (19-36)',
    dozen: n === 0 ? 'None' : n <= 12 ? '1st Dozen' : n <= 24 ? '2nd Dozen' : '3rd Dozen',
    column: n === 0 ? 'None' : n % 3 === 1 ? '1st Column' : n % 3 === 2 ? '2nd Column' : '3rd Column',
  };
}


function ai_button_click_event(button) {
  button.addEventListener('click', () => {
    const popup = document.createElement('div');
  popup.style.position = 'fixed';
popup.style.top = '120px';
popup.style.left = '120px';
popup.style.backgroundColor = 'white';
popup.style.padding = '20px';
popup.style.border = '1px solid black';
popup.style.zIndex = '9999';         // keep it above everything
popup.style.overflow = 'visible';    // allow dropdowns to overflow
popup.style.maxHeight = 'none';      // remove clipping
popup.style.pointerEvents = 'auto';  // ensure interaction

    const closeButton = document.createElement('button');
    closeButton.textContent = 'Close';
    closeButton.style.marginBottom = '10px';
    closeButton.addEventListener('click', () => popup.remove());
    popup.appendChild(closeButton);

    const title = document.createElement('h1');
    title.innerText = 'Casino Number Fetcher';
    popup.appendChild(title);

const dropdown = document.createElement('select');
dropdown.style.width = '100%';
dropdown.style.marginBottom = '10px';
dropdown.style.padding = '5px';
dropdown.style.fontSize = '16px';
 dropdown.style.overflow = 'visible';

apis.forEach(api => {
  const option = document.createElement('option');
  option.value = api.file;
  option.textContent = api.name;
  dropdown.appendChild(option);
});
popup.appendChild(dropdown);



    const textbox = document.createElement('textarea');
    textbox.style.width = '100%';
    textbox.style.height = '80px';
    textbox.placeholder = 'Click Fetch to load data';
    popup.appendChild(textbox);

    const fetchButton = document.createElement('button');
    fetchButton.textContent = 'Fetch Numbers';
    fetchButton.style.marginTop = '10px';
    fetchButton.addEventListener('click', async () => {
      try {
        const file = dropdown.value;
        const response = await fetch(file);
        if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`);
        const data = await response.json();
        const numbers = data
          .map(entry => entry.data?.result?.outcome?.number)
          .filter(n => typeof n === 'number')
          .join(', ');
        textbox.value = numbers;
      } catch (err) {
        console.error('Fetch error:', err);
      }
    });
    popup.appendChild(fetchButton);

        const aiOneButton = document.createElement('button');
    aiOneButton.textContent = 'Predict';
    aiOneButton.style.marginTop = '10px';
    aiOneButton.style.marginLeft = '10px';
    aiOneButton.addEventListener('click', () => {
     if (predictionsPanel) {
  get_ai_predictions_with_model().then(newPanel => {
    predictionsPanel.replaceWith(newPanel);
    predictionsPanel = newPanel;
  });
}
    });
    popup.appendChild(aiOneButton);



    const addOneButton = document.createElement('button');
    addOneButton.textContent = 'Add Oldest Number';
    addOneButton.style.marginTop = '10px';
    addOneButton.style.marginLeft = '10px';
    addOneButton.addEventListener('click', () => {
      const values = textbox.value.split(',').map(v => v.trim()).filter(v => v !== '');
      if (values.length > 0) {
        const first = parseInt(values.shift());
        if (!isNaN(first)) numberPadSpin(first);
        textbox.value = values.join(', ');
if (predictionsPanel) {
  get_ai_predictions_with_model().then(newPanel => {
    predictionsPanel.replaceWith(newPanel);
    predictionsPanel = newPanel;
  });
}
      }
    });
    popup.appendChild(addOneButton);



      const predictionsTitle = document.createElement('h2');
predictionsTitle.textContent = 'AI Predictions';
predictionsTitle.style.marginTop = '20px';
popup.appendChild(predictionsTitle);

// Get content from your prediction function
predictionsPanel = get_ai_predictions();
popup.appendChild(predictionsPanel);


    document.body.appendChild(popup);
    ai_makeDraggable(popup);
  });





}
/*
function ai_makeDraggable(dragHandle, dragTarget) {
  let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
  dragHandle.onmousedown = dragMouseDown;

  function dragMouseDown(e) {
    e.preventDefault();
    pos3 = e.clientX;
    pos4 = e.clientY;
    document.onmouseup = closeDragElement;
    document.onmousemove = elementDrag;
  }

  function elementDrag(e) {
    e.preventDefault();
    pos1 = pos3 - e.clientX;
    pos2 = pos4 - e.clientY;
    pos3 = e.clientX;
    pos4 = e.clientY;
    dragTarget.style.top = (dragTarget.offsetTop - pos2) + "px";
    dragTarget.style.left = (dragTarget.offsetLeft - pos1) + "px";
  }

  function closeDragElement() {
    document.onmouseup = null;
    document.onmousemove = null;
  }
}
*/
function ai_makeDraggable(elmnt) {
  let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;

  elmnt.onmousedown = function (e) {
    e = e || window.event;

    // Prevent drag if clicking on an interactive element
    const tag = e.target.tagName.toLowerCase();
    if (['select', 'input', 'textarea', 'button', 'label'].includes(tag)) {
      return; // Do not initiate drag
    }

    e.preventDefault();
    pos3 = e.clientX;
    pos4 = e.clientY;
    document.onmouseup = closeDragElement;
    document.onmousemove = elementDrag;
  };

  function elementDrag(e) {
    e = e || window.event;
    e.preventDefault();
    pos1 = pos3 - e.clientX;
    pos2 = pos4 - e.clientY;
    pos3 = e.clientX;
    pos4 = e.clientY;
    elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
    elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
  }

  function closeDragElement() {
    document.onmouseup = null;
    document.onmousemove = null;
  }
}


function get_ai_predictions() {
  const panel = document.createElement('div');
  panel.style.border = '1px solid #ccc';
  panel.style.padding = '10px';
  panel.style.marginTop = '10px';
  panel.style.backgroundColor = '#f9f9f9';

  if (!Array.isArray(numbers) || numbers.length < 10) {
    panel.textContent = 'Not enough data for AI predictions.';
    return panel;
  }

  // --- Basic prediction logic ---
  const last10 = numbers.slice(-10);

  // Method 1: Frequency (most common in last 20)
  const freqMap = {};
  numbers.slice(-20).forEach(n => {
    freqMap[n] = (freqMap[n] || 0) + 1;
  });
  const mostFreq = Object.entries(freqMap).sort((a, b) => b[1] - a[1])[0][0];

  // Method 2: Momentum (last 3 different numbers shifted)
  const momentumGuess = (last10[last10.length - 1] + 3) % 37;

  // Method 3: "Neural Net" stub - avg + noise
  const avg = Math.round(last10.reduce((sum, n) => sum + n, 0) / last10.length);
  const neuralNetGuess = (avg + Math.floor(Math.random() * 5) - 2) % 37;

  // --- Outside Bets ---
  function getOutsideBet(n) {
    const red = [1,3,5,7,9,12,14,16,18,19,21,23,25,27,30,32,34,36];
    const black = [2,4,6,8,10,11,13,15,17,20,22,24,26,28,29,31,33,35];
    return {
      color: red.includes(n) ? 'Red' : black.includes(n) ? 'Black' : 'Green',
      oddEven: n === 0 ? 'None' : n % 2 === 0 ? 'Even' : 'Odd',
      highLow: n === 0 ? 'None' : n <= 18 ? 'Low (1-18)' : 'High (19-36)',
      dozen: n === 0 ? 'None' : n <= 12 ? '1st Dozen' : n <= 24 ? '2nd Dozen' : '3rd Dozen',
      column: n === 0 ? 'None' : n % 3 === 1 ? '1st Column' : n % 3 === 2 ? '2nd Column' : '3rd Column',
    };
  }
/*
  // --- Format predictions ---
  const methods = [
    { name: 'Neural Network (avg+noise)', number: neuralNetGuess },
    { name: 'Frequency Analysis', number: parseInt(mostFreq) },
    { name: 'Momentum Shift', number: momentumGuess }
  ];

  methods.forEach(method => {
    const bets = getOutsideBet(method.number);
    const section = document.createElement('div');
    section.innerHTML = `
      <strong>${method.name}</strong><br>
      Predicted Number: <b>${method.number}</b><br>
      Outside Bets: ${bets.color}, ${bets.oddEven}, ${bets.highLow}, ${bets.dozen}, ${bets.column}
      <hr>
    `;
    panel.appendChild(section);
  });
*/
  return panel;
}

//-----------------------------------------------------------------------------------------------------------------------------------
// AI TENSOR FLOW
//------------------------------------------------------------------------------------------------------------------------------------

async function trainRouletteModel(numbers) {
  const lookback = 5;
  if (numbers.length <= lookback) return null;

  // Prepare training data
  const xs = [];
  const ys = [];

  for (let i = 0; i < numbers.length - lookback; i++) {
    const input = numbers.slice(i, i + lookback).map(n => n / 36); // normalize
    const output = numbers[i + lookback]; // target
    xs.push(input);
    ys.push(output);
  }

  const xsTensor = tf.tensor2d(xs);
  const ysTensor = tf.tensor1d(ys, 'int32');
  const ysOneHot = tf.oneHot(ysTensor, 37);

  const model = tf.sequential();
  model.add(tf.layers.dense({ inputShape: [lookback], units: 32, activation: 'relu' }));
  model.add(tf.layers.dense({ units: 64, activation: 'relu' }));
  model.add(tf.layers.dense({ units: 37, activation: 'softmax' }));

  model.compile({
    optimizer: 'adam',
    loss: 'categoricalCrossentropy',
    metrics: ['accuracy']
  });

  await model.fit(xsTensor, ysOneHot, {
    epochs: 20,
    batchSize: 8,
    shuffle: true
  });

  return model;
}


async function predictNextNumber(model, numbers) {
  const lookback = 5;
  const recent = numbers.slice(-lookback).map(n => n / 36);
  const input = tf.tensor2d([recent]);
  const prediction = model.predict(input);
  const result = prediction.argMax(-1).dataSync()[0];
  return result; // predicted number 0-36
}


function getWheelBiasPrediction(numbers, wheelLayout) {
  if (numbers.length < 50) return null; // not enough data

  // Count hits per number
  const freqMap = Array(37).fill(0);
  for (const n of numbers) {
    if (typeof n === 'number' && n >= 0 && n <= 36) {
      freqMap[n]++;
    }
  }



  // Project frequency onto wheel positions as rolling clusters
  const wheelBiasScores = wheelLayout.map((number, i) => {
    let score = 0;
    for (let j = -2; j <= 2; j++) {
      const neighborIndex = (i + j + wheelLayout.length) % wheelLayout.length;
      const neighbor = wheelLayout[neighborIndex];
      if (typeof neighbor === 'number' && neighbor >= 0 && neighbor <= 36) {
        score += freqMap[neighbor];
      }
    }
    return { number, score };
  });

  // Sort clusters by total score
  wheelBiasScores.sort((a, b) => b.score - a.score);

  // Check if top score is significantly higher than average
  const avgScore = wheelBiasScores.reduce((sum, obj) => sum + obj.score, 0) / wheelBiasScores.length;
  const top = wheelBiasScores[0];

  if (top.score < avgScore + 1) {
    return null; // No strong bias found
  }

  return top.number;
}


  function detectDealerSignature(numbers, wheelLayout) {
  if (numbers.length < 15) return null;

  const offsets = [];

  for (let i = 1; i < numbers.length; i++) {
    const prev = numbers[i - 1];
    const curr = numbers[i];
    const prevIndex = wheelLayout.indexOf(prev);
    const currIndex = wheelLayout.indexOf(curr);
    if (prevIndex === -1 || currIndex === -1) continue;

    // Alternate spin direction assumption
    let offset;
    if (i % 2 === 0) {
      // Even-indexed spin = clockwise
      offset = (currIndex - prevIndex + wheelLayout.length) % wheelLayout.length;
    } else {
      // Odd-indexed spin = counter-clockwise
      offset = (prevIndex - currIndex + wheelLayout.length) % wheelLayout.length;
    }

    offsets.push(offset);
  }

  // Count how often each offset appears
  const offsetCounts = {};
  offsets.forEach(off => offsetCounts[off] = (offsetCounts[off] || 0) + 1);

  const sortedOffsets = Object.entries(offsetCounts).sort((a, b) => b[1] - a[1]);
  const [mostCommonOffset, count] = sortedOffsets[0];
  const total = offsets.length;
  const percent = (count / total) * 100;

  if (percent >= 30) {
    // Predict next spin direction
    const lastNumber = numbers[numbers.length - 1];
    const lastIndex = wheelLayout.indexOf(lastNumber);
    const nextDirection = (numbers.length % 2 === 0) ? 'cw' : 'ccw';

    let predictedIndex;
    if (nextDirection === 'cw') {
      predictedIndex = (lastIndex + parseInt(mostCommonOffset)) % wheelLayout.length;
    } else {
      predictedIndex = (lastIndex - parseInt(mostCommonOffset) + wheelLayout.length) % wheelLayout.length;
    }

    const predictedNumber = wheelLayout[predictedIndex];

    return {
      offset: parseInt(mostCommonOffset),
      confidence: percent.toFixed(1),
      predictedNumber,
      direction: nextDirection,
      zone: getWheelNeighbors(predictedNumber, wheelLayout)
    };
  }

  return null;
}


async function get_ai_predictions_with_model() {
  const panel = document.createElement('div');
  panel.textContent = 'Training AI model...';

  if (numbers.length < 10) {
    panel.textContent = 'Not enough data for AI training.';
    return panel;
  }

  const model = await trainRouletteModel(numbers);
  const predictedNumber = await predictNextNumber(model, numbers);

  const singleZeroNeighbors = getWheelNeighbors(predictedNumber, wheelSingleZero);
const doubleZeroNeighbors = getWheelNeighbors(predictedNumber, wheelDoubleZero);

  const bets = getOutsideBet(predictedNumber);

  const biasNumber = getWheelBiasPrediction(numbers, wheelSingleZero);
const biasNeighbors = getWheelNeighbors(biasNumber, wheelSingleZero);

panel.innerHTML = `
  <strong>Neural Net </strong><br>
  Predicted Number: <b>${predictedNumber === 37 ? '00' : predictedNumber}</b><br>
  Outside Bets: ${bets.color}, ${bets.oddEven}, ${bets.highLow}, ${bets.dozen}, ${bets.column}<br><br>

  <strong>Wheel Section (Single-Zero)</strong><br>
  ${singleZeroNeighbors.map(n => n === 37 ? '00' : n).join(', ')}<br><br>

  <strong>Wheel Section (Double-Zero)</strong><br>
  ${doubleZeroNeighbors.map(n => n === 37 ? '00' : n).join(', ')}
`;

if (biasNumber !== null) {
  const biasNeighbors = getWheelNeighbors(biasNumber, wheelSingleZero);
  panel.innerHTML += `<br><br>
    <strong>Wheel Bias Prediction</strong><br>
    Predicted Number: <b>${biasNumber}</b><br>
    Bias Zone (±2 on wheel): ${biasNeighbors.join(', ')}<br><br>
  `;
} else {
  panel.innerHTML += `<br><br><strong>Wheel Bias Prediction</strong><br>
    No strong bias detected yet.<br><br>`;
}

const dealerSignature = detectDealerSignature(numbers, wheelSingleZero);
if (dealerSignature) {
  panel.innerHTML += `<br><br>
    <strong>Dealer Signature Detected Single Zero</strong><br>
    Most Common Offset: <b>${dealerSignature.offset}</b><br>
    Confidence: ${dealerSignature.confidence}%<br>
    Assumed Next Spin Direction: <b>${dealerSignature.direction.toUpperCase()}</b><br>
    Predicted Number: <b>${dealerSignature.predictedNumber}</b><br>
    Likely Zone (±3): ${dealerSignature.zone.join(', ')}
  `;
} else {
  panel.innerHTML += `<br><br><strong>Dealer Signature Detected Single Zero</strong><br>
    No consistent signature detected yet.
  `;
}

const dealerSignature0 = detectDealerSignature(numbers, wheelDoubleZero);
if (dealerSignature0) {
  panel.innerHTML += `<br><br>
    <strong>Dealer Signature Detected Double Zero</strong><br>
    Most Common Offset: <b>${dealerSignature.offset}</b><br>
    Confidence: ${dealerSignature.confidence}%<br>
    Assumed Next Spin Direction: <b>${dealerSignature.direction.toUpperCase()}</b><br>
    Predicted Number: <b>${dealerSignature.predictedNumber}</b><br>
    Likely Zone (±3): ${dealerSignature.zone.join(', ')}
  `;
} else {
  panel.innerHTML += `<br><br><strong>Dealer Signature Detected Double Zero</strong><br>
    No consistent signature detected yet.
  `;
}

  return panel;
}
