<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Trading Journal - Multi Account</title>
<style>
  /* Your original styles unchanged */
  body {
    font-family: Arial, sans-serif;
    margin: 20px;
    background: #f4f6f8;
  }
  /* Header Wrapper */
  #headerWrapper {
    max-width: 1500px;
    margin: 0 auto 25px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 25px;
    flex-wrap: wrap;
  }
  #headerWrapper h1 {
    margin: 0;
  }
  #headerWrapper label {
    font-weight: bold;
    font-size: 10px;
    margin-right: 8px;
  }
  #headerWrapper input[type="number"] {
    width: 120px;
    padding: 5px 8px;
    font-size: 14px;
  }
  #actualBalanceWrapper {
    font-weight: bold;
    font-size: 16px;
    background-color: #007bff;
    color: white;
    padding: 6px 12px;
    border-radius: 4px;
  }
  input[disabled] {
    background-color: #e9ecef;
  }
  form {
    background: white;
    padding: 20px 30px;
    border-radius: 8px;
    margin-bottom: 30px;
    box-shadow: 0 0 10px rgba(0,0,0,0.1);
    max-width: 1500px;
    margin-left: auto;
    margin-right: auto;
  }
  form .grid-container {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 18px 40px;
    align-items: center;
  }
  form .grid-container div {
    display: flex;
    align-items: center;
  }
  label {
    width: 140px;
    font-weight: bold;
    margin-right: 12px;
    white-space: nowrap;
  }
  input[type="text"],
  input[type="number"],
  input[type="time"],
  input[type="date"],
  select,
  textarea {
    flex: 1;
    padding: 6px 8px;
    font-size: 14px;
    border: 1px solid #ccc;
    border-radius: 4px;
    min-width: 0;
  }
  textarea {
    resize: vertical;
  }
  /* Full width fields: e.g. textareas or wide inputs below */
  .full-width {
    grid-column: 1 / -1;
    margin-top: 10px;
  }
  /* Buttons */
  button {
    background-color: #007bff;
    color: white;
    border:none;
    padding: 10px 16px;
    cursor: pointer;
    border-radius: 4px;
    font-size: 12px;
  }
  button:disabled {
    background-color: #aaa;
    cursor: not-allowed;
  }
  button:hover:not(:disabled) {
    background-color: #0056b3;
  }
  #buttonsWrapper {
    margin-top: 20px;
    display: flex;
    justify-content: space-between;
    max-width: 1500px;
    margin-left: auto;
    margin-right: auto;
    gap: 10px;
    flex-wrap: wrap;
  }
  /* Table styling */
  table {
    width: 100%;
    border-collapse: collapse;
    background: white;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 0 10px rgba(0,0,0,0.1);
    max-width: 1500px;
    margin-left: auto;
    margin-right: auto;
    display: block;
    overflow-x: auto;
    white-space: nowrap;
  }
  th, td {
    text-align: center;
    padding: 8px;
    border-bottom: 1px solid #ddd;
    font-size: 12px;
    vertical-align: middle;
    overflow-wrap: break-word;
    white-space: normal;
  }
  /* Wider columns get min-width and left align for readability */
  th:nth-child(18), td:nth-child(18),
  th:nth-child(20), td:nth-child(20),
  th:nth-child(23), td:nth-child(23),
  th:nth-child(24), td:nth-child(24) {
    min-width: 150px;
    text-align: left;
  }
  th {
    background-color: #007bff;
    color: white;
    position: sticky;
    top: 0;
    z-index: 2;
  }
  tr:hover {
    background-color: #f1f1f1;
  }
  .actions button {
    background-color: #dc3545;
    margin: 0 2px;
    padding: 5px 8px;
    font-size: 10px;
  }
  .actions button.edit {
    background-color: #28a745;
  }
  #clearAllBtn {
    background-color: #6c757d;
  }
  /* Responsive for smaller screens: stack form fields */
  @media (max-width: 700px) {
    form .grid-container {
      grid-template-columns: 1fr;
    }
    label {
      width: 110px;
    }
    #buttonsWrapper {
      flex-direction: column;
      gap: 10px;
    }
    #buttonsWrapper button {
      width: 100%;
    }
    #headerWrapper {
      justify-content: center;
    }
  }

  /* Filter & sort controls styling with some added flex wrap */
  #filterSortWrapper {
    max-width: 1100px;
    margin: 15px auto;
    display: flex;
    flex-wrap: wrap;
    gap: 15px;
    align-items: center;
  }
  #filterSortWrapper label {
    font-weight: bold;
    margin-right: 6px;
    white-space: nowrap;
  }
  #filterSortWrapper input,
  #filterSortWrapper select {
    padding: 4px 6px;
    font-size: 12px;
    min-width: 110px;
  }
  #filterSortWrapper > div {
    display: flex;
    align-items: center;
  }

  /* Account selector wrapper */
  #accountSelectorWrapper {
    max-width: 1500px;
    margin: 0 auto 15px;
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
  }
  #accountSelectorWrapper label {
    font-weight: bold;
  }
</style>
</head>
<body>

<!-- Account Selector -->
<div id="accountSelectorWrapper" aria-label="Select trading account">
  <label for="accountSelect">Select Account:</label>
  <select id="accountSelect" aria-describedby="accountsDesc"></select>
  <button id="addAccountBtn" type="button" aria-label="Add New Account">Add New Account</button>
  <div id="accountsDesc" style="font-size: 12px; color: #555;">Manage multiple trading accounts</div>
</div>

<!-- Header with Balance and Actual Balance display -->
<div id="headerWrapper" aria-label="Account balances">
  <h1>Trading Journal</h1>
  <div>
    <label for="initialBalance">Balance:</label>
    <input type="number" id="initialBalance" min="0" step="0.01" aria-describedby="balanceDesc" />
    <div id="balanceDesc" style="font-weight:normal; font-size:12px; color: #555;">Initial account balance</div>
  </div>
  <div id="actualBalanceWrapper" aria-live="polite" title="Initial Balance plus all profits">Actual Balance: $<span id="actualBalance">0.00</span></div>
