<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Trading Journal</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;
  }
</style>
</head>
<body>

<!-- 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="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="asc">Ascending</option>
      <option value="desc">Descending</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');

  // Store full data: initialBalance and trades array
  let data = {
    initialBalance: 5000,
    trades: []
  };

  let trades = data.trades;

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

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

  // Helper: get next trade number (max + 1)
  function getNextTradeNumber() {
    if (!data.trades || data.trades.length === 0) return 1;
    return data.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; // optional now
    } 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 server (with debounce)
  let debounceTimeout;
  initialBalanceInput.addEventListener('input', () => {
    clearTimeout(debounceTimeout);
    debounceTimeout = setTimeout(async () => {
      let val = Number(initialBalanceInput.value);
      if (isNaN(val) || val < 0) val = 5000;
      data.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();
        // Also update risk and RRR calculations when balance changes
        updateRiskReward();
      } catch(e) {
        alert("Error saving initial balance: " + e.message);
      }
    }, 500);
  });

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

  // Update actual balance display (initial + sum of profits)
  function updateActualBalanceDisplay() {
    const totalProfit = data.trades.reduce((acc, trade) => acc + (trade.profit || 0), 0);
    const actual = data.initialBalance + totalProfit;
    actualBalanceSpan.textContent = actual.toFixed(2);
  }

  // Update account reward field for all trades
  function updateAccountRewardForAllTrades() {
    data.trades.forEach(trade => {
      trade.accountReward = calculateAccountReward(trade.profit);
    });
  }

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

    let filteredTrades = data.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 data.trades for editing
      const originalIndex = data.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}?`)) {
          data.trades.splice(originalIndex, 1);
          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 = data.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) {
      // Show confirmation warning instead of blocking
      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?")) {
        // User cancelled, don't submit
        return;
      }
    }

    // Validate numeric fields
    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 === '') {
      data.trades.push(tradeData);
    } else {
      data.trades[index] = tradeData;
    }

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

    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";

        // Auto-set next trade number for new trade
        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.')) {
      data.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 = data.trades;

    // Determine if filter is active
    const isFilterActive = currentFilters.value.trim() !== '';
    // Determine if sort is default sort (trade ascending)
    const isDefaultSort = currentSort.column === 'trade' && currentSort.direction === 'asc';

    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) {
      // Apply sorting if not default
      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: 'asc' };
    sortColumnSelect.value = 'trade';
    sortDirectionSelect.value = 'asc';
    renderTrades();
  });

  // Load data (initialBalance + trades) 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();
      if(!data.initialBalance) data.initialBalance = 5000;
      if(!Array.isArray(data.trades)) data.trades = [];
      trades = data.trades;

      initialBalanceInput.value = data.initialBalance.toFixed(2);
      updateAccountRewardForAllTrades();
      updateActualBalanceDisplay();
      renderTrades();

      if (!tradeForm.dataset.editing || tradeForm.dataset.editing === "false") {
        document.getElementById('trade').value = getNextTradeNumber();
      }
      // Update risk reward calculation with loaded initial balance
      updateRiskReward();
    } catch (e) {
      alert('Failed to load data from server: ' + e.message);
      data = { initialBalance: 5000, trades: [] };
      trades = [];
      initialBalanceInput.value = data.initialBalance.toFixed(2);
      renderTrades();
      document.getElementById('trade').value = getNextTradeNumber();
      updateRiskReward();
    }
  }

  // --- 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;
      }

      // Allow negative RRR, but avoid division by zero
      if (risk === 0) {
        document.getElementById('closeRrr').value = '';
        return;
      }

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

  // Event listeners to trigger close RRR recalculation
  ['mode', 'entry', 'sl', 'close', 'exitType'].forEach(id => {
    document.getElementById(id).addEventListener('input', calculateCloseRRR);
  });

  // --- New: Calculate risk %, reward %, and RRR (Risk Reward Ratio) 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,
      'DE30.P': 10,
      // add more indices symbols here if needed
    };
    const symbolUpper = symbol.toUpperCase();
    const contractSize = contractSizes[symbolUpper] || 100000; // default forex contract size

    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();
    const initialBalance = data.initialBalance; // from loaded data

    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', 'initialBalance'].forEach(id => {
    const el = document.getElementById(id);
    if(el) {
      el.addEventListener('input', updateRiskReward);
    }
  });

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

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

</body>
</html>