let portfolioData = [];
let coinColors = {};
let addTransactionModal, editTransactionModal, colorConfigModal, noteModal;
let buyForm, sellForm;
let portfolioList, pieChartCanvas, chartLegend;
let editIdGlobal = null;
let currentNoteId = null;
let currentNoteType = null;

function formatPrice(value) {
  if (isNaN(value)) return "-";
  if (value < 0.01) return value.toFixed(6);
  if (value < 1) return value.toFixed(4);
  return value.toFixed(2);
}

document.addEventListener("DOMContentLoaded", () => {
  addTransactionModal = document.getElementById("addTransactionModal");
  editTransactionModal = document.getElementById("editTransactionModal");
  colorConfigModal = document.getElementById("colorConfigModal");
  noteModal = document.getElementById("noteModal");
  buyForm = document.getElementById("buyForm");
  sellForm = document.getElementById("sellForm");
  portfolioList = document.getElementById("portfolioList");
  pieChartCanvas = document.getElementById("portfolioPieChart");
  chartLegend = document.getElementById("chartLegend");
  
  window.addEventListener("click", (event) => {
    if (event.target === addTransactionModal) closeAddTransactionModal();
    if (event.target === editTransactionModal) closeEditTransactionModal();
    if (event.target === colorConfigModal) closeColorConfigModal();
    if (event.target === noteModal) closeNoteModal();
  });
  
  loadCoinColorsFromStorage();
  loadPortfolioData();
  setInterval(() => {
    updatePrices();
  }, 10000);
});

function loadPortfolioData() {
  fetch("/api/portfolio", { credentials: "include" })
    .then(r => r.json())
    .then(d => {
      portfolioData = d.transactions || [];
      updatePrices();
    });
}

function updatePrices() {
  fetch("/api/portfolio/prices", { credentials: "include" })
    .then(r => r.json())
    .then(arr => {
      portfolioData = arr.map(x => {
        x.id = String(x.id);
        return x;
      });
      renderPortfolio();
      drawPieChart();
    });
}

function renderPortfolio() {
  portfolioList.innerHTML = "";
  let grouped = {};
  portfolioData.forEach(t => {
    if (!grouped[t.symbol]) grouped[t.symbol] = [];
    grouped[t.symbol].push(t);
  });
  
  for (let sym in grouped) {
    const section = document.createElement("div");
    section.className = "coin-section";
    const heading = document.createElement("h2");
    heading.textContent = sym;
    section.appendChild(heading);
    
    const table = document.createElement("table");
    const thead = document.createElement("thead");
    thead.innerHTML = `
      <tr>
        <th>Symbol</th>
        <th>Amount</th>
        <th>Buy Price</th>
        <th>Current</th>
        <th>Invest</th>
        <th>Profit / Loss</th>
        <th>% Change</th>
        <th>Buy Date</th>
      </tr>
    `;
    table.appendChild(thead);
    
    const tbody = document.createElement("tbody");
    let totalAmount = 0;
    let totalCost = 0;
    
    grouped[sym].forEach(tx => {
      const currentTotal = tx.amount * tx.currentPrice;
      const initialTotal = tx.amount * tx.buyPrice;
      const diff = currentTotal - initialTotal;
      const pct = initialTotal === 0 ? 0 : (diff / initialTotal) * 100;
      totalAmount += tx.amount;
      totalCost += initialTotal;
      
      const row = document.createElement("tr");
      const diffClass = diff >= 0 ? "positive" : "negative";
      const editButton = `<span class="edit-button" onclick="openEditTransactionModal('${tx.id}')">✎</span>`;
      const noteButton = `<span class="note-button ${tx.note ? 'has-note' : 'no-note'}" onclick="openNoteModal('${tx.id}', 'portfolio')">✉</span>`;
      
      row.innerHTML = `
        <td>${tx.symbol}</td>
        <td>${tx.amount}</td>
        <td>${formatPrice(tx.buyPrice)}</td>
        <td>${formatPrice(tx.currentPrice)}</td>
        <td>${(tx.amount * tx.buyPrice).toFixed(2)}</td>
        <td class="${diffClass}">${diff.toFixed(2)}</td>
        <td class="${diffClass}">${pct.toFixed(2)}%</td>
        <td>${tx.date}${editButton}${noteButton}</td>
      `;
      tbody.appendChild(row);
    });
    
    const totalCurrent = totalAmount * (grouped[sym][0].currentPrice || 0);
    const totalDiff = totalCurrent - totalCost;
    const totalPct = totalCost === 0 ? 0 : (totalDiff / totalCost) * 100;
    const avgBuyPrice = totalAmount === 0 ? 0 : totalCost / totalAmount;
    
    const totalRow = document.createElement("tr");
    totalRow.className = "summary-row";
    const summaryClass = totalDiff >= 0 ? "positive" : "negative";
    totalRow.innerHTML = `
      <td>${sym} (Total)</td>
      <td>${totalAmount.toFixed(6)}</td>

      <td>Ø ${formatPrice(avgBuyPrice)}</td>

      <td>${formatPrice(grouped[sym][0].currentPrice || 0)}</td>
      <td>${totalCost.toFixed(2)}</td>
      <td class="${summaryClass}">${totalDiff.toFixed(2)}</td>
      <td class="${summaryClass}">${totalPct.toFixed(2)}%</td>
      <td>-</td>
    `;
    tbody.appendChild(totalRow);
    table.appendChild(tbody);
    section.appendChild(table);
    portfolioList.appendChild(section);
  }
  calculateTotals();
}