</div>

<form id="tradeForm" autocomplete="off" aria-label="Add or edit trade">
  <input type="hidden" id="tradeIndex" />

  <div class="grid-container">
    <!-- Your form fields unchanged -->
    <div>
      <label for="trade">Trade #<sup style="color:red">*</sup></label>
      <input type="number" id="trade" min="1" placeholder="e.g. 1" required aria-required="true" />
    </div>
    <div>
      <label for="emaBias">M15 EMA's Bias</label>
      <select id="emaBias" aria-label="M15 EMA's Bias">
        <option value="">Select</option>
        <option>Bullish</option>
        <option>Bearish</option>
        <option>Neutral</option>
      </select>
    </div>

    <div>
      <label for="day">Day (Date)<sup style="color:red">*</sup></label>
      <input type="date" id="day" required aria-required="true" />
    </div>
    <div>
      <label for="time">Time<sup style="color:red">*</sup></label>
      <input type="time" id="time" required aria-required="true" />
    </div>

    <div>
      <label for="symbol">Symbol<sup style="color:red">*</sup></label>
      <input list="symbolList" type="text" id="symbol" placeholder="e.g. EURUSD" required aria-required="true" autocomplete="off" />
      <datalist id="symbolList">
        <!-- Common Forex Pairs -->
        <option value="EURUSD"></option>
        <option value="USDJPY"></option>
        <option value="GBPUSD"></option>
        <option value="AUDUSD"></option>
        <option value="USDCAD"></option>
        <option value="USDCHF"></option>
        <option value="NZDUSD"></option>
        <option value="EURJPY"></option>
        <option value="EURGBP"></option>
        <!-- Indices -->
        <option value="USTEC.p"></option>
        <option value="DE30.p"></option>
        <option value="SPX500.p"></option>
        <option value="UK100.p"></option>
        <option value="BTC"></option>
        <option value="JPN225.p"></option>
      </datalist>
    </div>
    <div>
      <label for="session">Session</label>
      <select id="session" aria-label="Session">
        <option value="">Select</option>
        <option>Asia</option>
        <option>London</option>
        <option>New York</option>
        <option>No Session</option>
      </select>
    </div>

    <div>
      <label for="risk">Risk %</label>
      <input type="number" id="risk" min="0" step="0.01" placeholder="e.g. 1.5" />
    </div>
    <div>
      <label for="rrr">RRR (Risk Reward)</label>
      <input type="number" id="rrr" min="0" step="0.01" placeholder="e.g. 2" />
    </div>

    <div>
      <label for="positionSize">Position Size<sup style="color:red">*</sup></label>
      <input type="number" id="positionSize" min="0" step="0.01" placeholder="e.g. 0.5" required aria-required="true" />
    </div>
    <div>
      <label for="mode">Mode<sup style="color:red">*</sup></label>
      <select id="mode" required aria-required="true">
        <option value="">Select</option>
        <option>Buy</option>
        <option>Sell</option>
      </select>
    </div>

    <div>
      <label for="entry">Entry Price<sup style="color:red">*</sup></label>
      <input type="number" id="entry" min="0" step="any" placeholder="e.g. 1.12345" required aria-required="true" />
    </div>
    <div>
      <label for="sl">Stop Loss (SL)</label>
      <input type="number" id="sl" min="0" step="any" placeholder="e.g. 1.1200" />
    </div>

    <div>
      <label for="tp">Take Profit (TP)</label>
      <input type="number" id="tp" min="0" step="any" placeholder="e.g. 1.1300" />
    </div>
    <div>
      <label for="exitType">Exit Type<sup style="color:red">*</sup></label>
      <select id="exitType" required aria-required="true">
        <option value="">Select</option>
        <option value="SL">Stop Loss (SL)</option>
        <option value="TP">Take Profit (TP)</option>
        <option value="Manual">Manual</option>
      </select>
    </div>

    <div>
      <label for="close">Close Price</label>
      <input type="number" id="close" min="0" step="any" placeholder="Only if manual exit" disabled />
    </div>

    <div>
      <label for="entryConfirm">Entry Confirm</label>
      <input type="text" id="entryConfirm" placeholder="e.g. M1 CISD+FVG, M1 MSS, M5 CISD" />
    </div>

    <div class="full-width">
      <label for="whyOpen" style="vertical-align: top;">Why Open</label>
      <textarea id="whyOpen" rows="2" placeholder="Explain why you opened this trade"></textarea>
    </div>

    <div class="full-width">
      <label for="feelings" style="vertical-align: top;">Feelings</label>
      <textarea id="feelings" rows="2" placeholder="What were your emotions"></textarea>
    </div>

    <div>
      <label for="closeRrr">Close RRR</label>
      <input type="number" id="closeRrr" step="0.01" placeholder="Exit RRR" />
    </div>
    <div>
      <label for="closeTime">Close Time</label>
      <input type="time" id="closeTime" />
    </div>

    <div class="full-width">
      <label for="whyCloseManual" style="vertical-align: top;">Why Close if Exit Manual</label>
      <textarea id="whyCloseManual" rows="2" placeholder="Reason for manual exit"></textarea>
    </div>

    <div>
      <label for="profit">Profit<sup style="color:red">*</sup></label>
      <input type="number" id="profit" step="0.01" placeholder="Enter profit" required aria-required="true" aria-describedby="profitDesc" />
      <div id="profitDesc" style="font-weight:normal; font-size:12px; color: #555;">Enter the profit manually</div>
    </div>
    <div>
      <label for="accountReward">Account Reward (%)</label>
      <input type="number" id="accountReward" step="0.0001" placeholder="Calculated automatically" disabled />
    </div>

    <div class="full-width">
      <label for="resultAfterClose" style="vertical-align: top;">
        Result After Close if Exit Manual <br />
        <small style="font-weight: normal; color: #555;">
          (Optional - leave empty if unsure of exit result)
        </small>
      </label>
      <select id="resultAfterClose" aria-label="Result After Close if Exit Manual">
        <option value="">Select</option>
        <option value="TP">Take Profit (TP)</option>
        <option value="SL">Stop Loss (SL)</option>
      </select>
    </div>
  </div>

  <div id="buttonsWrapper">
    <button type="submit" id="submitBtn">Add Trade</button>
    <button type="button" id="clearAllBtn" title="Clear All Trades">Clear All</button>
    <button type="button" id="exportBtn" title="Export all trades as CSV">Export Trades</button>
    <button type="button" id="statsBtn" title="Go to statistics page">Stats</button>
  </div>