function calculateTotals() {
  let grandCost = 0;
  let grandValue = 0;
  portfolioData.forEach(t => {
    grandCost += t.buyPrice * t.amount;
    grandValue += t.currentPrice * t.amount;
  });
  const diff = grandValue - grandCost;
  const pct = grandCost === 0 ? 0 : (diff / grandCost) * 100;
  document.getElementById("totalInvest").textContent = grandCost.toFixed(2) + " USDT";
  document.getElementById("totalProfitLoss").textContent = diff.toFixed(2) + " USDT";
  document.getElementById("totalPercentChange").textContent = pct.toFixed(2) + "%";
}

function drawPieChart() {
  if (!pieChartCanvas) return;
  let grouped = {};
  portfolioData.forEach(t => {
    if (!grouped[t.symbol]) grouped[t.symbol] = 0;
    grouped[t.symbol] += t.currentPrice * t.amount;
  });
  
  let totalAll = 0;
  let coinValues = [];
  for (let s in grouped) {
    totalAll += grouped[s];
  }
  for (let s in grouped) {
    coinValues.push({ symbol: s, value: grouped[s] });
  }
  
  const ctx = pieChartCanvas.getContext("2d");
  ctx.clearRect(0, 0, pieChartCanvas.width, pieChartCanvas.height);
  const centerX = pieChartCanvas.width / 2;
  const centerY = pieChartCanvas.height / 2;
  const radius = Math.min(centerX, centerY) - 10;
  let startAngle = 0;
  
  coinValues.forEach(item => {
    const sliceAngle = totalAll === 0 ? 0 : (item.value / totalAll) * 2 * Math.PI;
    if (!coinColors[item.symbol]) {
      coinColors[item.symbol] = randomColor();
    }
    ctx.fillStyle = coinColors[item.symbol];
    ctx.beginPath();
    ctx.moveTo(centerX, centerY);
    ctx.arc(centerX, centerY, radius, startAngle, startAngle + sliceAngle);
    ctx.closePath();
    ctx.fill();
    startAngle += sliceAngle;
  });
  
  renderChartLegend(coinValues, totalAll);
}

function renderChartLegend(coinValues, totalAll) {
  chartLegend.innerHTML = "";
  coinValues.forEach(item => {
    const percent = totalAll === 0 ? 0 : (item.value / totalAll) * 100;
    const div = document.createElement("div");
    const colorBox = document.createElement("span");
    colorBox.className = "legend-color-box";
    colorBox.style.backgroundColor = coinColors[item.symbol];
    div.appendChild(colorBox);
    div.appendChild(document.createTextNode(item.symbol + " - " + percent.toFixed(2) + "%"));
    chartLegend.appendChild(div);
  });
}


function openNoteModal(id, type) {
  currentNoteId = id;
  currentNoteType = type;
  noteModal.style.display = "block";
  
  if (type === 'portfolio') {
    const tx = portfolioData.find(x => String(x.id) === String(id));
    document.getElementById("noteText").value = tx?.note || "";
  }
}