</form>

<!-- Filter and Sort controls with SINGLE FILTER COLUMN + input -->
<div id="filterSortWrapper" aria-label="Filter and sort trades">
  <div>
    <label for="filterColumn">Filter Column:</label>
    <select id="filterColumn" aria-label="Select column to filter">
      <option value="trade">Trade #</option>
      <option value="day">Day</option>
      <option value="time">Time</option>
      <option value="symbol">Symbol</option>
      <option value="session">Session</option>
      <option value="emaBias">M15 EMA's Bias</option>
      <option value="risk">Risk %</option>
      <option value="rrr">RRR</option>
      <option value="positionSize">Position Size</option>
      <option value="mode">Mode</option>
      <option value="entry">Entry</option>
      <option value="sl">SL</option>
      <option value="tp">TP</option>
      <option value="exitType">Exit Type</option>
      <option value="close">Close</option>
      <option value="entryConfirm">Entry Confirm</option>
      <option value="closeRrr">Close RRR</option>
      <option value="closeTime">Close Time</option>
      <option value="whyOpen">Why Open</option>
      <option value="feelings">Feelings</option>
      <option value="whyCloseManual">Why Close If Manual</option>
      <option value="profit">Profit</option>
      <option value="accountReward">Account Reward (%)</option>
      <option value="resultAfterClose">Result After Close</option>
    </select>
  </div>
  <div>
    <label for="filterValue">Filter Value:</label>
    <input type="text" id="filterValue" placeholder="Enter filter text" autocomplete="off" />
  </div>
  <div>
    <label for="sortColumn">Sort by:</label>
    <select id="sortColumn">
      <option value="trade">Trade #</option>
      <option value="day">Day</option>
      <option value="time">Time</option>
      <option value="symbol">Symbol</option>
      <option value="session">Session</option>
      <option value="emaBias">M15 EMA's Bias</option>
      <option value="risk">Risk %</option>
      <option value="rrr">RRR</option>
      <option value="positionSize">Position Size</option>
      <option value="mode">Mode</option>
      <option value="entry">Entry</option>
      <option value="sl">SL</option>
      <option value="tp">TP</option>
      <option value="exitType">Exit Type</option>
      <option value="close">Close</option>
      <option value="entryConfirm">Entry Confirm</option>
      <option value="closeRrr">Close RRR</option>
      <option value="closeTime">Close Time</option>
      <option value="whyOpen">Why Open</option>
      <option value="feelings">Feelings</option>
      <option value="whyCloseManual">Why Close If Manual</option>
      <option value="profit">Profit</option>
      <option value="accountReward">Account Reward (%)</option>
      <option value="resultAfterClose">Result After Close</option>
    </select>
  </div>
  <div>
    <label for="sortDirection">Direction:</label>
    <select id="sortDirection">
      <option value="desc">Descending</option>
      <option value="asc">Ascending</option>
    </select>
  </div>
  <button id="clearFiltersBtn" type="button" style="padding:0 10px; font-size: 12px;">Clear Filters</button>
</div>

<table id="tradesTable" aria-label="Trading journal records">
  <thead>
    <tr>
      <th scope="col">Trade #</th>
      <th scope="col">Day</th>
      <th scope="col">Time</th>
      <th scope="col">Symbol</th>
      <th scope="col">Session</th>
      <th scope="col">M15 EMA's Bias</th>
      <th scope="col">Risk %</th>
      <th scope="col">RRR</th>
      <th scope="col">Position Size</th>
      <th scope="col">Mode</th>
      <th scope="col">Entry</th>
      <th scope="col">SL</th>
      <th scope="col">TP</th>
      <th scope="col">Exit Type</th>
      <th scope="col">Close</th>
      <th scope="col">Entry Confirm</th>
      <th scope="col">Close RRR</th>
      <th scope="col">Close Time</th>
      <th scope="col">Why Open</th>
      <th scope="col">Feelings</th>
      <th scope="col">Why Close If Manual</th>
      <th scope="col">Profit</th>
      <th scope="col">Account Reward (%)</th>
      <th scope="col">Result After Close</th>
      <th scope="col">Actions</th>
    </tr>
  </thead>
  <tbody>
    <!-- Trades inserted by JS -->
  </tbody>
</table>

<script>
  const tradeForm = document.getElementById('tradeForm');
  const tradesTableBody = document.querySelector('#tradesTable tbody');
  const clearAllBtn = document.getElementById('clearAllBtn');
  const submitBtn = document.getElementById('submitBtn');
  const exportBtn = document.getElementById('exportBtn');
  const statsBtn = document.getElementById('statsBtn');

  const exitTypeEl = document.getElementById('exitType');
  const closePriceEl = document.getElementById('close');
  const sessionEl = document.getElementById('session');
  const timeEl = document.getElementById('time');

  const initialBalanceInput = document.getElementById('initialBalance');
  const actualBalanceSpan = document.getElementById('actualBalance');

  // Filter & Sort Controls
  const filterColumnSelect = document.getElementById('filterColumn');
  const filterValueInput = document.getElementById('filterValue');
  const sortColumnSelect = document.getElementById('sortColumn');
  const sortDirectionSelect = document.getElementById('sortDirection');
  const clearFiltersBtn = document.getElementById('clearFiltersBtn');

  // ACCOUNT SELECTOR elements
  const accountSelect = document.getElementById('accountSelect');
  const addAccountBtn = document.getElementById('addAccountBtn');

  // Store full data: accounts object and currentAccountId
  let data = {
    accounts: {},
    currentAccountId: null
  };

  // The currently active trades array for selected account
  let trades = [];

  // Current filters and sorting settings
  let currentFilters = {
    column: 'trade',
    value: ''
  };

  let currentSort = {
    column: 'trade',
    direction: 'desc'
  };

  // Helper: get next trade number (max + 1) for current account
  function getNextTradeNumber() {
    if (!trades || trades.length === 0) return 1;
    return trades.reduce((max, t) => Math.max(max, t.trade || 0), 0) + 1;
  }

  // Parse time string in 24h or 12h format (with AM/PM) -> minutes since midnight
  function parseTimeToMinutes(timeStr) {
    if (!timeStr) return null;

    timeStr = timeStr.trim().toUpperCase();

    const is12h = timeStr.includes('AM') || timeStr.includes('PM');

    if (is12h) {
      const match = timeStr.match(/^(\d{1,2}):(\d{2})\s?(AM|PM)$/);
      if (!match) return null;

      let hour = Number(match[1]);
      const minute = Number(match[2]);
      const ampm = match[3];

      if (hour < 1 || hour > 12 || minute < 0 || minute > 59) return null;

      if (ampm === 'PM' && hour !== 12) hour += 12;
      if (ampm === 'AM' && hour === 12) hour = 0;

      return hour * 60 + minute;
    } else {
      const match = timeStr.match(/^(\d{1,2}):(\d{2})$/);
      if (!match) return null;

      const hour = Number(match[1]);
      const minute = Number(match[2]);

      if (hour < 0 || hour > 23 || minute < 0 || minute > 59) return null;

      return hour * 60 + minute;
    }
  }

  // Auto-set session based on time (24h or 12h with AM/PM)
  function autoSelectSession(timeValue) {
    const minutesTotal = parseTimeToMinutes(timeValue);
    if (minutesTotal === null) {
      sessionEl.value = "";
      return;
    }

    const sessions = [
      {name: "Asia", start: 60, end: 420},       // 01:00 - 07:00
      {name: "London", start: 600, end: 720},   // 10:00 - 12:00
      {name: "New York", start: 900, end: 1080} // 15:00 - 18:00
    ];

    for (const session of sessions) {
      if (minutesTotal >= session.start && minutesTotal < session.end) {
        sessionEl.value = session.name;
        return;
      }
    }

    sessionEl.value = "No Session";
  }

  // Attach auto-select session on time input change
  timeEl.addEventListener('input', e => {
    autoSelectSession(e.target.value);
  });

  // Enable or disable Close Price input based on Exit Type and handle Result After Close
  exitTypeEl.addEventListener('change', () => {
    if(exitTypeEl.value === 'Manual') {
      closePriceEl.disabled = false;
      closePriceEl.required = true;

      const resultAfterCloseEl = document.getElementById('resultAfterClose');
      resultAfterCloseEl.disabled = false;
      resultAfterCloseEl.required = false;
    } else {
      closePriceEl.disabled = true;
      closePriceEl.value = '';
      closePriceEl.required = false;

      const resultAfterCloseEl = document.getElementById('resultAfterClose');
      resultAfterCloseEl.disabled = true;
      resultAfterCloseEl.value = '';
      resultAfterCloseEl.required = false;

      document.getElementById('closeRrr').value = '';
    }
    calculateCloseRRR();
  });

  window.addEventListener('DOMContentLoaded', () => {
    if(exitTypeEl.value === 'Manual') {
      closePriceEl.disabled = false;
      closePriceEl.required = true;
    } else {
      closePriceEl.disabled = true;
      closePriceEl.required = false;
    }
  });

  // When initial balance input changes - update current account and save to server (debounced)
  let debounceTimeout;
  initialBalanceInput.addEventListener('input', () => {
    clearTimeout(debounceTimeout);
    debounceTimeout = setTimeout(async () => {
      let val = Number(initialBalanceInput.value);
      if (isNaN(val) || val < 0) val = 5000;

      if (data.currentAccountId && data.accounts[data.currentAccountId]) {
        data.accounts[data.currentAccountId].initialBalance = val;
      }

      try {
        const res = await fetch('/save.php', {
          method: 'POST',
          headers: {'Content-Type': 'application/json'},
          body: JSON.stringify(data)
        });
        if (!res.ok) throw new Error("Network error saving initial balance.");
        const json = await res.json();
        if(json.status !== 'saved') throw new Error("Server error saving initial balance.");

        updateAccountRewardForAllTrades();
        updateActualBalanceDisplay();
        renderTrades();
        updateRiskReward();
      } catch(e) {
        alert("Error saving initial balance: " + e.message);
      }
    }, 500);
  });

  // Calculate account reward % from initial balance for profit
  function calculateAccountReward(profit) {
    if (profit === null || profit === undefined || isNaN(profit)) return '';
    if (!data.currentAccountId || !data.accounts[data.currentAccountId]) return '';
    const initialBalance = data.accounts[data.currentAccountId].initialBalance;
    if(!initialBalance || initialBalance === 0) return '';
    return ((profit / initialBalance) * 100).toFixed(4);
  }

  // Update actual balance display (initial + sum of profits)
  function updateActualBalanceDisplay() {
    if (!data.currentAccountId || !data.accounts[data.currentAccountId]) {
      actualBalanceSpan.textContent = '0.00';
      return;
    }
    const accountData = data.accounts[data.currentAccountId];
    const totalProfit = accountData.trades.reduce((acc, trade) => acc + (trade.profit || 0), 0);
    const actual = accountData.initialBalance + totalProfit;
    actualBalanceSpan.textContent = actual.toFixed(2);
  }

  // Update account reward field for all trades in current account
  function updateAccountRewardForAllTrades() {
    if (!data.currentAccountId || !data.accounts[data.currentAccountId]) return;
    const tradesArray = data.accounts[data.currentAccountId].trades;
    tradesArray.forEach(trade => {
      trade.accountReward = calculateAccountReward(trade.profit);
    });
  }

  // Render trade table rows with filtering & sorting applied
  function renderTrades() {
    tradesTableBody.innerHTML = '';

    let filteredTrades = trades;

    if (currentFilters.value.trim() !== '') {
      const search = currentFilters.value.trim().toLowerCase();
      const filterCol = currentFilters.column;

      filteredTrades = filteredTrades.filter(trade => {
        let fieldVal = trade[filterCol];

        if (fieldVal === null || fieldVal === undefined) return false;

        if (typeof fieldVal !== 'string') fieldVal = fieldVal.toString();

        return fieldVal.toLowerCase().includes(search);
      });
    }

    // Apply sorting
    filteredTrades.sort((a, b) => {
      const col = currentSort.column;
      let valA = a[col];
      let valB = b[col];

      // handle null or undefined
      if(valA === undefined || valA === null) valA = '';
      if(valB === undefined || valB === null) valB = '';

      // For 'day' (date), parse to Date for comparison
      if(col === 'day') {
        valA = new Date(valA);
        valB = new Date(valB);
      }

      // For 'trade' and 'profit' - numeric sort (add other numeric columns as well)
      if(['trade', 'profit', 'risk', 'rrr', 'positionSize', 'closeRrr', 'accountReward'].includes(col)) {
        valA = Number(valA);
        valB = Number(valB);
        if(isNaN(valA)) valA = -Infinity;
        if(isNaN(valB)) valB = -Infinity;
      }

      if(valA < valB) return currentSort.direction === 'asc' ? -1 : 1;
      if(valA > valB) return currentSort.direction === 'asc' ? 1 : -1;
      return 0;
    });

    if(filteredTrades.length === 0) {
      const tr = document.createElement('tr');
      const td = document.createElement('td');
      td.colSpan = 25; 
      td.style.textAlign = 'center';
      td.textContent = 'No trades match current filters.';
      tr.appendChild(td);
      tradesTableBody.appendChild(tr);
      updateActualBalanceDisplay();
      return;
    }

    filteredTrades.forEach((trade, index) => {
      const tr = document.createElement('tr');

      const fields = [
        trade.trade,
        trade.day,
        trade.time,
        trade.symbol,
        trade.session,
        trade.emaBias,
        trade.risk,
        trade.rrr,
        trade.positionSize,
        trade.mode,
        trade.entry,
        trade.sl,
        trade.tp,
        trade.exitType,
        trade.close,
        trade.entryConfirm,
        trade.closeRrr,
        trade.closeTime,
        trade.whyOpen,
        trade.feelings,
        trade.whyCloseManual,
        trade.profit,
        trade.accountReward,
        trade.resultAfterClose,
      ];

      fields.forEach(field => {
        const td = document.createElement('td');
        td.textContent = (field === undefined || field === null) ? '' : field;
        td.title = td.textContent;
        tr.appendChild(td);
      });

      // Profit column color coding
      const profitTd = tr.children[21];
      if(profitTd && profitTd.textContent !== '') {
        const val = Number(profitTd.textContent);
        profitTd.style.color = val >= 0 ? 'green' : 'red';
      }

      const actionsTd = document.createElement('td');
      actionsTd.className = 'actions';

      const editBtn = document.createElement('button');
      editBtn.textContent = 'Edit';
      editBtn.className = 'edit';
      editBtn.type = 'button';
      editBtn.title = "Edit trade";

      // Need to find original index of this trade in full trades array for editing
      const originalIndex = trades.indexOf(trade);
      editBtn.addEventListener('click', () => {
        populateFormForEdit(originalIndex);
        window.scrollTo(0, 0);
      });

      const delBtn = document.createElement('button');
      delBtn.textContent = 'Delete';
      delBtn.type = 'button';
      delBtn.title = "Delete trade";
      delBtn.addEventListener('click', async () => {
        if(confirm(`Are you sure you want to delete trade #${trade.trade}?`)) {
          trades.splice(originalIndex, 1);
          data.accounts[data.currentAccountId].trades = trades;
          try {
            const res = await fetch('/save.php', {
              method: 'POST',
              headers: {'Content-Type': 'application/json'},
              body: JSON.stringify(data)
            });
            if(!res.ok) throw new Error('Network error');
            const json = await res.json();
            if(json.status === 'saved') {
              alert('Trade deleted.');
              updateAccountRewardForAllTrades();
              updateActualBalanceDisplay();
              renderTrades();
            } else {
              alert('Failed to save trades on server after deletion.');
            }
          } catch(e) {
            alert('Error deleting trade: ' + e.message);
          }
        }
      });

      actionsTd.appendChild(editBtn);
      actionsTd.appendChild(delBtn);
      tr.appendChild(actionsTd);

      tradesTableBody.appendChild(tr);
    });

    updateActualBalanceDisplay();
  }

  // Fill form for editing a trade
  function populateFormForEdit(index) {
    const trade = trades[index];
    document.getElementById('tradeIndex').value = index;

    document.getElementById('trade').value = trade.trade || '';
    document.getElementById('day').value = trade.day || '';
    document.getElementById('time').value = trade.time || '';
    document.getElementById('symbol').value = trade.symbol || '';
    document.getElementById('session').value = trade.session || '';
    document.getElementById('emaBias').value = trade.emaBias || '';
    document.getElementById('risk').value = trade.risk || '';
    document.getElementById('rrr').value = trade.rrr || '';
    document.getElementById('positionSize').value = trade.positionSize || '';
    document.getElementById('mode').value = trade.mode || '';
    document.getElementById('entry').value = trade.entry || '';
    document.getElementById('sl').value = trade.sl || '';
    document.getElementById('tp').value = trade.tp || '';
    document.getElementById('exitType').value = trade.exitType || '';
    document.getElementById('close').value = trade.close || '';
    document.getElementById('entryConfirm').value = trade.entryConfirm || '';
    document.getElementById('closeRrr').value = trade.closeRrr || '';
    document.getElementById('closeTime').value = trade.closeTime || '';
    document.getElementById('whyOpen').value = trade.whyOpen || '';
    document.getElementById('feelings').value = trade.feelings || '';
    document.getElementById('whyCloseManual').value = trade.whyCloseManual || '';
    document.getElementById('profit').value = trade.profit || '';
    document.getElementById('accountReward').value = trade.accountReward || '';
    document.getElementById('resultAfterClose').value = trade.resultAfterClose || '';

    closePriceEl.disabled = trade.exitType === 'Manual' ? false : true;
    closePriceEl.required = trade.exitType === 'Manual';

    const resultAfterCloseEl = document.getElementById('resultAfterClose');
    if(trade.exitType === 'Manual') {
      resultAfterCloseEl.disabled = false;
      resultAfterCloseEl.required = false;
    } else {
      resultAfterCloseEl.disabled = true;
      resultAfterCloseEl.required = false;
    }

    submitBtn.textContent = 'Update Trade';

    tradeForm.dataset.editing = "true";

    // Compute Close RRR especially for manual exit on load
    calculateCloseRRR();

    // Update risk reward when populating edit form
    updateRiskReward();
  }

  // Form submit handler for add/update
  tradeForm.addEventListener('submit', async e => {
    e.preventDefault();

    function getNumberValue(id) {
      const v = document.getElementById(id).value;
      return v === '' ? null : Number(v);
    }

    // Validate required fields
    const requiredFields = [
      {id: 'trade', name: 'Trade #'},
      {id: 'day', name: 'Day (Date)'},
      {id: 'time', name: 'Time'},
      {id: 'symbol', name: 'Symbol'},
      {id: 'positionSize', name: 'Position Size'},
      {id: 'mode', name: 'Mode'},
      {id: 'entry', name: 'Entry Price'},
      {id: 'exitType', name: 'Exit Type'},
      {id: 'profit', name: 'Profit'},
    ];

    for (const field of requiredFields) {
      const val = document.getElementById(field.id).value;
      if (!val || val.trim() === '') {
        alert(`Please fill out required field: ${field.name}`);
        return;
      }
    }

    if(exitTypeEl.value === 'Manual' && (!closePriceEl.value || closePriceEl.value.trim() === '')) {
      alert("Close Price is required for Manual exit type.");
      return;
    }

    const resultAfterClose = document.getElementById('resultAfterClose').value;

    if(exitTypeEl.value === 'Manual' && !resultAfterClose) {
      if(!confirm("You left 'Result After Close' empty, which means you're unsure of the exit result.\n\nAre you sure you want to save the trade without this information?")) {
        return;
      }
    }

    const numberFields = ['risk','rrr','positionSize','entry','sl','tp','close','closeRrr','profit'];
    for (const nf of numberFields) {
      const val = document.getElementById(nf).value;
      if(val) {
        const num = Number(val);
        if(isNaN(num)) {
          alert(`Field ${nf} must be a valid number.`);
          return;
        }
      }
    }

    let tradeData = {
      trade: getNumberValue('trade'),
      day: document.getElementById('day').value || '',
      time: document.getElementById('time').value || '',
      symbol: document.getElementById('symbol').value.trim() || '',
      session: document.getElementById('session').value,
      emaBias: document.getElementById('emaBias').value,
      risk: getNumberValue('risk'),
      rrr: getNumberValue('rrr'),
      positionSize: getNumberValue('positionSize'),
      mode: document.getElementById('mode').value,
      entry: getNumberValue('entry'),
      sl: getNumberValue('sl'),
      tp: getNumberValue('tp'),
      exitType: document.getElementById('exitType').value,
      close: getNumberValue('close'),
      entryConfirm: document.getElementById('entryConfirm').value.trim() || '',
      closeRrr: getNumberValue('closeRrr'),
      closeTime: document.getElementById('closeTime').value || '',
      whyOpen: document.getElementById('whyOpen').value.trim() || '',
      feelings: document.getElementById('feelings').value.trim() || '',
      whyCloseManual: document.getElementById('whyCloseManual').value.trim() || '',
      profit: getNumberValue('profit'),
      accountReward: '',
      resultAfterClose: resultAfterClose,
    };

    if (tradeData.profit === null || isNaN(tradeData.profit)) {
      alert("Please enter a valid profit value.");
      return;
    }

    tradeData.accountReward = calculateAccountReward(tradeData.profit);

    const index = document.getElementById('tradeIndex').value;
    if(index === '') {
      trades.push(tradeData);
    } else {
      trades[index] = tradeData;
    }

    trades.sort((a, b) => (a.trade || 0) - (b.trade || 0));

    data.accounts[data.currentAccountId].trades = trades;

    try {
      const response = await fetch('/save.php', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify(data)
      });
      if (!response.ok) throw new Error('Network response was not ok');
      const result = await response.json();

      if(result.status === 'saved') {
        alert('Trade saved successfully.');
        tradeForm.reset();
        document.getElementById('tradeIndex').value = '';
        tradeForm.dataset.editing = "false";

        document.getElementById('trade').value = getNextTradeNumber();

        submitBtn.textContent = 'Add Trade';
        updateAccountRewardForAllTrades();
        updateActualBalanceDisplay();
        renderTrades();
      } else {
        alert('Failed to save trades on server.');
      }
    } catch (err) {
      alert('Error saving trades: ' + err.message);
    }
  });

  clearAllBtn.addEventListener('click', async () => {
    if(confirm('Are you sure you want to delete all trades? This action cannot be undone.')) {
      trades = [];
      data.accounts[data.currentAccountId].trades = trades;
      try {
        const response = await fetch('/save.php', {
          method: 'POST',
          headers: {'Content-Type': 'application/json'},
          body: JSON.stringify(data)
        });
        if(!response.ok) throw new Error("Network error");
        const result = await response.json();
        if(result.status === 'saved') {
          alert('All trades cleared.');
          updateAccountRewardForAllTrades();
          updateActualBalanceDisplay();
          renderTrades();

          // Reset Trade# input to 1 after clearing all
          document.getElementById('trade').value = 1;
          tradeForm.dataset.editing = "false";
        } else {
          alert('Failed to clear trades on server.');
        }
      } catch(e) {
        alert('Error clearing trades: ' + e.message);
      }
    }
  });

  // Helper to escape CSV values properly
  function csvEscape(value) {
    if (value === null || value === undefined) return '';
    const str = String(value);
    if(str.includes('"') || str.includes(',') || str.includes('\n') || str.includes('\r')) {
      return `"${str.replace(/"/g, '""')}"`;
    }
    return str;
  }

  // Helper to get filtered and sorted trades (export matching current table state)
  function getFilteredSortedTrades() {
    let filteredTrades = trades;

    const isFilterActive = currentFilters.value.trim() !== '';
    const isDefaultSort = currentSort.column === 'trade' && currentSort.direction === 'desc';

    if (isFilterActive) {
      const search = currentFilters.value.trim().toLowerCase();
      const filterCol = currentFilters.column;

      filteredTrades = filteredTrades.filter(trade => {
        let fieldVal = trade[filterCol];
        if (fieldVal === null || fieldVal === undefined) return false;
        if (typeof fieldVal !== 'string') fieldVal = fieldVal.toString();
        return fieldVal.toLowerCase().includes(search);
      });
    }

    filteredTrades = filteredTrades.slice(); // to avoid mutating original

    if (!isDefaultSort) {
      filteredTrades.sort((a, b) => {
        const col = currentSort.column;
        let valA = a[col];
        let valB = b[col];

        if (valA === undefined || valA === null) valA = '';
        if (valB === undefined || valB === null) valB = '';

        if (col === 'day') {
          valA = new Date(valA);
          valB = new Date(valB);
        }

        if (['trade', 'profit', 'risk', 'rrr', 'positionSize', 'closeRrr', 'accountReward'].includes(col)) {
          valA = Number(valA);
          valB = Number(valB);
          if (isNaN(valA)) valA = -Infinity;
          if (isNaN(valB)) valB = -Infinity;
        }

        if (valA < valB) return currentSort.direction === 'asc' ? -1 : 1;
        if (valA > valB) return currentSort.direction === 'asc' ? 1 : -1;
        return 0;
      });
    }

    return filteredTrades;
  }

  // Export trades as CSV (filtered/sorted or all)
  function exportTradesToCSV() {
    const tradesToExport = getFilteredSortedTrades();

    if (tradesToExport.length === 0) {
      alert('No trades to export.');
      return;
    }

    const headers = [
      "Trade #",
      "Day",
      "Time",
      "Symbol",
      "Session",
      "M15 EMA's Bias",
      "Risk %",
      "RRR",
      "Position Size",
      "Mode",
      "Entry",
      "SL",
      "TP",
      "Exit Type",
      "Close",
      "Entry Confirm",
      "Close RRR",
      "Close Time",
      "Why Open",
      "Feelings",
      "Why Close If Manual",
      "Profit",
      "Account Reward (%)",
      "Result After Close"
    ];

    let csvContent = headers.map(csvEscape).join(",") + "\r\n";

    tradesToExport.forEach(trade => {
      const row = [
        trade.trade,
        trade.day,
        trade.time,
        trade.symbol,
        trade.session,
        trade.emaBias,
        trade.risk,
        trade.rrr,
        trade.positionSize,
        trade.mode,
        trade.entry,
        trade.sl,
        trade.tp,
        trade.exitType,
        trade.close,
        trade.entryConfirm,
        trade.closeRrr,
        trade.closeTime,
        trade.whyOpen,
        trade.feelings,
        trade.whyCloseManual,
        trade.profit,
        trade.accountReward,
        trade.resultAfterClose
      ].map(csvEscape);
      csvContent += row.join(",") + "\r\n";
    });

    const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
    const url = URL.createObjectURL(blob);

    const a = document.createElement('a');
    a.href = url;
    a.download = 'trades_export.csv';

    document.body.appendChild(a);
    a.click();
    setTimeout(() => {
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
    }, 0);
  }

  exportBtn.addEventListener('click', exportTradesToCSV);

  statsBtn.addEventListener('click', () => {
    window.location.href = 'stats.htm';
  });

  // Filter and sort event listeners for the single filter column + value
  filterColumnSelect.addEventListener('change', e => {
    currentFilters.column = e.target.value;
    renderTrades();
  });
  filterValueInput.addEventListener('input', e => {
    currentFilters.value = e.target.value;
    renderTrades();
  });
  sortColumnSelect.addEventListener('change', e => {
    currentSort.column = e.target.value;
    renderTrades();
  });
  sortDirectionSelect.addEventListener('change', e => {
    currentSort.direction = e.target.value;
    renderTrades();
  });
  clearFiltersBtn.addEventListener('click', () => {
    currentFilters = { column: 'trade', value: '' };
    filterColumnSelect.value = 'trade';
    filterValueInput.value = '';
    currentSort = { column: 'trade', direction: 'desc' };
    sortColumnSelect.value = 'trade';
    sortDirectionSelect.value = 'desc';
    renderTrades();
  });

  // Load data (accounts + currentAccountId) from server on page load
  async function loadDataFromServer() {
    try {
      const response = await fetch('/load.php');
      if (!response.ok) throw new Error('Network error loading data');
      data = await response.json();

      // Create default account if none exist
      if (!data.accounts || Object.keys(data.accounts).length === 0) {
        data.accounts = {
          "default": {
            initialBalance: 5000,
            trades: []
          }
        };
        data.currentAccountId = "default";
      }

      if (!data.currentAccountId || !data.accounts[data.currentAccountId]) {
        data.currentAccountId = Object.keys(data.accounts)[0];
      }

      // Populate account selector
      accountSelect.innerHTML = '';
      Object.keys(data.accounts).forEach(acc => {
        const opt = document.createElement('option');
        opt.value = acc;
        opt.textContent = acc;
        accountSelect.appendChild(opt);
      });
      accountSelect.value = data.currentAccountId;

      updateUIForCurrentAccount();
    } catch (e) {
      alert('Failed to load data from server: ' + e.message);
    }
  }

  // Update UI when account is changed or loaded
  function updateUIForCurrentAccount() {
    if (!data.currentAccountId || !data.accounts[data.currentAccountId]) return;

    const accountData = data.accounts[data.currentAccountId];
    initialBalanceInput.value = accountData.initialBalance.toFixed(2);
    trades = accountData.trades;
    updateAccountRewardForAllTrades();
    updateActualBalanceDisplay();
    renderTrades();
    updateRiskReward();

    tradeForm.reset();
    document.getElementById('tradeIndex').value = '';
    tradeForm.dataset.editing = "false";
    document.getElementById('trade').value = getNextTradeNumber();
    submitBtn.textContent = 'Add Trade';
  }

  accountSelect.addEventListener('change', () => {
    data.currentAccountId = accountSelect.value;
    updateUIForCurrentAccount();
  });

  addAccountBtn.addEventListener('click', () => {
    let name = prompt("Enter new account name:");
    if (!name) return;

    name = name.trim();

    if (name === '') {
      alert("Account name cannot be empty.");
      return;
    }

    if (data.accounts[name]) {
      alert("An account with that name already exists.");
      return;
    }

    data.accounts[name] = { initialBalance: 5000, trades: [] };
    data.currentAccountId = name;

    const option = document.createElement('option');
    option.value = name;
    option.textContent = name;
    accountSelect.appendChild(option);

    accountSelect.value = name;
    updateUIForCurrentAccount();

    // Save immediately so new account persists
    saveDataToServer();
  });

  async function saveDataToServer() {
    try {
      const res = await fetch('/save.php', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify(data)
      });
      if (!res.ok) throw new Error("Network error saving data.");
      const json = await res.json();
      if(json.status !== 'saved') throw new Error("Server error saving data.");
    } catch(e) {
      alert("Error saving data: " + e.message);
    }
  }

  // --- Close RRR Calculation ---

  function calculateCloseRRR() {
    const mode = document.getElementById('mode').value;
    const entry = parseFloat(document.getElementById('entry').value);
    const sl = parseFloat(document.getElementById('sl').value);
    const close = parseFloat(document.getElementById('close').value);
    const exitType = document.getElementById('exitType').value;

    if (!mode || isNaN(entry) || isNaN(sl) || isNaN(close)) {
      document.getElementById('closeRrr').value = '';
      return;
    }

    let risk, reward;

    if (exitType === 'Manual') {
      if (mode === 'Buy') {
        risk = entry - sl;
        reward = close - entry;
      } else if (mode === 'Sell') {
        risk = sl - entry;
        reward = entry - close;
      } else {
        document.getElementById('closeRrr').value = '';
        return;
      }

      if (risk === 0) {
        document.getElementById('closeRrr').value = '';
        return;
      }

      const rrr = reward / risk;
      document.getElementById('closeRrr').value = rrr.toFixed(2);
    } else {
      document.getElementById('closeRrr').value = '';
    }
  }

  ['mode', 'entry', 'sl', 'close', 'exitType'].forEach(id => {
    document.getElementById(id).addEventListener('input', calculateCloseRRR);
  });

  // --- Calculate risk %, reward %, and RRR automatically ---

  function calculateRiskReward({entry, sl, tp, positionSize, initialBalance, symbol}) {
    if (!entry || !sl || !tp || !positionSize || !initialBalance || !symbol) return null;

    const contractSizes = {
      'USTEC.P': 10,
      'SPX500.P': 10,
      'BTC': 1,
      'DE30.P': 10,
    };
    const symbolUpper = symbol.toUpperCase();
    const contractSize = contractSizes[symbolUpper] || 100000; 

    const riskPerUnit = Math.abs(entry - sl) * contractSize;
    const rewardPerUnit = Math.abs(tp - entry) * contractSize;

    const monetaryRisk = riskPerUnit * positionSize;
    const monetaryReward = rewardPerUnit * positionSize;

    if (monetaryRisk === 0) return null;

    const riskPercent = (monetaryRisk / initialBalance) * 100;
    const rewardPercent = (monetaryReward / initialBalance) * 100;
    const rrr = monetaryReward / monetaryRisk;

    return {
      riskPercent: riskPercent.toFixed(2),
      rewardPercent: rewardPercent.toFixed(2),
      rrr: rrr.toFixed(2)
    };
  }

  function updateRiskReward() {
    const entry = parseFloat(document.getElementById('entry').value);
    const sl = parseFloat(document.getElementById('sl').value);
    const tp = parseFloat(document.getElementById('tp').value);
    const positionSize = parseFloat(document.getElementById('positionSize').value);
    const symbol = document.getElementById('symbol').value.trim();
    if (!data.currentAccountId || !data.accounts[data.currentAccountId]) {
      document.getElementById('risk').value = '';
      document.getElementById('rrr').value = '';
      return;
    }
    const initialBalance = data.accounts[data.currentAccountId].initialBalance;

    if (isNaN(entry) || isNaN(sl) || isNaN(tp) || isNaN(positionSize) || !symbol) {
      document.getElementById('risk').value = '';
      document.getElementById('rrr').value = '';
      return;
    }

    const res = calculateRiskReward({entry, sl, tp, positionSize, initialBalance, symbol});

    if (res) {
      document.getElementById('risk').value = res.riskPercent;
      document.getElementById('rrr').value = res.rrr;
    } else {
      document.getElementById('risk').value = '';
      document.getElementById('rrr').value = '';
    }
  }

  ['entry', 'sl', 'tp', 'positionSize', 'symbol'].forEach(id => {
    const el = document.getElementById(id);
    if(el) el.addEventListener('input', updateRiskReward);
  });

  // Auto update Account Reward % live based on profit input
  document.getElementById('profit').addEventListener('input', () => {
    const profitVal = parseFloat(document.getElementById('profit').value);
    const accRewardInput = document.getElementById('accountReward');
    if (!isNaN(profitVal) && data.currentAccountId && data.accounts[data.currentAccountId] && data.accounts[data.currentAccountId].initialBalance > 0) {
      accRewardInput.value = ((profitVal / data.accounts[data.currentAccountId].initialBalance) * 100).toFixed(4);
    } else {
      accRewardInput.value = '';
    }
  });

  window.addEventListener('DOMContentLoaded', () => {
    loadDataFromServer();
    calculateCloseRRR();
    updateRiskReward();
  });
</script>

</body>
</html>