function closeNoteModal() {
  noteModal.style.display = "none";
}

function saveNote() {
  const noteText = document.getElementById("noteText").value;
  const endpoint = currentNoteType === 'portfolio' 
    ? "/api/portfolio/note" 
    : "/api/trade_summary/note"; 

  fetch(endpoint, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ 
      id: currentNoteId, 
      note: noteText 
    }),
    credentials: "include"
  })
  .then(r => r.json())
  .then(j => {
    if (j.error) {
      alert(j.error);
    } else {
      closeNoteModal();
      updatePrices();
    }
  })
  .catch(() => alert("Network error"));
}


function openAddTransactionModal() {
  addTransactionModal.style.display = "block";
  showBuyForm();
}

function closeAddTransactionModal() {
  addTransactionModal.style.display = "none";
}

function showBuyForm() {
  buyForm.style.display = "block";
  sellForm.style.display = "none";
}

function showSellForm() {
  buyForm.style.display = "none";
  sellForm.style.display = "block";
  populateSellDropdown();
}

function confirmBuy() {
  const symbol = document.getElementById("buySymbol").value.trim().toUpperCase();
  const amount = parseFloat(document.getElementById("buyAmount").value);
  const buyPrice = parseFloat(document.getElementById("buyPrice").value);
  const buyDate = document.getElementById("buyDate").value;
  
  if (!symbol || isNaN(amount) || isNaN(buyPrice)) {
    alert("Please enter valid values");
    return;
  }
  
  const newId = Date.now() + Math.floor(Math.random() * 999999);
  fetch("/api/coinPrice?symbol=" + symbol, { credentials: "include" })
    .then(r => r.json())
    .then(j => {
      if (j.error) {
        alert("This coin is not supported");
      } else {
        fetch("/api/portfolio/buy", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            id: newId,
            symbol,
            amount,
            buyPrice,
            date: buyDate
          }),
          credentials: "include"
        })
        .then(rr => rr.json())
        .then(result => {
          if (result.error) {
            alert(result.error);
          } else {
            updatePrices();
            closeAddTransactionModal();
          }
        });
      }
    })
    .catch(() => alert("Network error"));
}

function confirmSell() {
  const sel = document.getElementById("sellSelectTransaction");
  const val = sel.value;
  if (!val) return;
  
  const sellAmount = parseFloat(document.getElementById("sellAmount").value);
  const sellPrice = parseFloat(document.getElementById("sellPrice").value);
  const sellDate = document.getElementById("sellDate").value;
  
  if (isNaN(sellAmount) || isNaN(sellPrice) || !sellDate) {
    alert("Please enter valid values");
    return;
  }
  
  const parts = val.split("|");
  const sym = parts[0];
  const idx = parseInt(parts[1], 10);
  let selectedTransaction = null;
  let count = 0;
  
  for (let i = 0; i < portfolioData.length; i++) {
    if (portfolioData[i].symbol === sym) {
      if (count === idx) {
        selectedTransaction = portfolioData[i];
        break;
      }
      count++;
    }
  }
  
  if (!selectedTransaction) {
    alert("Invalid");
    return;
  }
  
  fetch("/api/portfolio/sell", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      id: selectedTransaction.id,
      sellAmount: sellAmount,
      sellPrice: sellPrice,
      sellDate: sellDate
    }),
    credentials: "include"
  })
  .then(r => r.json())
  .then(j => {
    if (j.error) {
      alert(j.error);
    } else {
      updatePrices();
      closeAddTransactionModal();
    }
  })
  .catch(() => alert("Error during sell"));
}

function populateSellDropdown() {
  const sel = document.getElementById("sellSelectTransaction");
  sel.innerHTML = "";
  let grouped = {};
  portfolioData.forEach(t => {
    if (!grouped[t.symbol]) grouped[t.symbol] = [];
    grouped[t.symbol].push(t);
  });
  
  for (let sym in grouped) {
    grouped[sym].forEach((tx, i) => {
      const opt = document.createElement("option");
      opt.value = sym + "|" + i;
      opt.text = sym + " - " + tx.amount + "@" + tx.buyPrice + " (" + tx.date + ")";
      sel.appendChild(opt);
    });
  }
}

function openEditTransactionModal(id) {
  editTransactionModal.style.display = "block";
  editIdGlobal = id;
  let t = portfolioData.find(x => String(x.id) === String(id));
  if (!t) {
    alert("No valid transaction found");
    return;
  }
  document.getElementById("editSymbol").value = t.symbol;
  document.getElementById("editAmount").value = t.amount;
  document.getElementById("editBuyPrice").value = t.buyPrice;
  document.getElementById("editDate").value = t.date;
}

function closeEditTransactionModal() {
  editTransactionModal.style.display = "none";
}

function saveEditedTransaction() {
  let t = portfolioData.find(x => String(x.id) === String(editIdGlobal));
  if (!t) {
    alert("No valid transaction found");
    return;
  }
  
  const newAmount = parseFloat(document.getElementById("editAmount").value);
  const newBuyPrice = parseFloat(document.getElementById("editBuyPrice").value);
  const newDate = document.getElementById("editDate").value;
  
  if (isNaN(newAmount) || isNaN(newBuyPrice)) {
    alert("Please enter valid values");
    return;
  }
  
  fetch("/api/portfolio/edit", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      id: t.id,
      symbol: t.symbol,
      newAmount,
      newBuyPrice,
      newDate
    }),
    credentials: "include"
  })
  .then(r => r.json())
  .then(j => {
    if (j.error) {
      alert(j.error);
    } else {
      closeEditTransactionModal();
      updatePrices();
    }
  })
  .catch(() => alert("Error during edit"));
}

function deleteTransaction() {
  openDeleteConfirmationModal();
}

function openDeleteConfirmationModal() {
  document.getElementById("deleteConfirmationModal").style.display = "block";
}

function closeDeleteConfirmationModal() {
  document.getElementById("deleteConfirmationModal").style.display = "none";
}

function confirmDeleteTransaction() {
  let t = portfolioData.find(x => String(x.id) === String(editIdGlobal));
  if (!t) {
    alert("No valid transaction found");
    closeDeleteConfirmationModal();
    return;
  }
  
  fetch("/api/portfolio/delete", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ id: t.id, symbol: t.symbol }),
    credentials: "include"
  })
  .then(r => r.json())
  .then(j => {
    if (j.error) {
      alert(j.error);
    } else {
      closeDeleteConfirmationModal();
      closeEditTransactionModal();
      updatePrices();
    }
  })
  .catch(() => alert("Error deleting transaction"));
}

function openColorConfigModal() {
  colorConfigModal.style.display = "block";
  renderColorConfigList();
}

function closeColorConfigModal() {
  colorConfigModal.style.display = "none";
}

function renderColorConfigList() {
  const container = document.getElementById("colorConfigList");
  container.innerHTML = "";
  let syms = {};
  portfolioData.forEach(t => { syms[t.symbol] = true; });
  
  Object.keys(syms).forEach(s => {
    const div = document.createElement("div");
    div.style.marginBottom = "0.5rem";
    const label = document.createElement("label");
    label.textContent = s + ": ";
    div.appendChild(label);
    
    const input = document.createElement("input");
    input.type = "color";
    if (!coinColors[s]) {
      coinColors[s] = randomColor();
    }
    input.value = rgbToHex(coinColors[s]);
    input.addEventListener("input", () => {
      coinColors[s] = input.value;
    });
    div.appendChild(input);
    container.appendChild(div);
  });
}

function saveColorConfig() {
  closeColorConfigModal();
  saveCoinColorsToStorage();
  drawPieChart();
}

function randomColor() {
  const r = Math.floor(Math.random() * 200 + 55);
  const g = Math.floor(Math.random() * 200 + 55);
  const b = Math.floor(Math.random() * 200 + 55);
  return `rgb(${r},${g},${b})`;
}

function rgbToHex(str) {
  if (str.indexOf("#") === 0) return str;
  const p = str.replace(/[^\d,]/g, "").split(",");
  const r = parseInt(p[0], 10);
  const g = parseInt(p[1], 10);
  const b = parseInt(p[2], 10);
  return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}

function loadCoinColorsFromStorage() {
  const s = localStorage.getItem("coinColors");
  if (s) coinColors = JSON.parse(s);
}

function saveCoinColorsToStorage() {
  localStorage.setItem("coinColors", JSON.stringify(coinColors));
}

