const { useState, useEffect, useRef } = React;

const STRATEGIES = ["Trend Follow", "Breakout", "Pullback", "Mean Reversion", "Scalp", "VWAP Fade", "Opening Range", "News Play", "Overnight Gap", "ICT/SMC", "Order Flow", "Momentum", "Other"];
const EMOTIONS = ["Calm", "Disciplined", "Confident", "In the Zone", "FOMO", "Anxious", "Greedy", "Fearful", "Revenge", "Bored", "Overconfident", "Distracted"];
const MISTAKES = ["None", "Premature Entry", "Late Entry", "Premature Exit", "Late Exit", "Wrong Size", "Ignored Stop", "Over-Traded", "Against Plan", "Chased Price", "Averaging Down", "Emotional Trade", "Poor Risk/Reward"];
const INSTRUMENTS = ["ES", "NQ", "MES", "MNQ", "YM", "RTY", "CL", "GC", "SI", "ZB", "ZN", "6E", "Other"];
const SESSIONS = ["Pre-Market", "RTH Open", "RTH Mid", "RTH Close", "Overnight"];
const MOOD_OPTIONS = ["Calm", "Focused", "Anxious", "Angry", "Tired", "FOMO", "Confident"];
const DISCIPLINE_TAG_OPTIONS = ["Followed plan", "Revenge traded", "Chased", "Oversized", "Hesitated", "Cut winners early"];

const DEFAULT_TRADING_RULES = [
  { text: "Stayed under $200 max daily loss", category: "risk" },
  { text: "Max 1-2 micro contracts (MES/MNQ) per trade", category: "risk" },
  { text: "Set stop loss before entry", category: "risk" },
  { text: "No averaging down or adding to losers", category: "risk" },
  { text: "Max 3 trades today", category: "process" },
  { text: "Only traded during RTH Open (9:30-10:30 ET)", category: "process" },
  { text: "Reviewed charts and did pre-market analysis", category: "process" },
  { text: "Only traded A+ setups from playbook", category: "process" },
  { text: "Walked away after 2 consecutive losses", category: "mindset" },
  { text: "Did not revenge trade after a loss", category: "mindset" },
  { text: "Accepted losses without emotional reaction", category: "mindset" },
];

const RULE_CATEGORY_COLORS = {
  risk: "#ff5566",
  process: "#00ddff",
  mindset: "#7fffb2"
};

const RULE_CATEGORY_LABELS = {
  risk: "Risk Management",
  process: "Process / Discipline",
  mindset: "Mindset / Emotional"
};
const POINT_VALUES = { ES: 50, NQ: 20, MES: 5, MNQ: 2, YM: 5, RTY: 50, CL: 1000, GC: 100, SI: 5000, ZB: 1000, ZN: 1000, "6E": 125000, Other: 50 };
const KNOWN_INSTRUMENTS = new Set(Object.keys(POINT_VALUES));

const emotionColors = {
  "Calm": "#7fffb2", "Disciplined": "#00ddff", "Confident": "#aaff44", "In the Zone": "#ffdd00",
  "FOMO": "#ff9900", "Anxious": "#ff7744", "Greedy": "#ff5566", "Fearful": "#ff3355",
  "Revenge": "#ff0033", "Bored": "#666688", "Overconfident": "#ffbb00", "Distracted": "#bb66ff"
};

const mistakeColors = {
  "None": "#7fffb2",
  "Premature Entry": "#ff9900", "Late Entry": "#ff9900",
  "Premature Exit": "#ff7744", "Late Exit": "#ff7744",
  "Wrong Size": "#ff5566", "Ignored Stop": "#ff0033",
  "Over-Traded": "#ff3355", "Against Plan": "#ff0033",
  "Chased Price": "#ffbb00", "Averaging Down": "#ff5566",
  "Emotional Trade": "#ff7744", "Poor Risk/Reward": "#ff9900"
};

// Helper to normalize mistake field (backwards compat: string → array)
function getMistakes(trade) {
  if (!trade.mistake) return ["None"];
  if (Array.isArray(trade.mistake)) return trade.mistake.length > 0 ? trade.mistake : ["None"];
  return [trade.mistake]; // old string format
}

function calcPnl(trade) {
  const diff = trade.direction === "Long" ? trade.exit - trade.entry : trade.entry - trade.exit;
  return parseFloat((diff * trade.size * (POINT_VALUES[trade.market] || 50)).toFixed(2));
}

function formatDateToYMD(dateString) {
  if (!dateString) return "";

  // If already in YYYY-MM-DD format, return as-is
  if (/^\d{4}-\d{2}-\d{2}$/.test(dateString)) {
    return dateString;
  }

  // Handle MM/DD/YYYY format
  if (/^\d{1,2}\/\d{1,2}\/\d{4}$/.test(dateString)) {
    const [month, day, year] = dateString.split('/');
    return `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
  }

  // Try to parse other formats
  try {
    const date = new Date(dateString);
    if (isNaN(date.getTime())) return dateString; // Return original if invalid

    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    return `${year}-${month}-${day}`;
  } catch {
    return dateString;
  }
}

function formatDateDisplay(dateString) {
  // Convert YYYY-MM-DD to MM/DD/YYYY for display
  if (!dateString) return "";
  if (/^\d{4}-\d{2}-\d{2}$/.test(dateString)) {
    const [year, month, day] = dateString.split('-');
    return `${month}/${day}/${year}`;
  }
  return dateString;
}

function getTodayLocalDate() {
  // Get today's date in local timezone as YYYY-MM-DD
  const today = new Date();
  const year = today.getFullYear();
  const month = String(today.getMonth() + 1).padStart(2, '0');
  const day = String(today.getDate()).padStart(2, '0');
  return `${year}-${month}-${day}`;
}

function detectSession(timestamp) {
  const date = new Date(timestamp);
  const etString = date.toLocaleString("en-US", { timeZone: "America/New_York" });
  const etDate = new Date(etString);
  const time = etDate.getHours() * 60 + etDate.getMinutes();
  if (time >= 570 && time < 630) return "RTH Open";
  if (time >= 630 && time < 900) return "RTH Mid";
  if (time >= 900 && time < 960) return "RTH Close";
  if (time >= 960 && time < 1080) return "Overnight";
  return "Pre-Market";
}

function parseCSV(text) {
  const lines = text.split(/\r?\n/).filter(l => l.trim());
  if (lines.length < 2) return [];
  const headers = lines[0].split(",").map(h => h.trim().replace(/^"|"$/g, ""));
  return lines.slice(1).map(line => {
    const values = [];
    let current = "";
    let inQuotes = false;
    for (let i = 0; i < line.length; i++) {
      if (line[i] === '"') { inQuotes = !inQuotes; }
      else if (line[i] === ',' && !inQuotes) { values.push(current.trim()); current = ""; }
      else { current += line[i]; }
    }
    values.push(current.trim());
    const row = {};
    headers.forEach((h, i) => { row[h] = values[i] || ""; });
    return row;
  });
}

function parseTradovateCsv(text) {
  const rows = parseCSV(text);
  if (rows.length === 0) return { trades: [], error: "No data rows found in CSV." };

  // Only keep filled orders
  const filled = rows.filter(r => (r["Status"] || "").toLowerCase() === "filled");
  if (filled.length === 0) return { trades: [], error: "No filled orders found. Make sure you exported from the Orders tab." };

  // Group by Product (instrument) and pair buys/sells into round trips
  const byProduct = {};
  for (const row of filled) {
    const product = (row["Product"] || "").trim();
    if (!byProduct[product]) byProduct[product] = [];
    byProduct[product].push(row);
  }

  const trades = [];

  for (const [product, orders] of Object.entries(byProduct)) {
    // Sort by fill time
    orders.sort((a, b) => new Date(a["Fill Time"] || a["Timestamp"] || a["Date"]) - new Date(b["Fill Time"] || b["Timestamp"] || b["Date"]));

    let position = 0;
    let entryOrders = [];
    let exitOrders = [];

    for (const order of orders) {
      const bs = (order["B/S"] || "").trim();
      const qty = parseInt(order["Filled Qty"] || order["filledQty"] || order["Quantity"] || "0");
      const price = parseFloat(order["Avg Fill Price"] || order["avgPrice"] || "0");
      if (!qty || !price || !bs) continue;

      const signed = bs.toLowerCase().startsWith("b") ? qty : -qty;
      const prevPosition = position;
      position += signed;

      // Track if this is an entry or exit order
      const isEntry = (prevPosition === 0) || (Math.sign(prevPosition) === Math.sign(position) && Math.abs(position) > Math.abs(prevPosition));
      const isExit = !isEntry;

      if (prevPosition === 0) {
        // Opening new position
        entryOrders = [{ bs, qty, price, time: order["Fill Time"] || order["Timestamp"] || order["Date"] }];
        exitOrders = [];
      } else if (position === 0 || (prevPosition !== 0 && Math.sign(position) !== Math.sign(prevPosition))) {
        // Round trip complete - add current exit order first
        exitOrders.push({ bs, qty, price, time: order["Fill Time"] || order["Timestamp"] || order["Date"] });

        const totalEntryQty = entryOrders.reduce((s, o) => s + o.qty, 0);
        const totalExitQty = exitOrders.reduce((s, o) => s + o.qty, 0);

        // Calculate weighted average entry price
        const entryPrice = entryOrders.reduce((s, o) => s + o.price * o.qty, 0) / totalEntryQty;

        // Calculate weighted average exit price
        const exitPrice = exitOrders.reduce((s, o) => s + o.price * o.qty, 0) / totalExitQty;

        const direction = prevPosition > 0 ? "Long" : "Short";
        const entryTime = entryOrders[0].time;
        const exitTime = exitOrders[exitOrders.length - 1].time;

        // Resolve instrument
        const rootSymbol = product.replace(/[FGHJKMNQUVXZ]\d{1,2}$/, "");
        const market = KNOWN_INSTRUMENTS.has(rootSymbol) ? rootSymbol : (KNOWN_INSTRUMENTS.has(product) ? product : "Other");

        // Extract times from timestamps
        const extractTime = (timestamp) => {
          if (!timestamp) return "";
          const date = new Date(timestamp);
          const hours = String(date.getHours()).padStart(2, '0');
          const minutes = String(date.getMinutes()).padStart(2, '0');
          const seconds = String(date.getSeconds()).padStart(2, '0');
          return `${hours}:${minutes}:${seconds}`;
        };

        const trade = {
          id: `csv-${Date.now()}-${trades.length}`,
          date: formatDateToYMD(entryTime),
          ticker: market,
          market,
          direction,
          entry: parseFloat(entryPrice.toFixed(6)),
          exit: parseFloat(exitPrice.toFixed(6)),
          entryTime: extractTime(entryTime),
          exitTime: extractTime(exitTime),
          size: totalEntryQty,
          strategy: "Other",
          emotion: "Calm",
          session: entryTime ? detectSession(entryTime) : "RTH Mid",
          notes: "[Imported from Tradovate CSV]",
          source: "csv",
        };
        trade.pnl = calcPnl(trade);
        trades.push(trade);

        // If reversed position, start tracking new position
        if (position !== 0) {
          entryOrders = [{ bs, qty: Math.abs(position), price, time: order["Fill Time"] || order["Timestamp"] || order["Date"] }];
          exitOrders = [];
        } else {
          entryOrders = [];
          exitOrders = [];
        }
      } else if (isEntry) {
        // Adding to position (scaling in)
        entryOrders.push({ bs, qty, price, time: order["Fill Time"] || order["Timestamp"] || order["Date"] });
      } else if (isExit) {
        // Reducing position (scaling out)
        exitOrders.push({ bs, qty, price, time: order["Fill Time"] || order["Timestamp"] || order["Date"] });
      }
    }
  }

  trades.sort((a, b) => new Date(b.date) - new Date(a.date));
  return { trades, error: null };
}

const initialTrades = [
  { id: 1, date: "2026-02-24", ticker: "ES", market: "ES", direction: "Long", entry: 5820.25, exit: 5832.50, size: 2, strategy: "Opening Range", emotion: "Disciplined", session: "RTH Open", notes: "Clean ORB setup. Waited for 9:45 confirm. Held to full target. Textbook execution.", pnl: 1225 },
  { id: 2, date: "2026-02-25", ticker: "NQ", market: "NQ", direction: "Short", entry: 20450, exit: 20510, size: 1, strategy: "VWAP Fade", emotion: "Revenge", session: "RTH Mid", notes: "Took this after a losing trade. Rushed entry, no patience. Stopped out at highs.", pnl: -1200 },
  { id: 3, date: "2026-02-26", ticker: "CL", market: "CL", direction: "Long", entry: 71.20, exit: 71.85, size: 2, strategy: "Trend Follow", emotion: "Calm", session: "RTH Open", notes: "EIA inventory report play. Clean trend continuation setup. Let it run to target.", pnl: 1300 },
  { id: 4, date: "2026-02-27", ticker: "MES", market: "MES", direction: "Short", entry: 5795.50, exit: 5783.00, size: 5, strategy: "Breakout", emotion: "Confident", session: "Pre-Market", notes: "Pre-market breakdown below overnight lows. Clean entry, held to target.", pnl: 312 },
];

// IndexedDB helper functions for journal storage
const DB_NAME = 'TradingJournalDB';
const DB_VERSION = 1;
const STORE_NAME = 'journalEntries';

function openJournalDB() {
  return new Promise((resolve, reject) => {
    const request = indexedDB.open(DB_NAME, DB_VERSION);

    request.onerror = () => reject(request.error);
    request.onsuccess = () => resolve(request.result);

    request.onupgradeneeded = (event) => {
      const db = event.target.result;
      if (!db.objectStoreNames.contains(STORE_NAME)) {
        db.createObjectStore(STORE_NAME);
      }
    };
  });
}

async function saveJournalToDB(entries) {
  try {
    const db = await openJournalDB();
    const transaction = db.transaction([STORE_NAME], 'readwrite');
    const store = transaction.objectStore(STORE_NAME);
    store.put(entries, 'entries');

    return new Promise((resolve, reject) => {
      transaction.oncomplete = () => resolve();
      transaction.onerror = () => reject(transaction.error);
    });
  } catch (error) {
    console.error('Failed to save to IndexedDB:', error);
    throw error;
  }
}

async function loadJournalFromDB() {
  try {
    const db = await openJournalDB();
    const transaction = db.transaction([STORE_NAME], 'readonly');
    const store = transaction.objectStore(STORE_NAME);
    const request = store.get('entries');

    return new Promise((resolve, reject) => {
      request.onsuccess = () => resolve(request.result || {});
      request.onerror = () => reject(request.error);
    });
  } catch (error) {
    console.error('Failed to load from IndexedDB:', error);
    return {};
  }
}

// Firestore helper functions for user-specific data
async function saveTradesToFirestore(userId, trades) {
  try {
    console.log('💾 Saving trades to Firestore (new format)...', trades.length, 'trades');
    const tradesCollection = db.collection('users').doc(userId).collection('trades');

    // Save each trade as a separate document (to avoid 1MB limit)
    const batch = db.batch();
    let batchCount = 0;
    const maxBatchSize = 500; // Firestore batch limit

    // First, get all existing trade documents to delete ones that no longer exist
    const existingDocs = await tradesCollection.get();
    const tradeIds = new Set(trades.map(t => String(t.id)));

    existingDocs.forEach(doc => {
      if (doc.id !== 'metadata' && !tradeIds.has(doc.id)) {
        batch.delete(tradesCollection.doc(doc.id));
        batchCount++;
      }
    });

    // Commit deletion batch if needed
    if (batchCount > 0) {
      await batch.commit();
    }

    // Now save/update all current trades
    const batches = [];
    let currentBatch = db.batch();
    batchCount = 0;

    for (const trade of trades) {
      const docRef = tradesCollection.doc(String(trade.id));
      currentBatch.set(docRef, trade);
      batchCount++;

      if (batchCount >= maxBatchSize) {
        batches.push(currentBatch.commit());
        currentBatch = db.batch();
        batchCount = 0;
      }
    }

    // Commit remaining batch
    if (batchCount > 0) {
      batches.push(currentBatch.commit());
    }

    // Save metadata
    const metadataBatch = db.batch();
    metadataBatch.set(tradesCollection.doc('metadata'), {
      count: trades.length,
      updatedAt: firebase.firestore.FieldValue.serverTimestamp()
    });
    batches.push(metadataBatch.commit());

    await Promise.all(batches);
    console.log('✅ Trades saved successfully (new format)');
  } catch (error) {
    console.error('Failed to save trades to Firestore:', error);
    throw error;
  }
}

async function loadTradesFromFirestore(userId) {
  try {
    console.log('📥 Loading trades from Firestore for user:', userId);
    const tradesCollection = db.collection('users').doc(userId).collection('trades');

    // Load ALL documents from the collection
    console.log('🔍 Loading all documents from trades collection...');
    const snapshot = await tradesCollection.get();
    console.log('📊 Found', snapshot.size, 'total documents in trades collection');

    if (snapshot.empty) {
      console.log('⚠️ No trades found in Firestore (collection is empty)');
      return [];
    }

    // Log all document IDs for debugging
    const allDocIds = [];
    snapshot.forEach(doc => {
      allDocIds.push(doc.id);
    });
    console.log('📄 All document IDs:', allDocIds);

    let trades = [];
    let foundOldFormat = false;

    // Process each document
    snapshot.forEach(doc => {
      const docId = doc.id;
      const docData = doc.data();
      console.log('📄 Processing document:', docId, '| Data keys:', Object.keys(docData));

      // Check if this is the old format document (could be 'data', 'undefined', or any doc with 'trades' array)
      if (docData.trades && Array.isArray(docData.trades)) {
        console.log('✅ Found old format document "' + docId + '" with', docData.trades.length, 'trades');
        trades = [...trades, ...docData.trades];
        foundOldFormat = true;
      }
      // Otherwise, it's a new format individual trade document (skip metadata)
      else if (docId !== 'metadata' && docId !== 'data' && docId !== 'undefined') {
        console.log('✅ Found individual trade document:', docId);
        trades.push(docData);
      }
    });

    console.log('✅ Loaded', trades.length, 'total trades');
    console.log('   - From old format:', foundOldFormat ? 'YES' : 'NO');
    console.log('   - From new format:', (trades.length - (foundOldFormat ? snapshot.docs.find(d => d.id === 'data')?.data()?.trades?.length || 0 : 0)));

    if (trades.length > 0) {
      console.log('First trade sample:', trades[0]);
    }

    return trades;
  } catch (error) {
    console.error('❌ Failed to load trades from Firestore:', error);
    console.error('Error details:', error.message, error.code);
    return [];
  }
}

async function saveJournalToFirestore(userId, journalEntries) {
  try {
    // Save each date as a separate document to avoid 1MB Firestore limit
    const batch = db.batch();
    let batchCount = 0;
    const MAX_BATCH_SIZE = 500;

    for (const [dateKey, entryData] of Object.entries(journalEntries)) {
      const docRef = db.collection('users').doc(userId).collection('journal').doc(dateKey);
      batch.set(docRef, {
        ...entryData,
        updatedAt: firebase.firestore.FieldValue.serverTimestamp()
      });

      batchCount++;

      // Firestore batch limit is 500 operations
      if (batchCount >= MAX_BATCH_SIZE) {
        await batch.commit();
        batchCount = 0;
      }
    }

    // Commit remaining operations
    if (batchCount > 0) {
      await batch.commit();
    }

    console.log(`Saved ${Object.keys(journalEntries).length} journal entries to Firestore`);
  } catch (error) {
    console.error('Failed to save journal to Firestore:', error);
    throw error;
  }
}

async function loadJournalFromFirestore(userId) {
  try {
    // Try new format first (individual documents per date)
    const snapshot = await db.collection('users').doc(userId).collection('journal').get();

    if (snapshot.empty) {
      console.log('No journal entries found in Firestore');
      return {};
    }

    const entries = {};
    snapshot.docs.forEach(doc => {
      // Skip the old 'entries' document if it exists
      if (doc.id !== 'entries') {
        entries[doc.id] = doc.data();
      }
    });

    console.log(`Loaded ${Object.keys(entries).length} journal entries from Firestore`);
    return entries;
  } catch (error) {
    console.error('Failed to load journal from Firestore:', error);
    return {};
  }
}

// Trading Rules Firestore persistence
async function loadTradingRulesFromFirestore(userId) {
  try {
    const doc = await db.collection('users').doc(userId).collection('settings').doc('tradingRules').get();
    if (doc.exists) return doc.data().rules || [];
    return [];
  } catch (error) {
    console.error('Failed to load trading rules from Firestore:', error);
    return [];
  }
}

async function saveTradingRulesToFirestore(userId, rules) {
  try {
    await db.collection('users').doc(userId).collection('settings').doc('tradingRules').set({
      rules: rules,
      updatedAt: firebase.firestore.FieldValue.serverTimestamp()
    });
  } catch (error) {
    console.error('Failed to save trading rules to Firestore:', error);
  }
}

// Video Recording Component
function VideoRecorder({ user, onRecordingSaved }) {
  const [isRecording, setIsRecording] = useState(false);
  const [isPaused, setIsPaused] = useState(false);
  const [recordingTime, setRecordingTime] = useState(0);
  const [isProcessing, setIsProcessing] = useState(false);

  const mediaRecorderRef = useRef(null);
  const chunksRef = useRef([]);
  const timerRef = useRef(null);
  const streamRef = useRef(null);

  useEffect(() => {
    return () => {
      // Cleanup on unmount
      if (timerRef.current) clearInterval(timerRef.current);
      if (streamRef.current) {
        streamRef.current.getTracks().forEach(track => track.stop());
      }
    };
  }, []);

  const startRecording = async () => {
    try {
      // Request screen + audio
      const screenStream = await navigator.mediaDevices.getDisplayMedia({
        video: { mediaSource: 'screen' },
        audio: false
      });

      // Request microphone
      let audioStream;
      try {
        audioStream = await navigator.mediaDevices.getUserMedia({ audio: true });
      } catch (err) {
        console.log('Microphone access denied, recording screen only');
      }

      // Combine streams
      const tracks = [...screenStream.getVideoTracks()];
      if (audioStream) {
        tracks.push(...audioStream.getAudioTracks());
      }

      const combinedStream = new MediaStream(tracks);
      streamRef.current = combinedStream;

      // Create MediaRecorder
      const mediaRecorder = new MediaRecorder(combinedStream, {
        mimeType: 'video/webm;codecs=vp9',
        videoBitsPerSecond: 2500000 // 2.5 Mbps for good quality
      });

      chunksRef.current = [];

      mediaRecorder.ondataavailable = (event) => {
        if (event.data.size > 0) {
          chunksRef.current.push(event.data);
        }
      };

      mediaRecorder.onstop = async () => {
        const blob = new Blob(chunksRef.current, { type: 'video/webm' });
        await saveRecording(blob);

        // Stop all tracks
        streamRef.current.getTracks().forEach(track => track.stop());
        streamRef.current = null;
      };

      mediaRecorderRef.current = mediaRecorder;
      mediaRecorder.start(1000); // Collect data every second
      setIsRecording(true);

      // Start timer
      setRecordingTime(0);
      timerRef.current = setInterval(() => {
        setRecordingTime(prev => prev + 1);
      }, 1000);

    } catch (error) {
      console.error('Error starting recording:', error);
      alert('Failed to start recording. Please make sure you granted screen sharing permission.');
    }
  };

  const stopRecording = () => {
    if (mediaRecorderRef.current && isRecording) {
      mediaRecorderRef.current.stop();
      setIsRecording(false);
      if (timerRef.current) {
        clearInterval(timerRef.current);
        timerRef.current = null;
      }
      setIsProcessing(true);
    }
  };

  const saveRecording = async (blob) => {
    try {
      const timestamp = Date.now();
      const date = new Date().toISOString().split('T')[0];
      const time = new Date().toLocaleTimeString('en-US', { hour12: false }).replace(/:/g, '-');
      const fileName = `ultratrack_recording_${date}_${time}.webm`;

      // Create download link
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = fileName;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);

      // Save metadata to Firestore (for tracking purposes, no video URL)
      const recordingData = {
        userId: user.uid,
        fileName: fileName,
        localFile: true,
        createdAt: new Date().toISOString(),
        duration: recordingTime,
        size: blob.size,
        attached: false,
        tradeId: null
      };

      const docRef = await db.collection('recordings').add(recordingData);
      console.log('✅ Recording saved to Firestore with ID:', docRef.id);
      console.log('Recording data:', recordingData);

      setIsProcessing(false);
      setRecordingTime(0);

      const savedRecording = {
        id: docRef.id,
        ...recordingData
      };

      if (onRecordingSaved) {
        console.log('Calling onRecordingSaved callback with:', savedRecording);
        onRecordingSaved(savedRecording);
      }

      alert(`Recording saved to Downloads!\nFile: ${fileName}\n\nYou can attach this video to trades later.`);
    } catch (error) {
      console.error('Error saving recording:', error);
      alert('Failed to save recording');
      setIsProcessing(false);
    }
  };

  const formatTime = (seconds) => {
    const mins = Math.floor(seconds / 60);
    const secs = seconds % 60;
    return `${mins}:${secs.toString().padStart(2, '0')}`;
  };

  return (
    <div style={{
      position: 'fixed',
      bottom: '20px',
      right: '20px',
      zIndex: 1000,
      display: 'flex',
      flexDirection: 'column',
      alignItems: 'flex-end',
      gap: '8px'
    }}>
      {/* Recording Timer */}
      {(isRecording || isProcessing) && (
        <div style={{
          background: isProcessing ? '#1a1a2e' : '#ff0033',
          color: '#fff',
          padding: '8px 16px',
          borderRadius: '20px',
          fontSize: '14px',
          fontWeight: 'bold',
          display: 'flex',
          alignItems: 'center',
          gap: '8px',
          boxShadow: '0 4px 12px rgba(0,0,0,0.3)'
        }}>
          {isProcessing ? (
            <>
              <div style={{ fontSize: '12px' }}>Processing...</div>
            </>
          ) : (
            <>
              <div style={{
                width: '8px',
                height: '8px',
                borderRadius: '50%',
                background: '#fff',
                animation: 'pulse 1s infinite'
              }}></div>
              <div>{formatTime(recordingTime)}</div>
            </>
          )}
        </div>
      )}

      {/* Record Button */}
      <button
        onClick={isRecording ? stopRecording : startRecording}
        disabled={isProcessing}
        style={{
          width: '64px',
          height: '64px',
          borderRadius: '50%',
          border: 'none',
          background: isRecording ? '#ff3355' : '#2196F3',
          color: '#fff',
          fontSize: '24px',
          cursor: isProcessing ? 'not-allowed' : 'pointer',
          boxShadow: '0 4px 12px rgba(0,0,0,0.3)',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          transition: 'all 0.3s ease',
          opacity: isProcessing ? 0.5 : 1
        }}
        title={isRecording ? 'Stop Recording' : 'Start Recording'}
      >
        {isRecording ? '⬛' : '⏺'}
      </button>
    </div>
  );
}



// Authentication wrapper component
function App() {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
  const [authMode, setAuthMode] = useState('login'); // 'login' or 'signup'

  useEffect(() => {
    // Listen for auth state changes
    const unsubscribe = auth.onAuthStateChanged((user) => {
      setUser(user);
      setLoading(false);
    });

    return () => unsubscribe();
  }, []);

  if (loading) {
    return (
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100vh', background: '#06060d', color: '#fff', fontFamily: 'system-ui' }}>
        <p>Loading...</p>
      </div>
    );
  }

  if (!user) {
    return <AuthPage authMode={authMode} setAuthMode={setAuthMode} />;
  }

  // Check if email is verified
  if (!user.emailVerified) {
    return <EmailVerificationPage user={user} />;
  }

  return <TradingJournal user={user} />;
}

// Email Verification Page Component
function EmailVerificationPage({ user }) {
  const [resending, setResending] = useState(false);
  const [resendSuccess, setResendSuccess] = useState(false);
  const [checkingVerification, setCheckingVerification] = useState(false);

  const handleResendEmail = async () => {
    setResending(true);
    setResendSuccess(false);
    try {
      await user.sendEmailVerification();
      setResendSuccess(true);
    } catch (error) {
      console.error('Error resending verification email:', error);
    }
    setResending(false);
  };

  const handleCheckVerification = async () => {
    setCheckingVerification(true);
    try {
      await user.reload();
      if (user.emailVerified) {
        window.location.reload();
      }
    } catch (error) {
      console.error('Error checking verification:', error);
    }
    setCheckingVerification(false);
  };

  return (
    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', background: '#06060d', padding: '20px' }}>
      <div style={{ width: '100%', maxWidth: '500px', background: '#0f0f1e', border: '1px solid #1e1e30', borderRadius: '12px', padding: '40px', textAlign: 'center' }}>
        {/* Logo */}
        <div style={{ marginBottom: '32px' }}>
          <h1 style={{
            fontFamily: "'Courier New', Courier, monospace",
            fontSize: 32,
            fontWeight: 700,
            letterSpacing: "1px",
            margin: 0
          }}>
            <span style={{ color: "#e45e54" }}>u</span>
            <span style={{ color: "#f28b57" }}>l</span>
            <span style={{ color: "#fabf53" }}>t</span>
            <span style={{ color: "#8bc268" }}>r</span>
            <span style={{ color: "#7ca5d4" }}>a</span>
            <span style={{ color: "#a08ecc" }}>t</span>
            <span style={{ color: "#c581b6" }}>r</span>
            <span style={{ color: "#e45e54" }}>a</span>
            <span style={{ color: "#f28b57" }}>c</span>
            <span style={{ color: "#fabf53" }}>k</span>
          </h1>
          <p style={{ color: '#888', fontSize: '14px', marginTop: '8px' }}>Trading Journal</p>
        </div>

        {/* Email Icon */}
        <div style={{ fontSize: '48px', marginBottom: '24px' }}>📧</div>

        <h2 style={{ color: '#fff', fontSize: '24px', marginBottom: '16px', fontWeight: 600 }}>
          Verify Your Email
        </h2>

        <p style={{ color: '#aaa', fontSize: '14px', lineHeight: '1.6', marginBottom: '24px' }}>
          We've sent a verification email to <strong style={{ color: '#7fffb2' }}>{user.email}</strong>
          <br /><br />
          Please check your inbox and click the verification link to activate your account.
        </p>

        {resendSuccess && (
          <div style={{ padding: '12px', background: 'rgba(139,194,104,0.1)', border: '1px solid rgba(139,194,104,0.3)', borderRadius: '6px', marginBottom: '20px' }}>
            <p style={{ color: '#8bc268', fontSize: '13px', margin: 0 }}>
              Verification email sent! Please check your inbox.
            </p>
          </div>
        )}

        <div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
          <button
            onClick={handleCheckVerification}
            disabled={checkingVerification}
            style={{
              width: '100%',
              padding: '14px',
              background: checkingVerification ? '#444' : '#7fffb2',
              color: checkingVerification ? '#aaa' : '#000',
              border: 'none',
              borderRadius: '6px',
              fontSize: '14px',
              fontWeight: 600,
              cursor: checkingVerification ? 'not-allowed' : 'pointer',
              transition: 'all 0.2s'
            }}
          >
            {checkingVerification ? 'Checking...' : 'I\'ve Verified My Email'}
          </button>

          <button
            onClick={handleResendEmail}
            disabled={resending}
            style={{
              width: '100%',
              padding: '14px',
              background: 'transparent',
              color: resending ? '#666' : '#7ca5d4',
              border: '1px solid #2a2a4e',
              borderRadius: '6px',
              fontSize: '14px',
              fontWeight: 600,
              cursor: resending ? 'not-allowed' : 'pointer',
              transition: 'all 0.2s'
            }}
          >
            {resending ? 'Sending...' : 'Resend Verification Email'}
          </button>

          <button
            onClick={() => auth.signOut()}
            style={{
              width: '100%',
              padding: '14px',
              background: 'transparent',
              color: '#ff4466',
              border: '1px solid rgba(255,68,102,0.3)',
              borderRadius: '6px',
              fontSize: '14px',
              fontWeight: 600,
              cursor: 'pointer',
              transition: 'all 0.2s'
            }}
          >
            Sign Out
          </button>
        </div>
      </div>
    </div>
  );
}

// Login/Signup Page Component
function AuthPage({ authMode, setAuthMode }) {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');
  const [loading, setLoading] = useState(false);
  const [verificationSent, setVerificationSent] = useState(false);

  const handleSubmit = async (e) => {
    e.preventDefault();
    setError('');
    setLoading(true);

    try {
      if (authMode === 'signup') {
        const userCredential = await auth.createUserWithEmailAndPassword(email, password);
        // Send verification email
        await userCredential.user.sendEmailVerification();
        setVerificationSent(true);
        setLoading(false);
      } else {
        await auth.signInWithEmailAndPassword(email, password);
      }
    } catch (err) {
      setError(err.message);
      setLoading(false);
    }
  };

  return (
    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', background: '#06060d', padding: '20px' }}>
      <div style={{ width: '100%', maxWidth: '400px', background: '#0f0f1e', border: '1px solid #1e1e30', borderRadius: '12px', padding: '40px' }}>
        {/* Logo */}
        <div style={{ textAlign: 'center', marginBottom: '32px' }}>
          <h1 style={{
            fontFamily: "'Courier New', Courier, monospace",
            fontSize: 32,
            fontWeight: 700,
            letterSpacing: "1px",
            margin: 0
          }}>
            <span style={{ color: "#e45e54" }}>u</span>
            <span style={{ color: "#f28b57" }}>l</span>
            <span style={{ color: "#fabf53" }}>t</span>
            <span style={{ color: "#8bc268" }}>r</span>
            <span style={{ color: "#7ca5d4" }}>a</span>
            <span style={{ color: "#a08ecc" }}>t</span>
            <span style={{ color: "#c581b6" }}>r</span>
            <span style={{ color: "#e45e54" }}>a</span>
            <span style={{ color: "#f28b57" }}>c</span>
            <span style={{ color: "#fabf53" }}>k</span>
          </h1>
          <p style={{ color: '#888', fontSize: '14px', marginTop: '8px' }}>Trading Journal</p>
        </div>

        {/* Auth Form */}
        <form onSubmit={handleSubmit}>
          <div style={{ marginBottom: '20px' }}>
            <label style={{ display: 'block', color: '#ccc', fontSize: '14px', marginBottom: '8px' }}>Email</label>
            <input
              type="email"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              required
              style={{
                width: '100%',
                padding: '12px',
                background: '#1a1a2e',
                border: '1px solid #2a2a4e',
                borderRadius: '6px',
                color: '#fff',
                fontSize: '14px',
                outline: 'none'
              }}
            />
          </div>

          <div style={{ marginBottom: '24px' }}>
            <label style={{ display: 'block', color: '#ccc', fontSize: '14px', marginBottom: '8px' }}>Password</label>
            <input
              type="password"
              value={password}
              onChange={(e) => setPassword(e.target.value)}
              required
              minLength="6"
              style={{
                width: '100%',
                padding: '12px',
                background: '#1a1a2e',
                border: '1px solid #2a2a4e',
                borderRadius: '6px',
                color: '#fff',
                fontSize: '14px',
                outline: 'none'
              }}
            />
          </div>

          {error && (
            <div style={{ padding: '12px', background: 'rgba(255,68,102,0.1)', border: '1px solid rgba(255,68,102,0.3)', borderRadius: '6px', marginBottom: '20px' }}>
              <p style={{ color: '#ff4466', fontSize: '13px', margin: 0 }}>{error}</p>
            </div>
          )}

          {verificationSent && (
            <div style={{ padding: '12px', background: 'rgba(139,194,104,0.1)', border: '1px solid rgba(139,194,104,0.3)', borderRadius: '6px', marginBottom: '20px' }}>
              <p style={{ color: '#8bc268', fontSize: '13px', margin: 0, marginBottom: '8px', fontWeight: 600 }}>
                Verification email sent!
              </p>
              <p style={{ color: '#8bc268', fontSize: '12px', margin: 0 }}>
                Please check your email and click the verification link to activate your account. You can close this page.
              </p>
            </div>
          )}

          <button
            type="submit"
            disabled={loading || verificationSent}
            style={{
              width: '100%',
              padding: '14px',
              background: loading ? '#444' : '#7fffb2',
              color: loading ? '#999' : '#000',
              border: 'none',
              borderRadius: '6px',
              fontSize: '16px',
              fontWeight: '600',
              cursor: loading ? 'not-allowed' : 'pointer',
              transition: 'all 0.2s'
            }}
          >
            {loading ? 'Please wait...' : (authMode === 'login' ? 'Sign In' : 'Create Account')}
          </button>
        </form>

        {/* Toggle between login/signup */}
        <div style={{ marginTop: '24px', textAlign: 'center' }}>
          <p style={{ color: '#888', fontSize: '14px' }}>
            {authMode === 'login' ? "Don't have an account? " : "Already have an account? "}
            <button
              onClick={() => {
                setAuthMode(authMode === 'login' ? 'signup' : 'login');
                setError('');
              }}
              style={{
                background: 'none',
                border: 'none',
                color: '#7fffb2',
                cursor: 'pointer',
                textDecoration: 'underline',
                fontSize: '14px'
              }}
            >
              {authMode === 'login' ? 'Sign up' : 'Sign in'}
            </button>
          </p>
        </div>
      </div>
    </div>
  );
}

function TradingJournal({ user }) {
  // Load trades from Firestore
  const [trades, setTrades] = useState([]);
  const [tradesLoaded, setTradesLoaded] = useState(false);

  // Load trades from Firestore on mount
  useEffect(() => {
    async function loadTrades() {
      try {
        // Try loading from Firestore first
        let loadedTrades = await loadTradesFromFirestore(user.uid);

        // If Firestore is empty, check localStorage for migration
        if (loadedTrades.length === 0) {
          const localStorageData = localStorage.getItem('tradingJournalTrades');
          if (localStorageData) {
            console.log('Migrating trades from localStorage to Firestore...');
            loadedTrades = JSON.parse(localStorageData);
          } else {
            // No data anywhere, use initial trades
            loadedTrades = initialTrades;
          }
        }

        // Migrate old date formats and add default times
        loadedTrades = loadedTrades.map(trade => {
          const migrated = {
            ...trade,
            date: formatDateToYMD(trade.date)
          };

          if (!migrated.entryTime || !migrated.exitTime) {
            const sessionTimes = {
              "RTH Open": { entry: "09:30:00", exit: "10:15:00" },
              "RTH Mid": { entry: "11:00:00", exit: "13:30:00" },
              "RTH Close": { entry: "15:00:00", exit: "15:45:00" },
              "Pre-Market": { entry: "08:00:00", exit: "09:25:00" },
              "Overnight": { entry: "18:00:00", exit: "20:30:00" }
            };

            const defaultTime = sessionTimes[migrated.session] || { entry: "09:30:00", exit: "15:00:00" };
            if (!migrated.entryTime) migrated.entryTime = defaultTime.entry;
            if (!migrated.exitTime) migrated.exitTime = defaultTime.exit;
          }

          return migrated;
        });

        setTrades(loadedTrades);
        setTradesLoaded(true);

        // Save to Firestore and clear localStorage
        await saveTradesToFirestore(user.uid, loadedTrades);
        localStorage.removeItem('tradingJournalTrades');
        console.log('Trades migrated to Firestore successfully!');
      } catch (error) {
        console.error('Failed to load trades:', error);
        setTrades(initialTrades);
        setTradesLoaded(true);
      }
    }

    loadTrades();
  }, [user.uid]);

  // Auto-save trades to Firestore whenever they change (with debounce)
  useEffect(() => {
    if (tradesLoaded && trades.length > 0) {
      const timeoutId = setTimeout(() => {
        console.log('Auto-saving trades to Firestore...', trades.length, 'trades');
        saveTradesToFirestore(user.uid, trades)
          .then(() => {
            console.log('✅ Trades auto-saved successfully to Firestore');
          })
          .catch(error => {
            console.error('❌ Auto-save trades to Firestore failed:', error);
            // Don't show alert for auto-save errors, just log them
          });
      }, 2000); // Wait 2 seconds after last change before saving

      return () => clearTimeout(timeoutId);
    }
  }, [trades, tradesLoaded, user.uid]);

  const [view, setView] = useState("dashboard");
  const [chartTimeframe, setChartTimeframe] = useState("This Week");
  const [showForm, setShowForm] = useState(false);
  const [sidebarOpen, setSidebarOpen] = useState(true);
  const [calendarDate, setCalendarDate] = useState(new Date());
  const [recordings, setRecordings] = useState([]);
  const [recordingsLoaded, setRecordingsLoaded] = useState(false);
  const [weeklyAnalysis, setWeeklyAnalysis] = useState({ loading: false, error: null, data: null });
  const [selectedWeek, setSelectedWeek] = useState(() => {
    // Default to current week
    const now = new Date();
    const dayOfWeek = now.getDay();
    const startOfWeek = new Date(now);
    startOfWeek.setDate(now.getDate() - dayOfWeek);
    startOfWeek.setHours(0, 0, 0, 0);
    const endOfWeek = new Date(startOfWeek);
    endOfWeek.setDate(startOfWeek.getDate() + 6);
    endOfWeek.setHours(23, 59, 59, 999);
    return { start: startOfWeek, end: endOfWeek };
  });
  const [monthlyAnalysis, setMonthlyAnalysis] = useState({ loading: false, error: null, data: null });
  const [selectedMonth, setSelectedMonth] = useState(() => {
    const now = new Date();
    return { year: now.getFullYear(), month: now.getMonth() }; // month is 0-indexed
  });
  const [strategyScores, setStrategyScores] = useState({ loading: false, error: null, data: null });
  const [patterns, setPatterns] = useState({ loading: false, error: null, data: null });
  const [chatMessages, setChatMessages] = useState([]);
  const [chatInput, setChatInput] = useState("");
  const [chatLoading, setChatLoading] = useState(false);
  const [chatPanelOpen, setChatPanelOpen] = useState(false);

  // Load recordings from Firestore
  useEffect(() => {
    async function loadRecordings() {
      try {
        console.log('Loading recordings for user:', user.uid);

        // First, migrate any recordings without userId
        try {
          console.log('🔍 Checking for recordings without userId...');
          const allRecordingsSnapshot = await db.collection('recordings').get();
          console.log('📊 Total recordings in database:', allRecordingsSnapshot.docs.length);

          const recordingsToFix = [];

          allRecordingsSnapshot.docs.forEach(doc => {
            const data = doc.data();
            console.log(`Recording ${doc.id}: has userId = ${!!data.userId}, userId value = ${data.userId}`);
            if (!data.userId) {
              recordingsToFix.push(doc.id);
            }
          });

          if (recordingsToFix.length > 0) {
            console.log(`🔧 Migrating ${recordingsToFix.length} recordings without userId...`);
            console.log('Recording IDs to fix:', recordingsToFix);
            const batch = db.batch();
            recordingsToFix.forEach(docId => {
              const ref = db.collection('recordings').doc(docId);
              batch.update(ref, { userId: user.uid });
            });
            await batch.commit();
            console.log('✅ Migration complete!');
          } else {
            console.log('✅ No recordings need migration - all have userId');
          }
        } catch (migrationError) {
          console.error('❌ Migration error:', migrationError);
          console.error('Migration error details:', migrationError.message);
        }

        const snapshot = await db.collection('recordings')
          .where('userId', '==', user.uid)
          .orderBy('createdAt', 'desc')
          .get();

        console.log('Found', snapshot.docs.length, 'recordings in Firestore');

        const loadedRecordings = snapshot.docs.map(doc => ({
          id: doc.id,
          ...doc.data()
        }));

        console.log('Loaded recordings:', loadedRecordings);
        setRecordings(loadedRecordings);
        setRecordingsLoaded(true);
      } catch (error) {
        console.error('❌ Failed to load recordings:', error);
        console.error('Error details:', error.message);
        setRecordings([]);
        setRecordingsLoaded(true);
      }
    }

    loadRecordings();
  }, [user.uid]);

  // Custom strategies
  const [customStrategies, setCustomStrategies] = useState(() => {
    try {
      const saved = localStorage.getItem('tradingJournalCustomStrategies');
      return saved ? JSON.parse(saved) : [];
    } catch (error) {
      return [];
    }
  });

  // Custom emotions
  const [customEmotions, setCustomEmotions] = useState(() => {
    try {
      const saved = localStorage.getItem('tradingJournalCustomEmotions');
      return saved ? JSON.parse(saved) : [];
    } catch (error) {
      return [];
    }
  });

  // Custom mistakes
  const [customMistakes, setCustomMistakes] = useState(() => {
    try {
      const saved = localStorage.getItem('tradingJournalCustomMistakes');
      return saved ? JSON.parse(saved) : [];
    } catch (error) {
      return [];
    }
  });
  const [showStrategyManager, setShowStrategyManager] = useState(false);
  const [newStrategy, setNewStrategy] = useState("");
  const [showEmotionManager, setShowEmotionManager] = useState(false);
  const [newEmotion, setNewEmotion] = useState("");
  const [showMistakeManager, setShowMistakeManager] = useState(false);
  const [newMistake, setNewMistake] = useState("");

  // Trading rules checklist
  const [tradingRules, setTradingRules] = useState([]);
  const [tradingRulesLoaded, setTradingRulesLoaded] = useState(false);
  const [showRulesManager, setShowRulesManager] = useState(false);
  const [newRuleText, setNewRuleText] = useState("");
  const [newRuleCategory, setNewRuleCategory] = useState("risk");
  const [editingRuleId, setEditingRuleId] = useState(null);
  const [editingRuleText, setEditingRuleText] = useState("");

  const [isDark, setIsDark] = useState(() => {
    // Always use system preference
    return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
  });
  const [aiLoading, setAiLoading] = useState(false);
  const [aiReport, setAiReport] = useState("");
  const [aiError, setAiError] = useState("");
  const [expandedTrade, setExpandedTrade] = useState(null);
  const [tradeAi, setTradeAi] = useState({});
  const [filterSession, setFilterSession] = useState("All");
  const [filterStrategy, setFilterStrategy] = useState("All");
  const [filterDirection, setFilterDirection] = useState("All");
  const [filterOutcome, setFilterOutcome] = useState("All");
  const [filterDateFrom, setFilterDateFrom] = useState("");
  const [filterDateTo, setFilterDateTo] = useState("");
  const [expandedWeeks, setExpandedWeeks] = useState({});
  const [shareCardTrade, setShareCardTrade] = useState(null);
  const [sharePnLCard, setSharePnLCard] = useState(null); // "daily", "weekly", "monthly"
  const [apiKey, setApiKey] = useState(() => {
    try {
      const saved = localStorage.getItem('anthropicApiKey');
      return saved || "";
    } catch (error) {
      return "";
    }
  });
  const [form, setForm] = useState({ date: new Date().toISOString().split("T")[0], ticker: "", market: "ES", direction: "Long", entry: "", exit: "", entryTime: "", exitTime: "", size: "1", strategy: "Opening Range", emotion: "Calm", mistake: ["None"], session: "RTH Open", notes: "" });


  // Save trades to localStorage whenever they change
  useEffect(() => {
    try {
      localStorage.setItem('tradingJournalTrades', JSON.stringify(trades));
    } catch (error) {
      console.error('Failed to save trades to localStorage:', error);
    }
  }, [trades]);

  // Listen for system theme changes and always sync
  useEffect(() => {
    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
    const handleChange = (e) => {
      setIsDark(e.matches);
    };

    mediaQuery.addEventListener('change', handleChange);
    return () => mediaQuery.removeEventListener('change', handleChange);
  }, []);

  // Save custom strategies to localStorage
  useEffect(() => {
    try {
      localStorage.setItem('tradingJournalCustomStrategies', JSON.stringify(customStrategies));
    } catch (error) {
      console.error('Failed to save custom strategies to localStorage:', error);
    }
  }, [customStrategies]);

  // Save custom emotions to localStorage
  useEffect(() => {
    try {
      localStorage.setItem('tradingJournalCustomEmotions', JSON.stringify(customEmotions));
    } catch (error) {
      console.error('Failed to save custom emotions to localStorage:', error);
    }
  }, [customEmotions]);

  // Save custom mistakes to localStorage
  useEffect(() => {
    try {
      localStorage.setItem('tradingJournalCustomMistakes', JSON.stringify(customMistakes));
    } catch (error) {
      console.error('Failed to save custom mistakes to localStorage:', error);
    }
  }, [customMistakes]);

  // Save API key to localStorage
  useEffect(() => {
    try {
      localStorage.setItem('anthropicApiKey', apiKey);
    } catch (error) {
      console.error('Failed to save API key to localStorage:', error);
    }
  }, [apiKey]);

  // Load existing Lyra review when week changes
  useEffect(() => {
    async function loadExistingReview() {
      console.log('🔍 Checking for existing Lyra review...', { hasUser: !!user, week: selectedWeek });
      if (user && selectedWeek.start && selectedWeek.end) {
        const existingReview = await loadLyraReviewFromFirestore(user.uid, selectedWeek.start, selectedWeek.end);
        if (existingReview) {
          console.log('✅ Found existing review, displaying it');
          setWeeklyAnalysis({
            loading: false,
            error: null,
            data: existingReview
          });
        } else {
          console.log('ℹ️ No existing review for this week');
          // Clear analysis if no existing review for this week
          setWeeklyAnalysis({ loading: false, error: null, data: null });
        }
      }
    }
    loadExistingReview();
  }, [selectedWeek, user]);

  // Load existing Lyra monthly review when month changes
  useEffect(() => {
    async function loadExistingMonthly() {
      if (user && selectedMonth) {
        const existing = await loadMonthlyReviewFromFirestore(user.uid, selectedMonth.year, selectedMonth.month);
        if (existing) {
          setMonthlyAnalysis({ loading: false, error: null, data: existing });
        } else {
          setMonthlyAnalysis({ loading: false, error: null, data: null });
        }
      }
    }
    loadExistingMonthly();
  }, [selectedMonth, user]);

  // Load existing strategy scores on mount
  useEffect(() => {
    async function loadExistingScores() {
      if (user) {
        const existing = await loadStrategyScores(user.uid);
        if (existing) {
          setStrategyScores({ loading: false, error: null, data: existing });
        }
      }
    }
    loadExistingScores();
  }, [user]);

  // Load existing patterns on mount
  useEffect(() => {
    async function loadExistingPatterns() {
      if (user) {
        const existing = await loadPatterns(user.uid);
        if (existing) {
          setPatterns({ loading: false, error: null, data: existing });
        }
      }
    }
    loadExistingPatterns();
  }, [user]);

  // Load existing chat history on mount
  useEffect(() => {
    async function loadExistingChat() {
      if (user) {
        const existing = await loadChatHistory(user.uid);
        if (existing && existing.length > 0) {
          setChatMessages(existing);
        }
      }
    }
    loadExistingChat();
  }, [user]);

  // Mindset field setters — scoped under journalEntries[dateKey].mindset
  const updateMindsetField = (dateKey, field, value) => {
    setJournalEntries(prev => ({
      ...prev,
      [dateKey]: {
        ...prev[dateKey],
        mindset: { ...(prev[dateKey]?.mindset || {}), [field]: value }
      }
    }));
  };
  const toggleMindsetChip = (dateKey, field, value) => {
    setJournalEntries(prev => {
      const current = prev[dateKey]?.mindset?.[field] || [];
      const next = current.includes(value) ? current.filter(v => v !== value) : [...current, value];
      return {
        ...prev,
        [dateKey]: {
          ...prev[dateKey],
          mindset: { ...(prev[dateKey]?.mindset || {}), [field]: next }
        }
      };
    });
  };

  // --- Trading Rules helpers ---
  const activeRules = tradingRules.filter(r => r.active !== false);

  const updateRuleCheckoff = (dateKey, ruleId, value) => {
    setJournalEntries(prev => {
      const entry = prev[dateKey] || {};
      const mindset = entry.mindset || {};
      const checkoffs = { ...(mindset.ruleCheckoffs || {}), [ruleId]: value };
      // Compute score
      const activeRuleIds = activeRules.map(r => r.id);
      const followed = activeRuleIds.filter(id => checkoffs[id] === true).length;
      const total = activeRuleIds.length;
      const ruleScore = total > 0 ? Math.round((followed / total) * 100) : null;
      const ruleAdherence = total > 0 ? Math.round((followed / total) * 10) : mindset.ruleAdherence;
      return {
        ...prev,
        [dateKey]: {
          ...entry,
          mindset: { ...mindset, ruleCheckoffs: checkoffs, ruleScore, ruleAdherence }
        }
      };
    });
  };

  const computeRuleScore = (checkoffs) => {
    if (!checkoffs || activeRules.length === 0) return null;
    const followed = activeRules.filter(r => checkoffs[r.id] === true).length;
    return { followed, total: activeRules.length, percent: Math.round((followed / activeRules.length) * 100) };
  };

  const addTradingRule = () => {
    const text = newRuleText.trim();
    if (!text) return;
    const newRule = {
      id: "r_" + Date.now(),
      text,
      category: newRuleCategory,
      order: tradingRules.length,
      active: true,
      createdAt: new Date().toISOString().split("T")[0]
    };
    const updated = [...tradingRules, newRule];
    setTradingRules(updated);
    saveTradingRulesToFirestore(user.uid, updated);
    setNewRuleText("");
  };

  const deleteTradingRule = (ruleId) => {
    const updated = tradingRules.filter(r => r.id !== ruleId);
    setTradingRules(updated);
    saveTradingRulesToFirestore(user.uid, updated);
  };

  const toggleRuleActive = (ruleId) => {
    const updated = tradingRules.map(r => r.id === ruleId ? { ...r, active: !r.active } : r);
    setTradingRules(updated);
    saveTradingRulesToFirestore(user.uid, updated);
  };

  const saveEditRule = (ruleId) => {
    const text = editingRuleText.trim();
    if (!text) return;
    const updated = tradingRules.map(r => r.id === ruleId ? { ...r, text } : r);
    setTradingRules(updated);
    saveTradingRulesToFirestore(user.uid, updated);
    setEditingRuleId(null);
    setEditingRuleText("");
  };

  const loadDefaultRules = () => {
    if (tradingRules.length > 0 && !confirm("This will replace your current rules with defaults. Continue?")) return;
    const defaults = DEFAULT_TRADING_RULES.map((r, i) => ({
      ...r,
      id: "r_" + (Date.now() + i),
      order: i,
      active: true,
      createdAt: new Date().toISOString().split("T")[0]
    }));
    setTradingRules(defaults);
    saveTradingRulesToFirestore(user.uid, defaults);
  };

  const calculateRuleAdherenceStreak = () => {
    const dates = Object.keys(journalEntries)
      .filter(d => {
        const checkoffs = journalEntries[d]?.mindset?.ruleCheckoffs;
        return checkoffs && Object.keys(checkoffs).length > 0;
      })
      .sort((a, b) => b.localeCompare(a)); // descending

    if (dates.length === 0) return { current: 0, best: 0 };

    // Current streak: walk backward from most recent
    let currentStreak = 0;
    for (const date of dates) {
      const checkoffs = journalEntries[date]?.mindset?.ruleCheckoffs || {};
      const ruleIds = activeRules.map(r => r.id);
      const allFollowed = ruleIds.length > 0 && ruleIds.every(id => checkoffs[id] === true);
      if (allFollowed) {
        currentStreak++;
      } else {
        break;
      }
    }

    // Best streak: walk forward through all dates
    let bestStreak = 0;
    let tempStreak = 0;
    const ascending = [...dates].reverse();
    for (const date of ascending) {
      const checkoffs = journalEntries[date]?.mindset?.ruleCheckoffs || {};
      const ruleIds = activeRules.map(r => r.id);
      const allFollowed = ruleIds.length > 0 && ruleIds.every(id => checkoffs[id] === true);
      if (allFollowed) {
        tempStreak++;
        bestStreak = Math.max(bestStreak, tempStreak);
      } else {
        tempStreak = 0;
      }
    }

    return { current: currentStreak, best: bestStreak };
  };

  // Manual save function for journal entries (now using IndexedDB)
  const saveJournalEntries = async () => {
    try {
      await saveJournalToDB(journalEntries);
      alert(`Journal saved to IndexedDB! ${Object.keys(journalEntries).length} date(s) saved.`);
    } catch (error) {
      console.error('Failed to save journal entries:', error);
      if (error.message && error.message.includes('quota')) {
        alert('Storage limit exceeded! Your journal has too much data.\n\nSolutions:\n1. Delete old journal entries\n2. Remove some images from entries\n3. Export your data and start fresh');
      } else {
        alert('Failed to save journal: ' + (error.message || 'Unknown error'));
      }
    }
  };

  // --- CSV Import state ---
  const [showImport, setShowImport] = useState(false);
  const [importDragOver, setImportDragOver] = useState(false);
  const [importResult, setImportResult] = useState(null); // { trades: [], error: null }
  const [importPreview, setImportPreview] = useState(null); // trades to preview before confirming
  const fileInputRef = useRef(null);

  // --- Delete state ---
  const [deleteConfirm, setDeleteConfirm] = useState(null); // trade id to delete

  // --- Edit strategy state ---
  const [editStrategyTrade, setEditStrategyTrade] = useState(null); // trade being edited
  const [editStrategyValue, setEditStrategyValue] = useState("");

  // --- Edit emotion state ---
  const [editEmotionTrade, setEditEmotionTrade] = useState(null); // trade being edited
  const [editEmotionValue, setEditEmotionValue] = useState("");

  // --- Edit mistake state ---
  const [editMistakeTrade, setEditMistakeTrade] = useState(null); // trade being edited
  const [editMistakeValue, setEditMistakeValue] = useState([]);

  // --- Notes editor state ---
  const [editNotesTrade, setEditNotesTrade] = useState(null); // trade being edited
  const [notesText, setNotesText] = useState("");
  const [notesImages, setNotesImages] = useState([]); // array of {id, dataUrl}
  const imageInputRef = useRef(null);
  const [dragOver, setDragOver] = useState(false);

  // --- Edit time state ---
  const [editTimeTrade, setEditTimeTrade] = useState(null); // trade being edited
  const [editEntryTime, setEditEntryTime] = useState("");
  const [editExitTime, setEditExitTime] = useState("");

  // --- Calendar date modal state ---
  const [selectedCalendarDate, setSelectedCalendarDate] = useState(null); // { date, trades }

  // --- Journal state ---
  const [journalEntries, setJournalEntries] = useState({});
  const [journalLoaded, setJournalLoaded] = useState(false);
  // Snapshot of last-saved journal entries so auto-save only writes changed dates
  const lastSavedJournalRef = useRef({});

  // Load journal entries from Firestore on mount
  useEffect(() => {
    async function loadJournal() {
      try {
        // First, try to load from Firestore
        let entries = await loadJournalFromFirestore(user.uid);

        // If Firestore is empty, check IndexedDB for migration
        if (Object.keys(entries).length === 0) {
          const indexedDBData = await loadJournalFromDB();
          if (Object.keys(indexedDBData).length > 0) {
            console.log('Migrating journal from IndexedDB to Firestore...');
            entries = indexedDBData;
          } else {
            // If IndexedDB is empty, check localStorage for migration
            const localStorageData = localStorage.getItem('tradingJournalEntries');
            if (localStorageData) {
              console.log('Migrating journal from localStorage to Firestore...');
              entries = JSON.parse(localStorageData);
              // Clear from localStorage to free up space
              localStorage.removeItem('tradingJournalEntries');
            }
          }

          // Save to Firestore if we found data to migrate
          if (Object.keys(entries).length > 0) {
            await saveJournalToFirestore(user.uid, entries);
            console.log('Journal migration to Firestore complete!');
          }
        }

        setJournalEntries(entries);
        // Seed the snapshot so auto-save only writes entries that change AFTER load
        lastSavedJournalRef.current = { ...entries };
        setJournalLoaded(true);
      } catch (error) {
        console.error('Failed to load journal entries:', error);
        setJournalLoaded(true);
      }
    }

    loadJournal();
  }, [user.uid]);

  // Load trading rules from Firestore on mount
  useEffect(() => {
    async function loadRules() {
      const rules = await loadTradingRulesFromFirestore(user.uid);
      setTradingRules(rules);
      setTradingRulesLoaded(true);
    }
    loadRules();
  }, [user.uid]);

  // Auto-save journal entries to Firestore whenever they change (debounced, diff-only)
  useEffect(() => {
    if (!journalLoaded || Object.keys(journalEntries).length === 0) return;

    const timeoutId = setTimeout(() => {
      // Diff against last-saved snapshot — only write dates that actually changed
      const last = lastSavedJournalRef.current || {};
      const changed = {};
      for (const [dateKey, entry] of Object.entries(journalEntries)) {
        if (last[dateKey] !== entry) changed[dateKey] = entry;
      }
      const changedCount = Object.keys(changed).length;
      if (changedCount === 0) return;

      console.log(`Auto-saving journal to Firestore... ${changedCount} changed date(s)`);
      saveJournalToFirestore(user.uid, changed)
        .then(() => {
          // Capture the snapshot of what we just saved so the next diff is accurate
          lastSavedJournalRef.current = { ...journalEntries };
          console.log('✅ Journal auto-saved successfully to Firestore');
        })
        .catch(error => {
          console.error('❌ Auto-save journal to Firestore failed:', error);
        });
    }, 2000);

    return () => clearTimeout(timeoutId);
  }, [journalEntries, journalLoaded, user.uid]);

  const [selectedJournalDate, setSelectedJournalDate] = useState(() => {
    const today = new Date();
    return `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`;
  });
  const [journalDragOver, setJournalDragOver] = useState(false);
  const [previewImage, setPreviewImage] = useState(null); // { dataUrl, name }
  const [journalHistoryExpanded, setJournalHistoryExpanded] = useState(false);
  const [attachVideoTrade, setAttachVideoTrade] = useState(null); // trade to attach video to

  function handleCsvFile(file) {
    if (!file) return;
    const reader = new FileReader();
    reader.onload = (e) => {
      const result = parseTradovateCsv(e.target.result);
      if (result.error) {
        setImportResult({ count: 0, error: result.error });
        setImportPreview(null);
      } else if (result.trades.length === 0) {
        setImportResult({ count: 0, error: "No completed round-trip trades found in file." });
        setImportPreview(null);
      } else {
        setImportPreview(result.trades);
        setImportResult(null);
      }
    };
    reader.readAsText(file);
  }

  function confirmImport() {
    if (!importPreview) return;
    setTrades(prev => [...importPreview, ...prev].sort((a, b) => new Date(b.date) - new Date(a.date)));
    setImportResult({ count: importPreview.length, error: null });
    setImportPreview(null);
  }

  const totalPnl = trades.reduce((s, t) => s + t.pnl, 0);
  const winners = trades.filter(t => t.pnl > 0);
  const losers = trades.filter(t => t.pnl < 0);
  const winRate = trades.length ? Math.round((winners.length / trades.length) * 100) : 0;
  const avgWin = winners.length ? winners.reduce((s, t) => s + t.pnl, 0) / winners.length : 0;
  const avgLoss = losers.length ? Math.abs(losers.reduce((s, t) => s + t.pnl, 0) / losers.length) : 1;
  const profitFactor = losers.length ? ((avgWin * winners.length) / (avgLoss * losers.length)).toFixed(2) : "\u221e";
  const maxDD = (() => { let peak = 0, mdd = 0, run = 0; trades.slice().reverse().forEach(t => { run += t.pnl; if (run > peak) peak = run; const d = peak - run; if (d > mdd) mdd = d; }); return mdd; })();

  const filtered = trades.filter(t => {
    if (filterSession !== "All" && t.session !== filterSession) return false;
    if (filterStrategy !== "All" && t.strategy !== filterStrategy) return false;
    if (filterDirection !== "All" && t.direction !== filterDirection) return false;
    if (filterOutcome === "Winners" && t.pnl <= 0) return false;
    if (filterOutcome === "Losers" && t.pnl >= 0) return false;
    if (filterDateFrom && t.date < filterDateFrom) return false;
    if (filterDateTo && t.date > filterDateTo) return false;
    return true;
  });
  const isFiltered = filterSession !== "All" || filterStrategy !== "All" || filterDirection !== "All" || filterOutcome !== "All" || filterDateFrom || filterDateTo;

  // Group trades by week
  const getWeekKey = (dateStr) => {
    const date = new Date(dateStr);
    const startOfYear = new Date(date.getFullYear(), 0, 1);
    const days = Math.floor((date - startOfYear) / (24 * 60 * 60 * 1000));
    const weekNum = Math.ceil((days + startOfYear.getDay() + 1) / 7);
    return `${date.getFullYear()}-W${weekNum}`;
  };

  const getWeekRange = (weekKey) => {
    const [year, weekPart] = weekKey.split('-W');
    const weekNum = parseInt(weekPart);
    const jan1 = new Date(year, 0, 1);
    const daysToMonday = (jan1.getDay() === 0 ? -6 : 1) - jan1.getDay();
    const firstMonday = new Date(year, 0, 1 + daysToMonday);
    const weekStart = new Date(firstMonday.getTime() + (weekNum - 1) * 7 * 24 * 60 * 60 * 1000);
    const weekEnd = new Date(weekStart.getTime() + 6 * 24 * 60 * 60 * 1000);

    const formatDate = (d) => d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
    return `${formatDate(weekStart)} - ${formatDate(weekEnd)}`;
  };

  const isCurrentWeek = (weekKey) => {
    const now = new Date();
    return getWeekKey(now.toISOString().split('T')[0]) === weekKey;
  };

  const groupedByWeek = filtered.reduce((acc, trade) => {
    const weekKey = getWeekKey(trade.date);
    if (!acc[weekKey]) {
      acc[weekKey] = [];
    }
    acc[weekKey].push(trade);
    return acc;
  }, {});

  // Sort weeks by most recent first
  const sortedWeeks = Object.keys(groupedByWeek).sort((a, b) => b.localeCompare(a));

  // Auto-expand current week by default
  if (sortedWeeks.length > 0 && !Object.keys(expandedWeeks).length) {
    const currentWeek = sortedWeeks.find(w => isCurrentWeek(w));
    if (currentWeek && !expandedWeeks[currentWeek]) {
      setExpandedWeeks({ [currentWeek]: true });
    }
  }

  // Calculate chart trades based on timeframe
  const chartTrades = (() => {
    if (chartTimeframe === "All Time") return trades;

    // Create a new date and calculate local time without timezone shifts
    const today = new Date();
    const estDateString = today.toLocaleString("en-US", { timeZone: "America/New_York" });
    const now = new Date(estDateString);
    now.setHours(0, 0, 0, 0);

    let startDate = new Date(now);
    if (chartTimeframe === "This Week") {
      // Get Monday of current week
      const day = startDate.getDay();
      const diff = startDate.getDate() - day + (day === 0 ? -6 : 1);
      startDate.setDate(diff);
    } else if (chartTimeframe === "This Month") {
      startDate.setDate(1);
    }

    return trades.filter(t => {
      // Interpret trade date as local
      if (!t.date || typeof t.date !== 'string') return false;
      const parts = t.date.split("T")[0].split(" ")[0].split("-");
      if (parts.length < 3) return false;

      const [y, m, d] = parts;
      const tradeDate = new Date(y, m - 1, d);
      return tradeDate >= startDate;
    });
  })();

  // Calculate daily P&L grouped by date
  const dailyPnl = (() => {
    const byDate = {};
    chartTrades.forEach(t => {
      const date = t.date;
      if (!byDate[date]) {
        byDate[date] = { date, pnl: 0 };
      }
      byDate[date].pnl += t.pnl;
    });
    // Sort by date (oldest to newest)
    return Object.values(byDate).sort((a, b) => new Date(a.date) - new Date(b.date));
  })();

  // Calculate cumulative P&L
  const cumulativePnl = (() => {
    let cumulative = 0;
    return dailyPnl.map(d => {
      cumulative += d.pnl;
      return { date: d.date, cumPnl: cumulative };
    });
  })();
  
  // Guard against empty arrays returning -Infinity
  const maxDailyPnl = dailyPnl.length > 0 ? Math.max(...dailyPnl.map(d => Math.abs(d.pnl)), 1) : 1;
  const maxCumPnl = cumulativePnl.length > 0 ? Math.max(...cumulativePnl.map(d => Math.abs(d.cumPnl)), 1) : 1;

  const previewPnl = form.entry && form.exit && form.size ? calcPnl({ ...form, entry: +form.entry, exit: +form.exit, size: +form.size }) : null;

  function handleSubmit() {
    if (!form.entry || !form.exit || !form.size) return;
    const t = { ...form, id: Date.now(), entry: +form.entry, exit: +form.exit, size: +form.size, ticker: form.market, source: "manual" };
    t.pnl = calcPnl(t);
    setTrades(p => [t, ...p]);
    setForm({ date: new Date().toISOString().split("T")[0], ticker: "", market: "ES", direction: "Long", entry: "", exit: "", entryTime: "", exitTime: "", size: "1", strategy: "Opening Range", emotion: "Calm", session: "RTH Open", notes: "" });
    setShowForm(false);
  }

  function calcDurationMinutes(entryTime, exitTime) {
    if (!entryTime || !exitTime) return null;
    const toSeconds = t => { const p = t.split(':').map(Number); return p[0] * 3600 + p[1] * 60 + (p[2] || 0); };
    const diff = toSeconds(exitTime) - toSeconds(entryTime);
    return diff > 0 ? parseFloat((diff / 60).toFixed(1)) : null;
  }

  function buildDurationStats(tradesArr) {
    const withDur = tradesArr.map(t => ({ ...t, duration: calcDurationMinutes(t.entryTime, t.exitTime) })).filter(t => t.duration !== null);
    if (withDur.length === 0) return null;
    const avg = arr => arr.length ? (arr.reduce((s, t) => s + t.duration, 0) / arr.length).toFixed(1) : "N/A";
    const winners = withDur.filter(t => t.pnl > 0);
    const losers = withDur.filter(t => t.pnl < 0);
    const byStrategy = {};
    withDur.forEach(t => { if (!byStrategy[t.strategy]) byStrategy[t.strategy] = []; byStrategy[t.strategy].push(t.duration); });
    const stratDur = Object.entries(byStrategy).map(([name, durs]) => ({ name, avgMins: (durs.reduce((s, d) => s + d, 0) / durs.length).toFixed(1) })).sort((a, b) => b.avgMins - a.avgMins);
    const byHour = {};
    withDur.forEach(t => { if (!t.entryTime) return; const h = parseInt(t.entryTime.split(':')[0]); if (!byHour[h]) byHour[h] = { pnl: 0, count: 0 }; byHour[h].pnl += t.pnl; byHour[h].count++; });
    const hourPerf = Object.entries(byHour).map(([h, v]) => ({ hour: `${h}:00`, avgPnL: (v.pnl / v.count).toFixed(0), count: v.count })).sort((a, b) => b.avgPnL - a.avgPnL);
    return { avgAll: avg(withDur), avgWinners: avg(winners), avgLosers: avg(losers), longest: Math.max(...withDur.map(t => t.duration)).toFixed(1), shortest: Math.min(...withDur.map(t => t.duration)).toFixed(1), stratDur, hourPerf, tradesWithData: withDur.length };
  }

  // Aggregates mindset entries in [startDate, endDate] and joins per-day P&L from tradesArr.
  // startDate/endDate are Date objects. Returns null if no mindset entries in range.
  function buildMindsetStats(entriesObj, tradesArr, startDate, endDate) {
    if (!entriesObj || !startDate || !endDate) return null;
    const startMs = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate()).getTime();
    const endMs = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate(), 23, 59, 59).getTime();
    const rows = [];
    for (const [dateKey, entry] of Object.entries(entriesObj)) {
      const m = entry?.mindset;
      if (!m) continue;
      const parts = dateKey.split('-').map(Number);
      if (parts.length !== 3 || parts.some(isNaN)) continue;
      const ts = new Date(parts[0], parts[1] - 1, parts[2]).getTime();
      if (ts < startMs || ts > endMs) continue;
      const hasData =
        [m.sleepHours, m.stress, m.prepQuality, m.energy, m.ruleAdherence, m.dayRating].some(v => v != null && v !== "") ||
        (Array.isArray(m.mood) && m.mood.length > 0) ||
        (Array.isArray(m.disciplineTags) && m.disciplineTags.length > 0);
      if (!hasData) continue;
      rows.push({ dateKey, ...m });
    }
    if (rows.length === 0) return null;

    const avg = (field) => {
      const nums = rows.map(r => r[field]).filter(v => v != null && v !== "").map(Number).filter(v => !isNaN(v));
      return nums.length ? (nums.reduce((s, v) => s + v, 0) / nums.length).toFixed(1) : null;
    };
    const tally = (field) => {
      const counts = {};
      rows.forEach(r => (r[field] || []).forEach(v => { counts[v] = (counts[v] || 0) + 1; }));
      return Object.entries(counts).sort((a, b) => b[1] - a[1]).map(([value, count]) => ({ value, count }));
    };

    // Per-day detail with P&L joined from trades
    const pnlByDate = {};
    (tradesArr || []).forEach(t => { if (t.date) pnlByDate[t.date] = (pnlByDate[t.date] || 0) + (Number(t.pnl) || 0); });
    const daily = rows
      .sort((a, b) => a.dateKey.localeCompare(b.dateKey))
      .map(r => ({
        date: r.dateKey,
        sleep: r.sleepHours ?? null,
        stress: r.stress ?? null,
        mood: (r.mood || []).join('/') || null,
        pnl: pnlByDate[r.dateKey] != null ? Math.round(pnlByDate[r.dateKey]) : null
      }));

    // Rule adherence breakdown
    let ruleBreakdown = null;
    if (activeRules.length > 0) {
      const ruleCounts = {};
      let daysWithRules = 0;
      let perfectDays = [];
      rows.forEach(r => {
        const checkoffs = r.ruleCheckoffs;
        if (!checkoffs || Object.keys(checkoffs).length === 0) return;
        daysWithRules++;
        const allFollowed = activeRules.every(rule => checkoffs[rule.id] === true);
        if (allFollowed) perfectDays.push(r.dateKey);
        activeRules.forEach(rule => {
          if (!ruleCounts[rule.id]) ruleCounts[rule.id] = { text: rule.text, category: rule.category, followed: 0, broken: 0 };
          if (checkoffs[rule.id] === true) {
            ruleCounts[rule.id].followed++;
          } else {
            ruleCounts[rule.id].broken++;
          }
        });
      });

      if (daysWithRules > 0) {
        const perRule = Object.values(ruleCounts)
          .map(r => ({ ...r, complianceRate: Math.round((r.followed / (r.followed + r.broken)) * 100) }))
          .sort((a, b) => a.complianceRate - b.complianceRate);
        const mostBroken = perRule.filter(r => r.broken > 0).slice(0, 3);
        const avgScore = rows
          .filter(r => r.ruleScore != null)
          .reduce((sum, r, _, arr) => sum + r.ruleScore / arr.length, 0);

        // Per-day rule adherence with P&L
        const dailyRules = rows
          .filter(r => r.ruleCheckoffs && Object.keys(r.ruleCheckoffs).length > 0)
          .sort((a, b) => a.dateKey.localeCompare(b.dateKey))
          .map(r => {
            const followed = activeRules.filter(rule => r.ruleCheckoffs[rule.id] === true).length;
            const broken = activeRules.filter(rule => r.ruleCheckoffs[rule.id] !== true).map(rule => rule.text);
            return {
              date: r.dateKey,
              followed,
              total: activeRules.length,
              score: r.ruleScore,
              pnl: pnlByDate[r.dateKey] != null ? Math.round(pnlByDate[r.dateKey]) : null,
              brokenRules: broken
            };
          });

        ruleBreakdown = {
          daysWithRules,
          perfectDays,
          avgScore: Math.round(avgScore),
          mostBroken,
          perRule,
          dailyRules
        };
      }
    }

    return {
      entriesCount: rows.length,
      avgSleep: avg('sleepHours'),
      avgStress: avg('stress'),
      avgPrep: avg('prepQuality'),
      avgEnergy: avg('energy'),
      avgRuleAdherence: avg('ruleAdherence'),
      avgDayRating: avg('dayRating'),
      topMoods: tally('mood').slice(0, 3),
      topDisciplineTags: tally('disciplineTags').slice(0, 3),
      daily,
      ruleBreakdown
    };
  }

  async function runAnalysis() {
    if (!apiKey) {
      setAiError("Please enter your Anthropic API key above.");
      return;
    }
    setAiLoading(true); setAiReport(""); setAiError("");
    const summary = trades.map(t => `${t.date}|${t.ticker}|${t.direction}|E:${t.entry} X:${t.exit} ${t.size}ct|$${t.pnl}|${t.strategy}|${t.emotion}|${t.session}|${t.notes}`).join("\n");
    const durStats = buildDurationStats(trades);
    const durSection = durStats ? `\nHOLD TIME ANALYSIS (${durStats.tradesWithData} trades with timing data):
- Avg hold time: ${durStats.avgAll} min | Winners: ${durStats.avgWinners} min | Losers: ${durStats.avgLosers} min
- Range: ${durStats.shortest} min (shortest) to ${durStats.longest} min (longest)
- By strategy: ${durStats.stratDur.map(s => `${s.name} ${s.avgMins}min`).join(', ')}
- Best hours by avg P&L: ${durStats.hourPerf.slice(0, 3).map(h => `${h.hour} ($${h.avgPnL}/trade)`).join(', ')}` : "";
    try {
      const res = await fetch("https://api.anthropic.com/v1/messages", { method: "POST", headers: { "Content-Type": "application/json", "x-api-key": apiKey, "anthropic-version": "2023-06-01" }, body: JSON.stringify({ model: "claude-sonnet-4-20250514", max_tokens: 1200, messages: [{ role: "user", content: `You are an elite futures trading coach. Analyze this trader's journal:\n\n${summary}${durSection}\n\nProvide:\n1. **Edge Assessment** \u2014 where is the real edge and why?\n2. **Psychological Patterns** \u2014 what emotional tendencies are costing them money? Be specific and direct.\n3. **Session & Timing** \u2014 which sessions/hours show best vs worst performance? Are losers held longer than winners?\n4. **Risk Management** \u2014 position sizing and stop discipline assessment\n5. **Top 3 Action Items** \u2014 specific changes to implement next week\n\nBe sharp and direct. Use futures terminology. Under 500 words.` }] }) });
      const data = await res.json();
      if (data.error) {
        setAiError(`API Error: ${data.error.message || "Unknown error"}`);
      } else {
        setAiReport(data.content?.map(b => b.text || "").join("") || "No response.");
      }
    } catch (err) { setAiError("Failed to reach AI. Check your API key and try again."); }
    setAiLoading(false);
  }

  async function analyzeOne(trade) {
    if (!apiKey) {
      setTradeAi(p => ({ ...p, [trade.id]: { loading: false, text: "Please enter your Anthropic API key in the Lyra tab." } }));
      return;
    }
    setTradeAi(p => ({ ...p, [trade.id]: { loading: true, text: "" } }));
    try {
      const res = await fetch("https://api.anthropic.com/v1/messages", { method: "POST", headers: { "Content-Type": "application/json", "x-api-key": apiKey, "anthropic-version": "2023-06-01" }, body: JSON.stringify({ model: "claude-sonnet-4-20250514", max_tokens: 1000, messages: [{ role: "user", content: `Analyze this futures trade as a coach:\n\n${trade.ticker} | ${trade.direction} | Entry: ${trade.entry} Exit: ${trade.exit} | ${trade.size} contracts | P&L: $${trade.pnl}\nStrategy: ${trade.strategy} | Session: ${trade.session} | Emotion: ${trade.emotion}\nNotes: ${trade.notes}\n\nGive: (1) Execution quality \u2014 was entry/exit well-timed for this setup? (2) How did their emotional state (${trade.emotion}) affect this trade? (3) One specific improvement. Use futures terminology. 3 concise paragraphs.` }] }) });
      const data = await res.json();
      if (data.error) {
        setTradeAi(p => ({ ...p, [trade.id]: { loading: false, text: `API Error: ${data.error.message || "Unknown error"}` } }));
      } else {
        setTradeAi(p => ({ ...p, [trade.id]: { loading: false, text: data.content?.map(b => b.text || "").join("") || "No response." } }));
      }
    } catch { setTradeAi(p => ({ ...p, [trade.id]: { loading: false, text: "Analysis failed. Check your API key." } })); }
  }

  async function analyzeWeekly(startDate, endDate) {
    if (!apiKey) {
      setWeeklyAnalysis({ loading: false, error: "Please enter your Anthropic API key in the Lyra tab.", data: null });
      return;
    }

    setWeeklyAnalysis({ loading: true, error: null, data: null });

    try {
      // Fetch previous week's review from Firestore for comparison
      const prevStart = new Date(startDate);
      prevStart.setDate(prevStart.getDate() - 7);
      const prevEnd = new Date(endDate);
      prevEnd.setDate(prevEnd.getDate() - 7);

      let prevWeekReview = null;
      let prevWeekTrades = [];
      if (user) {
        prevWeekReview = await loadLyraReviewFromFirestore(user.uid, prevStart, prevEnd);
        prevWeekTrades = trades.filter(t => {
          const td = new Date(t.date);
          return td >= prevStart && td <= prevEnd;
        });
      }

      // Filter trades for the date range
      const weekTrades = trades.filter(t => {
        const tradeDate = new Date(t.date);
        return tradeDate >= startDate && tradeDate <= endDate;
      });

      if (weekTrades.length === 0) {
        setWeeklyAnalysis({ loading: false, error: "No trades found in this date range.", data: null });
        return;
      }

      // Calculate stats
      const winners = weekTrades.filter(t => t.pnl > 0);
      const losers = weekTrades.filter(t => t.pnl < 0);
      const totalPnL = weekTrades.reduce((sum, t) => sum + t.pnl, 0);
      const winRate = (winners.length / weekTrades.length * 100).toFixed(1);
      const avgWin = winners.length > 0 ? (winners.reduce((sum, t) => sum + t.pnl, 0) / winners.length).toFixed(2) : 0;
      const avgLoss = losers.length > 0 ? (losers.reduce((sum, t) => sum + t.pnl, 0) / losers.length).toFixed(2) : 0;

      // Group by strategy, emotion, session
      const strategyBreakdown = {};
      const emotionBreakdown = {};
      const sessionBreakdown = {};

      weekTrades.forEach(t => {
        if (!strategyBreakdown[t.strategy]) strategyBreakdown[t.strategy] = { count: 0, pnl: 0, wins: 0 };
        strategyBreakdown[t.strategy].count++;
        strategyBreakdown[t.strategy].pnl += t.pnl;
        if (t.pnl > 0) strategyBreakdown[t.strategy].wins++;

        if (!emotionBreakdown[t.emotion]) emotionBreakdown[t.emotion] = { count: 0, pnl: 0, wins: 0 };
        emotionBreakdown[t.emotion].count++;
        emotionBreakdown[t.emotion].pnl += t.pnl;
        if (t.pnl > 0) emotionBreakdown[t.emotion].wins++;

        if (!sessionBreakdown[t.session]) sessionBreakdown[t.session] = { count: 0, pnl: 0, wins: 0 };
        sessionBreakdown[t.session].count++;
        sessionBreakdown[t.session].pnl += t.pnl;
        if (t.pnl > 0) sessionBreakdown[t.session].wins++;
      });

      // Build prompt with all trade data
      const tradesData = weekTrades.map(t =>
        `${t.date} | ${t.ticker} ${t.direction} | Entry: ${t.entry} Exit: ${t.exit} | P&L: $${t.pnl} | Strategy: ${t.strategy} | Emotion: ${t.emotion} | Session: ${t.session}${t.notes ? ` | Notes: ${t.notes}` : ''}`
      ).join('\n');

      const weekDurStats = buildDurationStats(weekTrades);
      const weekDurSection = weekDurStats ? `

HOLD TIME ANALYSIS (${weekDurStats.tradesWithData} trades with timing data):
- Avg hold time: ${weekDurStats.avgAll} min | Winners: ${weekDurStats.avgWinners} min | Losers: ${weekDurStats.avgLosers} min
- Range: ${weekDurStats.shortest} min (shortest) to ${weekDurStats.longest} min (longest)
- By strategy: ${weekDurStats.stratDur.map(s => `${s.name} ${s.avgMins}min`).join(', ')}
- Best hours by avg P&L: ${weekDurStats.hourPerf.slice(0, 3).map(h => `${h.hour} ($${h.avgPnL}/trade, ${h.count} trades)`).join(', ')}` : "";

      // Mindset aggregation (optional — only if user has logged any journal check-ins this week)
      const weekMindset = buildMindsetStats(journalEntries, weekTrades, startDate, endDate);
      const weekRuleSection = weekMindset?.ruleBreakdown ? `

RULE ADHERENCE THIS WEEK:
- Overall: ${weekMindset.ruleBreakdown.avgScore}% avg adherence across ${weekMindset.ruleBreakdown.daysWithRules} day(s)
- Perfect adherence days: ${weekMindset.ruleBreakdown.perfectDays.length > 0 ? weekMindset.ruleBreakdown.perfectDays.join(', ') : 'none'}
${weekMindset.ruleBreakdown.mostBroken.length > 0 ? `- Most broken rules: ${weekMindset.ruleBreakdown.mostBroken.map(r => `"${r.text}" (broken ${r.broken} day${r.broken !== 1 ? 's' : ''}, ${r.complianceRate}% compliance)`).join(', ')}` : '- No rules were broken this week'}
- Per-day: ${weekMindset.ruleBreakdown.dailyRules.map(d => `${d.date} ${d.followed}/${d.total} rules${d.brokenRules.length > 0 ? ` (broke: ${d.brokenRules.join(', ')})` : ''} pnl $${d.pnl ?? 'n/a'}`).join(' | ')}` : "";

      const weekMindsetSection = weekMindset ? `

MINDSET DATA THIS WEEK (${weekMindset.entriesCount} day${weekMindset.entriesCount === 1 ? '' : 's'} logged):
- Averages:${weekMindset.avgSleep ? ` sleep ${weekMindset.avgSleep}h |` : ''}${weekMindset.avgStress ? ` stress ${weekMindset.avgStress}/10 |` : ''}${weekMindset.avgPrep ? ` prep ${weekMindset.avgPrep}/10 |` : ''}${weekMindset.avgEnergy ? ` energy ${weekMindset.avgEnergy}/10 |` : ''}${weekMindset.avgRuleAdherence ? ` rule adherence ${weekMindset.avgRuleAdherence}/10 |` : ''}${weekMindset.avgDayRating ? ` day rating ${weekMindset.avgDayRating}/10` : ''}
${weekMindset.topMoods.length > 0 ? `- Top moods: ${weekMindset.topMoods.map(m => `${m.value} (${m.count})`).join(', ')}` : ''}
${weekMindset.topDisciplineTags.length > 0 ? `- Discipline tags: ${weekMindset.topDisciplineTags.map(t => `${t.value} (${t.count})`).join(', ')}` : ''}
- Daily: ${weekMindset.daily.map(d => `${d.date}${d.sleep != null ? ` sleep ${d.sleep}h` : ''}${d.stress != null ? ` stress ${d.stress}` : ''}${d.mood ? ` mood ${d.mood}` : ''}${d.pnl != null ? ` pnl $${d.pnl}` : ''}`).join(' | ')}${weekRuleSection}` : "";

      // Build previous week context for comparison
      let prevWeekSection = "";
      if (prevWeekReview && prevWeekReview.stats) {
        const ps = prevWeekReview.stats;
        const prevTradesData = prevWeekTrades.map(t =>
          `${t.date} | ${t.ticker} ${t.direction} | P&L: $${t.pnl} | Strategy: ${t.strategy} | Emotion: ${t.emotion} | Session: ${t.session}`
        ).join('\n');
        prevWeekSection = `

PREVIOUS WEEK DATA (for comparison):
- Total Trades: ${ps.totalTrades}
- Winners: ${ps.winners} | Losers: ${ps.losers}
- Win Rate: ${ps.winRate}%
- Total P&L: $${ps.totalPnL.toFixed(2)}
- Avg Win: $${ps.avgWin} | Avg Loss: $${ps.avgLoss}

PREVIOUS WEEK STRATEGY BREAKDOWN:
${ps.strategyBreakdown ? Object.entries(ps.strategyBreakdown).map(([strategy, stats]) =>
  `${strategy}: ${stats.count} trades, ${(stats.wins/stats.count*100).toFixed(0)}% win rate, $${stats.pnl.toFixed(2)} P&L`
).join('\n') : 'N/A'}

PREVIOUS WEEK EMOTION BREAKDOWN:
${ps.emotionBreakdown ? Object.entries(ps.emotionBreakdown).map(([emotion, stats]) =>
  `${emotion}: ${stats.count} trades, ${(stats.wins/stats.count*100).toFixed(0)}% win rate, $${stats.pnl.toFixed(2)} P&L`
).join('\n') : 'N/A'}

PREVIOUS WEEK TRADES:
${prevTradesData || 'N/A'}

PREVIOUS WEEK LYRA REVIEW:
${prevWeekReview.analysis}`;
      }

      const prompt = `You are an expert futures trading coach. Analyze this week's trading performance and provide comprehensive insights.

THIS WEEK'S STATS:
- Total Trades: ${weekTrades.length}
- Winners: ${winners.length} | Losers: ${losers.length}
- Win Rate: ${winRate}%
- Total P&L: $${totalPnL.toFixed(2)}
- Avg Win: $${avgWin} | Avg Loss: $${avgLoss}

STRATEGY BREAKDOWN:
${Object.entries(strategyBreakdown).map(([strategy, stats]) =>
  `${strategy}: ${stats.count} trades, ${(stats.wins/stats.count*100).toFixed(0)}% win rate, $${stats.pnl.toFixed(2)} P&L`
).join('\n')}

EMOTIONAL STATE BREAKDOWN:
${Object.entries(emotionBreakdown).map(([emotion, stats]) =>
  `${emotion}: ${stats.count} trades, ${(stats.wins/stats.count*100).toFixed(0)}% win rate, $${stats.pnl.toFixed(2)} P&L`
).join('\n')}

SESSION BREAKDOWN:
${Object.entries(sessionBreakdown).map(([session, stats]) =>
  `${session}: ${stats.count} trades, ${(stats.wins/stats.count*100).toFixed(0)}% win rate, $${stats.pnl.toFixed(2)} P&L`
).join('\n')}${weekDurSection}${weekMindsetSection}

ALL TRADES THIS WEEK:
${tradesData}${prevWeekSection}

Provide a comprehensive weekly review in ${prevWeekSection ? "6" : "5"} sections:

1. **PERFORMANCE SUMMARY**: Overall assessment of the week's trading results and key metrics.

2. **PATTERN RECOGNITION**: Identify 2-3 patterns you notice (good and bad). What strategies/emotions/sessions are working? What's not? Be specific with data.

3. **STRENGTHS**: What did they do well this week? Highlight 2-3 specific examples from the trades.

4. **AREAS FOR IMPROVEMENT**: What needs work? Be honest and specific. Reference actual trades. If hold time data is available, note whether losers are being held longer than winners or vice versa, and flag any problematic hour-of-day patterns.

5. **ACTION ITEMS**: Give 3-5 concrete, actionable steps for next week to improve performance.${prevWeekSection ? `

6. **WEEK-OVER-WEEK COMPARISON**: Compare this week's performance against last week. Highlight key differences and similarities between the two weeks. Cover:
   - P&L and win rate changes (improved or declined, and by how much)
   - Strategy shifts (did they lean into different strategies? Did the same strategies perform differently?)
   - Emotional state changes (are they trading with better or worse psychology this week?)
   - Whether last week's action items were addressed or repeated mistakes persisted
   - Any emerging multi-week trends (positive habits forming, or recurring problems solidifying)
   Be specific with numbers when comparing. Call out both progress and regression.` : ""}

Use futures trading terminology. Be direct and coaching-focused. Keep each section to 2-3 paragraphs max.${weekMindsetSection ? " If mindset data is present above, explicitly call out any correlations you observe between mindset metrics (sleep, stress, mood, rule adherence) and P&L outcomes — for example, did low-sleep days produce worse results, or did 'Revenge traded' days cost money?" : ""}${weekRuleSection ? " IMPORTANT: Rule adherence data is included above. Dedicate a section of your analysis to RULE ADHERENCE — specifically: which rules were most commonly broken, what was the P&L impact on days rules were broken vs followed, and whether there are patterns in which rules get broken together. Be specific about dollar amounts." : ""}`;

      // Call Vercel serverless function to proxy Anthropic API
      console.log('Calling Vercel API proxy...');
      const res = await fetch('https://ultratrack-pi.vercel.app/api/analyze', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          prompt: prompt,
          apiKey: apiKey
        })
      });

      console.log('Vercel API response status:', res.status);
      const data = await res.json();
      console.log('Vercel API response data:', data);

      if (!res.ok || data.error) {
        const errorMsg = data.error || data.details?.message || `HTTP ${res.status} error`;
        console.error('API Error:', errorMsg);
        setWeeklyAnalysis({ loading: false, error: `API Error: ${errorMsg}`, data: null });
      } else {
        const analysisText = data.content?.map(b => b.text || "").join("") || "No response.";
        console.log('Analysis complete, text length:', analysisText.length);

        const analysisData = {
          analysis: analysisText,
          stats: {
            totalTrades: weekTrades.length,
            winners: winners.length,
            losers: losers.length,
            winRate: parseFloat(winRate),
            totalPnL: totalPnL,
            avgWin: parseFloat(avgWin),
            avgLoss: parseFloat(avgLoss),
            strategyBreakdown,
            emotionBreakdown,
            sessionBreakdown
          },
          dateRange: { start: startDate, end: endDate }
        };

        setWeeklyAnalysis({
          loading: false,
          error: null,
          data: analysisData
        });

        // Save the analysis to Firestore
        console.log('💾 Attempting to save Lyra review...', { hasUser: !!user, startDate, endDate });
        if (user) {
          await saveLyraReviewToFirestore(user.uid, startDate, endDate, analysisData);
          console.log('✅ Save complete!');
        } else {
          console.warn('⚠️ No user found, cannot save review');
        }
      }
    } catch (error) {
      console.error('Weekly analysis failed:', error);
      console.error('Error details:', error.message, error.stack);
      setWeeklyAnalysis({ loading: false, error: `Error: ${error.message || "Unknown error. Check console for details."}`, data: null });
    }
  }

  async function saveLyraReviewToFirestore(userId, startDate, endDate, analysisData) {
    try {
      const weekKey = `${startDate.toISOString().split('T')[0]}_${endDate.toISOString().split('T')[0]}`;

      await db.collection('users').doc(userId).collection('lyraReviews').doc(weekKey).set({
        ...analysisData,
        dateRange: {
          start: firebase.firestore.Timestamp.fromDate(startDate),
          end: firebase.firestore.Timestamp.fromDate(endDate)
        },
        createdAt: firebase.firestore.FieldValue.serverTimestamp(),
        updatedAt: firebase.firestore.FieldValue.serverTimestamp()
      });

      console.log('✅ Lyra review saved to Firestore for week:', weekKey);
    } catch (error) {
      console.error('Failed to save Lyra review:', error);
    }
  }

  async function loadLyraReviewFromFirestore(userId, startDate, endDate) {
    try {
      const weekKey = `${startDate.toISOString().split('T')[0]}_${endDate.toISOString().split('T')[0]}`;

      const doc = await db.collection('users').doc(userId).collection('lyraReviews').doc(weekKey).get();

      if (doc.exists) {
        const data = doc.data();
        console.log('✅ Loaded existing Lyra review for week:', weekKey);

        return {
          analysis: data.analysis,
          stats: data.stats,
          dateRange: {
            start: data.dateRange.start.toDate(),
            end: data.dateRange.end.toDate()
          }
        };
      }

      return null;
    } catch (error) {
      console.error('Failed to load Lyra review:', error);
      return null;
    }
  }

  function downloadLyraReviewPDF(analysisData, weekStart, weekEnd) {
    const { jsPDF } = window.jspdf;
    const doc = new jsPDF({ orientation: "portrait", unit: "mm", format: "a4" });
    const pageW = doc.internal.pageSize.getWidth();
    const pageH = doc.internal.pageSize.getHeight();
    const margin = 20;
    const contentW = pageW - margin * 2;
    const footerY = pageH - 12;
    const lineH = 5;

    const startStr = weekStart.toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' });
    const endStr = weekEnd.toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' });
    const stats = analysisData.stats;

    // Helper: add new page with dark background
    function newPage() {
      doc.addPage();
      doc.setFillColor(15, 15, 20);
      doc.rect(0, 0, pageW, pageH, 'F');
      return margin + 4;
    }

    // Helper: check page overflow, returns updated y
    function checkPage(currentY, needed) {
      if (currentY + needed > footerY) {
        return newPage();
      }
      return currentY;
    }

    // ============ PAGE 1 — COVER HEADER ============
    // Full dark background
    doc.setFillColor(15, 15, 20);
    doc.rect(0, 0, pageW, pageH, 'F');

    // Top accent line
    doc.setFillColor(127, 255, 178);
    doc.rect(0, 0, pageW, 1.2, 'F');

    let y = 22;

    // "lyra" logo — each letter in its brand color, Courier bold
    doc.setFont("courier", "bold");
    doc.setFontSize(28);
    const lyraLetters = [
      { ch: "l", color: [124, 165, 212] },
      { ch: "y", color: [139, 194, 104] },
      { ch: "r", color: [228, 94, 84] },
      { ch: "a", color: [250, 191, 83] },
    ];
    let lx = margin;
    lyraLetters.forEach(({ ch, color }) => {
      doc.setTextColor(...color);
      doc.text(ch, lx, y);
      lx += doc.getTextWidth(ch);
    });

    // "WEEKLY REVIEW" subtitle
    doc.setFont("helvetica", "normal");
    doc.setFontSize(10);
    doc.setTextColor(160, 160, 170);
    doc.text("WEEKLY REVIEW", lx + 6, y);

    // Date range
    y += 10;
    doc.setFont("helvetica", "normal");
    doc.setFontSize(11);
    doc.setTextColor(160, 160, 170);
    doc.text(`${startStr}  \u2014  ${endStr}`, margin, y);

    // Thin divider
    y += 8;
    doc.setDrawColor(50, 50, 65);
    doc.setLineWidth(0.2);
    doc.line(margin, y, pageW - margin, y);

    // ============ STATS BOXES ============
    y += 6;
    const statItems = [
      { label: "TRADES", value: `${stats.totalTrades}`, color: [255, 255, 255] },
      { label: "WIN RATE", value: `${stats.winRate}%`, color: stats.winRate >= 50 ? [127, 255, 178] : [255, 68, 102] },
      { label: "TOTAL P&L", value: `${stats.totalPnL >= 0 ? "+" : ""}$${stats.totalPnL.toFixed(2)}`, color: stats.totalPnL >= 0 ? [127, 255, 178] : [255, 68, 102] },
      { label: "AVG WIN", value: `$${stats.avgWin}`, color: [127, 255, 178] },
      { label: "AVG LOSS", value: `$${stats.avgLoss}`, color: [255, 68, 102] },
    ];

    const boxGap = 3;
    const boxW = (contentW - boxGap * (statItems.length - 1)) / statItems.length;
    const boxH = 20;

    statItems.forEach((s, i) => {
      const bx = margin + i * (boxW + boxGap);

      // Box background
      doc.setFillColor(22, 22, 32);
      doc.roundedRect(bx, y, boxW, boxH, 1.5, 1.5, 'F');

      // Label
      doc.setFont("helvetica", "normal");
      doc.setFontSize(6.5);
      doc.setTextColor(100, 100, 115);
      doc.text(s.label, bx + 4, y + 6);

      // Value
      doc.setFont("helvetica", "bold");
      doc.setFontSize(13);
      doc.setTextColor(...s.color);
      doc.text(s.value, bx + 4, y + 15);
    });

    y += boxH + 10;

    // Divider before analysis
    doc.setDrawColor(50, 50, 65);
    doc.line(margin, y, pageW - margin, y);
    y += 10;

    // ============ ANALYSIS BODY ============
    const analysis = analysisData.analysis || "";
    const paragraphs = analysis.split('\n');

    paragraphs.forEach(line => {
      const trimmed = line.trim();

      // Empty line = spacing
      if (!trimmed) {
        y += 3;
        return;
      }

      // Detect section headers: "1. **HEADER**" or "**HEADER**"
      const isSectionHeader = /^\d+\.\s*\*\*/.test(trimmed) || (trimmed.startsWith("**") && trimmed.endsWith("**"));

      // Detect sub-bullets: starts with - or *
      const isBullet = /^[-*]\s/.test(trimmed);

      if (isSectionHeader) {
        // Ensure space before header + room for header + at least a couple lines
        y = checkPage(y, 18);
        y += 6;

        const headerText = trimmed.replace(/\*\*/g, '').replace(/^\d+\.\s*/, '').replace(/:$/, '');

        // Section number
        const numMatch = trimmed.match(/^(\d+)\./);

        // Accent bar
        doc.setFillColor(127, 255, 178);
        doc.rect(margin, y - 3.5, 1.2, 5, 'F');

        // Header text
        doc.setFont("helvetica", "bold");
        doc.setFontSize(11);
        doc.setTextColor(255, 255, 255);
        const headerX = margin + 5;
        if (numMatch) {
          doc.setTextColor(127, 255, 178);
          doc.text(`${numMatch[1]}.`, headerX, y);
          doc.setTextColor(255, 255, 255);
          doc.text(headerText, headerX + 8, y);
        } else {
          doc.text(headerText, headerX, y);
        }

        y += 8;
        doc.setFont("helvetica", "normal");

      } else if (isBullet) {
        y = checkPage(y, lineH + 2);

        const bulletText = trimmed.replace(/^[-*]\s+/, '').replace(/\*\*/g, '').replace(/\*/g, '');
        doc.setFontSize(9);

        // Bullet dot
        doc.setFillColor(127, 255, 178);
        doc.circle(margin + 2, y - 1.2, 0.8, 'F');

        // Bullet text
        doc.setTextColor(200, 200, 210);
        const wrapped = doc.splitTextToSize(bulletText, contentW - 8);
        wrapped.forEach((wl, wi) => {
          y = checkPage(y, lineH);
          doc.text(wl, margin + 6, y);
          y += lineH;
        });
        y += 1;

      } else {
        // Regular paragraph text
        const cleanLine = trimmed.replace(/\*\*/g, '').replace(/\*/g, '');
        doc.setFontSize(9.5);
        doc.setTextColor(190, 190, 200);
        const wrapped = doc.splitTextToSize(cleanLine, contentW);
        wrapped.forEach(wl => {
          y = checkPage(y, lineH);
          doc.text(wl, margin, y);
          y += lineH;
        });
        y += 1.5;
      }
    });

    // ============ FOOTER ON EVERY PAGE ============
    const totalPages = doc.internal.getNumberOfPages();
    for (let i = 1; i <= totalPages; i++) {
      doc.setPage(i);

      // Footer divider
      doc.setDrawColor(40, 40, 55);
      doc.setLineWidth(0.15);
      doc.line(margin, footerY - 3, pageW - margin, footerY - 3);

      // Footer text
      doc.setFont("helvetica", "normal");
      doc.setFontSize(7);
      doc.setTextColor(80, 80, 95);
      doc.text(`ultratrack  \u00B7  Lyra AI Review  \u00B7  ${startStr} \u2014 ${endStr}`, margin, footerY);
      doc.text(`${i} / ${totalPages}`, pageW - margin, footerY, { align: "right" });

      // Bottom accent line
      doc.setFillColor(127, 255, 178);
      doc.rect(0, pageH - 1.2, pageW, 1.2, 'F');
    }

    doc.save(`lyra-review_${weekStart.toISOString().split('T')[0]}_${weekEnd.toISOString().split('T')[0]}.pdf`);
  }

  // ============================================================
  // MONTHLY REVIEW (Lyra Phase 1)
  // ============================================================

  function getMonthRange(year, month) {
    const start = new Date(year, month, 1, 0, 0, 0, 0);
    const end = new Date(year, month + 1, 0, 23, 59, 59, 999);
    return { start, end };
  }

  async function saveMonthlyReviewToFirestore(userId, year, month, analysisData) {
    try {
      const monthKey = `${year}-${String(month + 1).padStart(2, '0')}`;
      const { start, end } = getMonthRange(year, month);
      await db.collection('users').doc(userId).collection('lyraMonthlyReviews').doc(monthKey).set({
        ...analysisData,
        month: monthKey,
        dateRange: {
          start: firebase.firestore.Timestamp.fromDate(start),
          end: firebase.firestore.Timestamp.fromDate(end)
        },
        createdAt: firebase.firestore.FieldValue.serverTimestamp(),
        updatedAt: firebase.firestore.FieldValue.serverTimestamp()
      });
      console.log('✅ Monthly review saved to Firestore for month:', monthKey);
    } catch (error) {
      console.error('Failed to save monthly review:', error);
    }
  }

  async function loadMonthlyReviewFromFirestore(userId, year, month) {
    try {
      const monthKey = `${year}-${String(month + 1).padStart(2, '0')}`;
      const doc = await db.collection('users').doc(userId).collection('lyraMonthlyReviews').doc(monthKey).get();
      if (doc.exists) {
        const data = doc.data();
        console.log('✅ Loaded existing monthly review for month:', monthKey);
        return {
          analysis: data.analysis,
          stats: data.stats,
          month: data.month,
          dateRange: {
            start: data.dateRange.start.toDate(),
            end: data.dateRange.end.toDate()
          }
        };
      }
      return null;
    } catch (error) {
      console.error('Failed to load monthly review:', error);
      return null;
    }
  }

  async function analyzeMonthly(year, month) {
    if (!apiKey) {
      setMonthlyAnalysis({ loading: false, error: "Please enter your Anthropic API key in the Lyra tab.", data: null });
      return;
    }

    setMonthlyAnalysis({ loading: true, error: null, data: null });

    try {
      const { start: monthStart, end: monthEnd } = getMonthRange(year, month);

      // Previous month for comparison
      const prevYear = month === 0 ? year - 1 : year;
      const prevMonth = month === 0 ? 11 : month - 1;
      const { start: prevStart, end: prevEnd } = getMonthRange(prevYear, prevMonth);

      let prevMonthReview = null;
      let prevMonthTrades = [];
      if (user) {
        prevMonthReview = await loadMonthlyReviewFromFirestore(user.uid, prevYear, prevMonth);
        prevMonthTrades = trades.filter(t => {
          const td = new Date(t.date);
          return td >= prevStart && td <= prevEnd;
        });
      }

      // Filter trades for this month
      const monthTrades = trades.filter(t => {
        const td = new Date(t.date);
        return td >= monthStart && td <= monthEnd;
      });

      if (monthTrades.length === 0) {
        setMonthlyAnalysis({ loading: false, error: "No trades found in this month.", data: null });
        return;
      }

      // Calculate stats
      const winners = monthTrades.filter(t => t.pnl > 0);
      const losers = monthTrades.filter(t => t.pnl < 0);
      const totalPnL = monthTrades.reduce((sum, t) => sum + t.pnl, 0);
      const winRate = (winners.length / monthTrades.length * 100).toFixed(1);
      const avgWin = winners.length > 0 ? (winners.reduce((sum, t) => sum + t.pnl, 0) / winners.length).toFixed(2) : 0;
      const avgLoss = losers.length > 0 ? (losers.reduce((sum, t) => sum + t.pnl, 0) / losers.length).toFixed(2) : 0;

      const strategyBreakdown = {};
      const emotionBreakdown = {};
      const sessionBreakdown = {};

      monthTrades.forEach(t => {
        if (!strategyBreakdown[t.strategy]) strategyBreakdown[t.strategy] = { count: 0, pnl: 0, wins: 0 };
        strategyBreakdown[t.strategy].count++;
        strategyBreakdown[t.strategy].pnl += t.pnl;
        if (t.pnl > 0) strategyBreakdown[t.strategy].wins++;

        if (!emotionBreakdown[t.emotion]) emotionBreakdown[t.emotion] = { count: 0, pnl: 0, wins: 0 };
        emotionBreakdown[t.emotion].count++;
        emotionBreakdown[t.emotion].pnl += t.pnl;
        if (t.pnl > 0) emotionBreakdown[t.emotion].wins++;

        if (!sessionBreakdown[t.session]) sessionBreakdown[t.session] = { count: 0, pnl: 0, wins: 0 };
        sessionBreakdown[t.session].count++;
        sessionBreakdown[t.session].pnl += t.pnl;
        if (t.pnl > 0) sessionBreakdown[t.session].wins++;
      });

      // Per-week breakdown within the month
      const weeklyPnLs = [];
      const weekMap = {};
      monthTrades.forEach(t => {
        const td = new Date(t.date);
        const dayOfWeek = td.getDay();
        const weekStart = new Date(td);
        weekStart.setDate(td.getDate() - dayOfWeek);
        weekStart.setHours(0, 0, 0, 0);
        const weekKey = weekStart.toISOString().split('T')[0];
        if (!weekMap[weekKey]) weekMap[weekKey] = { trades: 0, pnl: 0, wins: 0 };
        weekMap[weekKey].trades++;
        weekMap[weekKey].pnl += t.pnl;
        if (t.pnl > 0) weekMap[weekKey].wins++;
      });
      Object.keys(weekMap).sort().forEach(k => {
        const w = weekMap[k];
        weeklyPnLs.push({
          weekStart: k,
          trades: w.trades,
          pnl: w.pnl,
          winRate: (w.wins / w.trades * 100).toFixed(0)
        });
      });

      // Build prompt
      const monthName = monthStart.toLocaleDateString('en-US', { month: 'long', year: 'numeric' });

      const monthDurStats = buildDurationStats(monthTrades);
      const monthDurSection = monthDurStats ? `

HOLD TIME ANALYSIS (${monthDurStats.tradesWithData} trades with timing data):
- Avg hold time: ${monthDurStats.avgAll} min | Winners: ${monthDurStats.avgWinners} min | Losers: ${monthDurStats.avgLosers} min
- Range: ${monthDurStats.shortest} min (shortest) to ${monthDurStats.longest} min (longest)
- By strategy: ${monthDurStats.stratDur.map(s => `${s.name} ${s.avgMins}min`).join(', ')}
- Best hours by avg P&L: ${monthDurStats.hourPerf.slice(0, 3).map(h => `${h.hour} ($${h.avgPnL}/trade, ${h.count} trades)`).join(', ')}` : "";

      // Mindset aggregation (optional — summary only for monthly, no per-day list)
      const monthMindset = buildMindsetStats(journalEntries, monthTrades, monthStart, monthEnd);

      const monthRuleSection = monthMindset?.ruleBreakdown ? `

RULE ADHERENCE THIS MONTH:
- Overall: ${monthMindset.ruleBreakdown.avgScore}% avg adherence across ${monthMindset.ruleBreakdown.daysWithRules} day(s)
- Perfect adherence days: ${monthMindset.ruleBreakdown.perfectDays.length} out of ${monthMindset.ruleBreakdown.daysWithRules}
${monthMindset.ruleBreakdown.mostBroken.length > 0 ? `- Most broken rules: ${monthMindset.ruleBreakdown.mostBroken.map(r => `"${r.text}" (${r.complianceRate}% compliance, broken ${r.broken} days)`).join(', ')}` : '- No rules were broken this month'}
- Per-rule compliance: ${monthMindset.ruleBreakdown.perRule.map(r => `"${r.text}" ${r.complianceRate}%`).join(' | ')}` : "";

      const monthMindsetSection = monthMindset ? `

MINDSET DATA THIS MONTH (${monthMindset.entriesCount} day${monthMindset.entriesCount === 1 ? '' : 's'} logged):
- Averages:${monthMindset.avgSleep ? ` sleep ${monthMindset.avgSleep}h |` : ''}${monthMindset.avgStress ? ` stress ${monthMindset.avgStress}/10 |` : ''}${monthMindset.avgPrep ? ` prep ${monthMindset.avgPrep}/10 |` : ''}${monthMindset.avgEnergy ? ` energy ${monthMindset.avgEnergy}/10 |` : ''}${monthMindset.avgRuleAdherence ? ` rule adherence ${monthMindset.avgRuleAdherence}/10 |` : ''}${monthMindset.avgDayRating ? ` day rating ${monthMindset.avgDayRating}/10` : ''}
${monthMindset.topMoods.length > 0 ? `- Top moods: ${monthMindset.topMoods.map(m => `${m.value} (${m.count})`).join(', ')}` : ''}
${monthMindset.topDisciplineTags.length > 0 ? `- Discipline tags: ${monthMindset.topDisciplineTags.map(t => `${t.value} (${t.count})`).join(', ')}` : ''}${monthRuleSection}` : "";

      let prevMonthSection = "";
      if (prevMonthReview && prevMonthReview.stats) {
        const ps = prevMonthReview.stats;
        prevMonthSection = `

PREVIOUS MONTH DATA (for comparison):
- Total Trades: ${ps.totalTrades}
- Winners: ${ps.winners} | Losers: ${ps.losers}
- Win Rate: ${ps.winRate}%
- Total P&L: $${ps.totalPnL.toFixed(2)}
- Avg Win: $${ps.avgWin} | Avg Loss: $${ps.avgLoss}

PREVIOUS MONTH STRATEGY BREAKDOWN:
${ps.strategyBreakdown ? Object.entries(ps.strategyBreakdown).map(([strategy, stats]) =>
  `${strategy}: ${stats.count} trades, ${(stats.wins/stats.count*100).toFixed(0)}% win rate, $${stats.pnl.toFixed(2)} P&L`
).join('\n') : 'N/A'}

PREVIOUS MONTH EMOTION BREAKDOWN:
${ps.emotionBreakdown ? Object.entries(ps.emotionBreakdown).map(([emotion, stats]) =>
  `${emotion}: ${stats.count} trades, ${(stats.wins/stats.count*100).toFixed(0)}% win rate, $${stats.pnl.toFixed(2)} P&L`
).join('\n') : 'N/A'}

PREVIOUS MONTH LYRA REVIEW:
${prevMonthReview.analysis}`;
      } else if (prevMonthTrades.length > 0) {
        const pWinners = prevMonthTrades.filter(t => t.pnl > 0);
        const pPnL = prevMonthTrades.reduce((s, t) => s + t.pnl, 0);
        prevMonthSection = `

PREVIOUS MONTH SUMMARY (no saved review):
- Total Trades: ${prevMonthTrades.length}
- Win Rate: ${(pWinners.length / prevMonthTrades.length * 100).toFixed(1)}%
- Total P&L: $${pPnL.toFixed(2)}`;
      }

      // Cap trade list to keep prompt size reasonable. For large months, send
      // a sample plus aggregate stats. Send up to 100 trades fully.
      const tradesForPrompt = monthTrades.slice(0, 100);
      const tradesData = tradesForPrompt.map(t =>
        `${t.date} | ${t.ticker} ${t.direction} | Entry: ${t.entry} Exit: ${t.exit} | P&L: $${t.pnl} | Strategy: ${t.strategy} | Emotion: ${t.emotion} | Session: ${t.session}${t.notes ? ` | Notes: ${t.notes}` : ''}`
      ).join('\n');
      const tradesNote = monthTrades.length > 100 ? `\n(Showing first 100 of ${monthTrades.length} trades — see breakdowns above for the full picture.)` : '';

      const prompt = `You are an expert futures trading coach conducting a MONTHLY performance review. This is a higher-level review than the weekly ones — focus on bigger trends, evolution, and the longer arc of the trader's development.

THIS MONTH: ${monthName}

MONTHLY STATS:
- Total Trades: ${monthTrades.length}
- Winners: ${winners.length} | Losers: ${losers.length}
- Win Rate: ${winRate}%
- Total P&L: $${totalPnL.toFixed(2)}
- Avg Win: $${avgWin} | Avg Loss: $${avgLoss}

WEEKLY BREAKDOWN (within this month):
${weeklyPnLs.map(w => `Week of ${w.weekStart}: ${w.trades} trades, ${w.winRate}% win rate, $${w.pnl.toFixed(2)} P&L`).join('\n')}${monthMindsetSection}

STRATEGY BREAKDOWN:
${Object.entries(strategyBreakdown).map(([strategy, stats]) =>
  `${strategy}: ${stats.count} trades, ${(stats.wins/stats.count*100).toFixed(0)}% win rate, $${stats.pnl.toFixed(2)} P&L`
).join('\n')}

EMOTIONAL STATE BREAKDOWN:
${Object.entries(emotionBreakdown).map(([emotion, stats]) =>
  `${emotion}: ${stats.count} trades, ${(stats.wins/stats.count*100).toFixed(0)}% win rate, $${stats.pnl.toFixed(2)} P&L`
).join('\n')}

SESSION BREAKDOWN:
${Object.entries(sessionBreakdown).map(([session, stats]) =>
  `${session}: ${stats.count} trades, ${(stats.wins/stats.count*100).toFixed(0)}% win rate, $${stats.pnl.toFixed(2)} P&L`
).join('\n')}${monthDurSection}

ALL TRADES THIS MONTH:
${tradesData}${tradesNote}${prevMonthSection}

Provide a comprehensive monthly review in ${prevMonthSection ? "6" : "5"} sections:

1. **MONTHLY PERFORMANCE SUMMARY**: Overall assessment of the month. How did the month go in terms of P&L, consistency, and growth? Reference the weekly breakdown to show the trajectory through the month.

2. **STRATEGY EVOLUTION**: Which strategies improved or declined through the month? Are they leaning into the right edges? Be specific about which to double down on and which to retire.

3. **EMOTIONAL TRENDS**: How did emotional patterns shift across the weeks of this month? Are they trading with better psychology than at the start of the month, or worse?

4. **KEY MILESTONES & REGRESSIONS**: Notable wins, biggest losses, breakthroughs, or recurring mistakes that defined this month.

5. **NEXT MONTH FOCUS AREAS**: 3-5 specific, concrete goals for next month. These should be measurable and tied to what you observed in this month's data.${prevMonthSection ? `

6. **MONTH-OVER-MONTH COMPARISON**: Compare this month against last month. Cover:
   - P&L and win rate changes (improved or declined, by how much)
   - Strategy shifts and how the same strategies performed differently
   - Whether last month's focus areas were addressed (if a previous Lyra review exists)
   - Multi-month trends (positive habits forming or recurring problems solidifying)
   Be specific with numbers.` : ""}

Use futures trading terminology. Be direct and coaching-focused. Each section 2-3 paragraphs max.${monthMindsetSection ? " If mindset data is present above, explicitly call out any correlations you observe between mindset metrics (sleep, stress, mood, rule adherence, discipline tags) and this month's P&L outcomes." : ""}${monthRuleSection ? " IMPORTANT: Rule adherence data is included. Dedicate a section to RULE ADHERENCE — analyze per-rule compliance trends, which broken rules cost the most money, and actionable recommendations for improving discipline on the weakest rules." : ""}`;

      console.log('Calling Vercel API proxy for monthly review...');
      const res = await fetch('https://ultratrack-pi.vercel.app/api/analyze', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ prompt: prompt, apiKey: apiKey })
      });

      const data = await res.json();
      console.log('Monthly Vercel API response:', data);

      if (!res.ok || data.error) {
        const errorMsg = data.error || data.details?.message || `HTTP ${res.status} error`;
        setMonthlyAnalysis({ loading: false, error: `API Error: ${errorMsg}`, data: null });
      } else {
        const analysisText = data.content?.map(b => b.text || "").join("") || "No response.";

        const analysisData = {
          analysis: analysisText,
          stats: {
            totalTrades: monthTrades.length,
            winners: winners.length,
            losers: losers.length,
            winRate: parseFloat(winRate),
            totalPnL: totalPnL,
            avgWin: parseFloat(avgWin),
            avgLoss: parseFloat(avgLoss),
            strategyBreakdown,
            emotionBreakdown,
            sessionBreakdown,
            weeklyPnLs
          },
          dateRange: { start: monthStart, end: monthEnd },
          month: `${year}-${String(month + 1).padStart(2, '0')}`
        };

        setMonthlyAnalysis({ loading: false, error: null, data: analysisData });

        if (user) {
          await saveMonthlyReviewToFirestore(user.uid, year, month, analysisData);
        }
      }
    } catch (error) {
      console.error('Monthly analysis failed:', error);
      setMonthlyAnalysis({ loading: false, error: `Error: ${error.message || "Unknown error."}`, data: null });
    }
  }

  function downloadMonthlyReviewPDF(analysisData, year, month) {
    const { jsPDF } = window.jspdf;
    const doc = new jsPDF({ orientation: "portrait", unit: "mm", format: "a4" });
    const pageW = doc.internal.pageSize.getWidth();
    const pageH = doc.internal.pageSize.getHeight();
    const margin = 20;
    const contentW = pageW - margin * 2;
    const footerY = pageH - 12;
    const lineH = 5;

    const monthDate = new Date(year, month, 1);
    const monthStr = monthDate.toLocaleDateString('en-US', { month: 'long', year: 'numeric' });
    const stats = analysisData.stats;

    function newPage() {
      doc.addPage();
      doc.setFillColor(15, 15, 20);
      doc.rect(0, 0, pageW, pageH, 'F');
      return margin + 4;
    }

    function checkPage(currentY, needed) {
      if (currentY + needed > footerY) {
        return newPage();
      }
      return currentY;
    }

    // Cover
    doc.setFillColor(15, 15, 20);
    doc.rect(0, 0, pageW, pageH, 'F');
    doc.setFillColor(127, 255, 178);
    doc.rect(0, 0, pageW, 1.2, 'F');

    let y = 22;

    doc.setFont("courier", "bold");
    doc.setFontSize(28);
    const lyraLetters = [
      { ch: "l", color: [124, 165, 212] },
      { ch: "y", color: [139, 194, 104] },
      { ch: "r", color: [228, 94, 84] },
      { ch: "a", color: [250, 191, 83] },
    ];
    let lx = margin;
    lyraLetters.forEach(({ ch, color }) => {
      doc.setTextColor(...color);
      doc.text(ch, lx, y);
      lx += doc.getTextWidth(ch);
    });

    doc.setFont("helvetica", "normal");
    doc.setFontSize(10);
    doc.setTextColor(160, 160, 170);
    doc.text("MONTHLY REVIEW", lx + 6, y);

    y += 10;
    doc.setFont("helvetica", "normal");
    doc.setFontSize(11);
    doc.setTextColor(160, 160, 170);
    doc.text(monthStr, margin, y);

    y += 8;
    doc.setDrawColor(50, 50, 65);
    doc.setLineWidth(0.2);
    doc.line(margin, y, pageW - margin, y);

    // Stats boxes
    y += 6;
    const statItems = [
      { label: "TRADES", value: `${stats.totalTrades}`, color: [255, 255, 255] },
      { label: "WIN RATE", value: `${stats.winRate}%`, color: stats.winRate >= 50 ? [127, 255, 178] : [255, 68, 102] },
      { label: "TOTAL P&L", value: `${stats.totalPnL >= 0 ? "+" : ""}$${stats.totalPnL.toFixed(2)}`, color: stats.totalPnL >= 0 ? [127, 255, 178] : [255, 68, 102] },
      { label: "AVG WIN", value: `$${stats.avgWin}`, color: [127, 255, 178] },
      { label: "AVG LOSS", value: `$${stats.avgLoss}`, color: [255, 68, 102] },
    ];

    const boxGap = 3;
    const boxW = (contentW - boxGap * (statItems.length - 1)) / statItems.length;
    const boxH = 20;

    statItems.forEach((s, i) => {
      const bx = margin + i * (boxW + boxGap);
      doc.setFillColor(22, 22, 32);
      doc.roundedRect(bx, y, boxW, boxH, 1.5, 1.5, 'F');
      doc.setFont("helvetica", "normal");
      doc.setFontSize(6.5);
      doc.setTextColor(100, 100, 115);
      doc.text(s.label, bx + 4, y + 6);
      doc.setFont("helvetica", "bold");
      doc.setFontSize(13);
      doc.setTextColor(...s.color);
      doc.text(s.value, bx + 4, y + 15);
    });

    y += boxH + 10;

    doc.setDrawColor(50, 50, 65);
    doc.line(margin, y, pageW - margin, y);
    y += 10;

    // Body
    const analysis = analysisData.analysis || "";
    const paragraphs = analysis.split('\n');

    paragraphs.forEach(line => {
      const trimmed = line.trim();
      if (!trimmed) {
        y += 3;
        return;
      }
      const isSectionHeader = /^\d+\.\s*\*\*/.test(trimmed) || (trimmed.startsWith("**") && trimmed.endsWith("**"));
      const isBullet = /^[-*]\s/.test(trimmed);

      if (isSectionHeader) {
        y = checkPage(y, 18);
        y += 6;
        const headerText = trimmed.replace(/\*\*/g, '').replace(/^\d+\.\s*/, '').replace(/:$/, '');
        const numMatch = trimmed.match(/^(\d+)\./);

        doc.setFillColor(127, 255, 178);
        doc.rect(margin, y - 3.5, 1.2, 5, 'F');

        doc.setFont("helvetica", "bold");
        doc.setFontSize(11);
        doc.setTextColor(255, 255, 255);
        const headerX = margin + 5;
        if (numMatch) {
          doc.setTextColor(127, 255, 178);
          doc.text(`${numMatch[1]}.`, headerX, y);
          doc.setTextColor(255, 255, 255);
          doc.text(headerText, headerX + 8, y);
        } else {
          doc.text(headerText, headerX, y);
        }

        y += 8;
        doc.setFont("helvetica", "normal");
      } else if (isBullet) {
        y = checkPage(y, lineH + 2);
        const bulletText = trimmed.replace(/^[-*]\s+/, '').replace(/\*\*/g, '').replace(/\*/g, '');
        doc.setFontSize(9);
        doc.setFillColor(127, 255, 178);
        doc.circle(margin + 2, y - 1.2, 0.8, 'F');
        doc.setTextColor(200, 200, 210);
        const wrapped = doc.splitTextToSize(bulletText, contentW - 8);
        wrapped.forEach(wl => {
          y = checkPage(y, lineH);
          doc.text(wl, margin + 6, y);
          y += lineH;
        });
        y += 1;
      } else {
        const cleanLine = trimmed.replace(/\*\*/g, '').replace(/\*/g, '');
        doc.setFontSize(9.5);
        doc.setTextColor(190, 190, 200);
        const wrapped = doc.splitTextToSize(cleanLine, contentW);
        wrapped.forEach(wl => {
          y = checkPage(y, lineH);
          doc.text(wl, margin, y);
          y += lineH;
        });
        y += 1.5;
      }
    });

    // Footer on every page
    const totalPages = doc.internal.getNumberOfPages();
    for (let i = 1; i <= totalPages; i++) {
      doc.setPage(i);
      doc.setDrawColor(40, 40, 55);
      doc.setLineWidth(0.15);
      doc.line(margin, footerY - 3, pageW - margin, footerY - 3);

      doc.setFont("helvetica", "normal");
      doc.setFontSize(7);
      doc.setTextColor(80, 80, 95);
      doc.text(`ultratrack  \u00B7  Lyra AI Monthly Review  \u00B7  ${monthStr}`, margin, footerY);
      doc.text(`${i} / ${totalPages}`, pageW - margin, footerY, { align: "right" });

      doc.setFillColor(127, 255, 178);
      doc.rect(0, pageH - 1.2, pageW, 1.2, 'F');
    }

    const monthKey = `${year}-${String(month + 1).padStart(2, '0')}`;
    doc.save(`lyra-monthly-review_${monthKey}.pdf`);
  }

  // ============================================================
  // STRATEGY SCORING (Lyra Phase 2)
  // ============================================================

  function gradeFromScore(score) {
    if (score >= 93) return "A";
    if (score >= 87) return "A-";
    if (score >= 83) return "B+";
    if (score >= 77) return "B";
    if (score >= 73) return "B-";
    if (score >= 67) return "C+";
    if (score >= 60) return "C";
    if (score >= 50) return "D";
    return "F";
  }

  async function saveStrategyScores(userId, data) {
    try {
      await db.collection('users').doc(userId).collection('lyraStrategyScores').doc('latest').set({
        ...data,
        createdAt: firebase.firestore.FieldValue.serverTimestamp(),
        updatedAt: firebase.firestore.FieldValue.serverTimestamp()
      });
      console.log('✅ Strategy scores saved');
    } catch (error) {
      console.error('Failed to save strategy scores:', error);
    }
  }

  async function loadStrategyScores(userId) {
    try {
      const doc = await db.collection('users').doc(userId).collection('lyraStrategyScores').doc('latest').get();
      if (doc.exists) {
        const data = doc.data();
        return {
          strategies: data.strategies,
          portfolioHealth: data.portfolioHealth,
          tradeCount: data.tradeCount,
          generatedAt: data.generatedAt
        };
      }
      return null;
    } catch (error) {
      console.error('Failed to load strategy scores:', error);
      return null;
    }
  }

  async function scoreStrategies() {
    if (!apiKey) {
      setStrategyScores({ loading: false, error: "Please enter your Anthropic API key in the Lyra tab.", data: null });
      return;
    }

    if (trades.length === 0) {
      setStrategyScores({ loading: false, error: "No trades to score yet.", data: null });
      return;
    }

    setStrategyScores({ loading: true, error: null, data: null });

    try {
      // Group trades by strategy
      const byStrategy = {};
      trades.forEach(t => {
        if (!byStrategy[t.strategy]) byStrategy[t.strategy] = [];
        byStrategy[t.strategy].push(t);
      });

      // Compute metrics per strategy (min 3 trades)
      const computed = [];
      Object.entries(byStrategy).forEach(([name, list]) => {
        if (list.length < 3) return;

        const winners = list.filter(t => t.pnl > 0);
        const losers = list.filter(t => t.pnl < 0);
        const totalPnL = list.reduce((s, t) => s + t.pnl, 0);
        const grossWins = winners.reduce((s, t) => s + t.pnl, 0);
        const grossLosses = Math.abs(losers.reduce((s, t) => s + t.pnl, 0));
        const winRate = winners.length / list.length * 100;
        const avgWin = winners.length > 0 ? grossWins / winners.length : 0;
        const avgLoss = losers.length > 0 ? grossLosses / losers.length : 0;
        const profitFactor = grossLosses > 0 ? grossWins / grossLosses : (grossWins > 0 ? 5 : 0);
        const avgWLRatio = avgLoss > 0 ? avgWin / avgLoss : (avgWin > 0 ? 3 : 0);
        const avgPnL = totalPnL / list.length;

        // Consistency: 1 - normalized stddev. Higher = more consistent.
        const meanAbs = list.reduce((s, t) => s + Math.abs(t.pnl), 0) / list.length || 1;
        const variance = list.reduce((s, t) => s + Math.pow(t.pnl - avgPnL, 2), 0) / list.length;
        const stddev = Math.sqrt(variance);
        const consistency = Math.max(0, Math.min(1, 1 - (stddev / (meanAbs * 2))));

        const frequency = list.length;

        // Composite score (0-100)
        const compositeScore = Math.round(
          (winRate * 0.25) +
          (Math.min(profitFactor, 5) / 5 * 25) +
          (Math.min(avgWLRatio, 3) / 3 * 20) +
          (consistency * 20) +
          (Math.min(frequency, 30) / 30 * 10)
        );

        computed.push({
          name,
          metrics: {
            winRate: parseFloat(winRate.toFixed(1)),
            profitFactor: parseFloat(profitFactor.toFixed(2)),
            avgWinLossRatio: parseFloat(avgWLRatio.toFixed(2)),
            frequency,
            consistency: parseFloat(consistency.toFixed(2)),
            totalPnL: parseFloat(totalPnL.toFixed(2)),
            avgPnL: parseFloat(avgPnL.toFixed(2)),
            avgWin: parseFloat(avgWin.toFixed(2)),
            avgLoss: parseFloat(avgLoss.toFixed(2))
          },
          compositeScore,
          grade: gradeFromScore(compositeScore)
        });
      });

      if (computed.length === 0) {
        setStrategyScores({ loading: false, error: "No strategies have enough trades yet (need at least 3 per strategy).", data: null });
        return;
      }

      // Sort by score, descending
      computed.sort((a, b) => b.compositeScore - a.compositeScore);

      // Build prompt for Claude — recommendations + per-strategy analysis
      const strategySummary = computed.map(s =>
        `${s.name}: ${s.metrics.winRate}% WR, ${s.metrics.profitFactor}x PF, ${s.metrics.avgWinLossRatio}:1 W/L, ${s.metrics.frequency} trades, consistency ${s.metrics.consistency}, $${s.metrics.totalPnL} total P&L, score ${s.compositeScore}/100 (${s.grade})`
      ).join('\n');

      const prompt = `You are an expert futures trading strategy analyst. Below are the computed metrics for each strategy in a trader's journal.

STRATEGIES:
${strategySummary}

For each strategy, provide:
- recommendation: one of "Focus" (expand and lean in), "Refine" (working but needs adjustment), "Retire" (consistently losing or unsustainable), or "Developing" (too few trades to judge but promising)
- analysis: 1-2 sentence assessment focused on what's driving the score and what to do about it

Also provide an overall portfolio strategy health assessment (2-3 sentences) covering the trader's overall strategy mix and concentration.

Respond ONLY with valid JSON in this exact format (no markdown, no code fence):
{"strategies":[{"name":"...","recommendation":"Focus|Refine|Retire|Developing","analysis":"..."}],"portfolioHealth":"..."}`;

      const res = await fetch('https://ultratrack-pi.vercel.app/api/analyze', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ prompt: prompt, apiKey: apiKey })
      });

      const apiData = await res.json();
      if (!res.ok || apiData.error) {
        const errorMsg = apiData.error || apiData.details?.message || `HTTP ${res.status} error`;
        setStrategyScores({ loading: false, error: `API Error: ${errorMsg}`, data: null });
        return;
      }

      const responseText = apiData.content?.map(b => b.text || "").join("") || "";
      // Strip markdown code fences if Claude added them anyway
      const cleaned = responseText.replace(/^```(?:json)?\s*/i, '').replace(/\s*```\s*$/, '').trim();

      let parsed;
      try {
        parsed = JSON.parse(cleaned);
      } catch (e) {
        console.error('Failed to parse strategy scoring JSON:', cleaned);
        setStrategyScores({ loading: false, error: "Couldn't parse Lyra's response. Try again.", data: null });
        return;
      }

      // Merge AI recommendations into computed strategies
      const merged = computed.map(s => {
        const aiEntry = parsed.strategies?.find(a => a.name === s.name);
        return {
          ...s,
          recommendation: aiEntry?.recommendation || "Developing",
          aiAnalysis: aiEntry?.analysis || ""
        };
      });

      const finalData = {
        strategies: merged,
        portfolioHealth: parsed.portfolioHealth || "",
        tradeCount: trades.length,
        generatedAt: new Date().toISOString()
      };

      setStrategyScores({ loading: false, error: null, data: finalData });

      if (user) {
        await saveStrategyScores(user.uid, finalData);
      }
    } catch (error) {
      console.error('Strategy scoring failed:', error);
      setStrategyScores({ loading: false, error: `Error: ${error.message || "Unknown error."}`, data: null });
    }
  }

  // ============================================================
  // PATTERN DETECTION (Lyra Phase 3)
  // ============================================================

  async function savePatterns(userId, data) {
    try {
      await db.collection('users').doc(userId).collection('lyraPatterns').doc('latest').set({
        ...data,
        createdAt: firebase.firestore.FieldValue.serverTimestamp(),
        updatedAt: firebase.firestore.FieldValue.serverTimestamp()
      });
      console.log('✅ Patterns saved');
    } catch (error) {
      console.error('Failed to save patterns:', error);
    }
  }

  async function loadPatterns(userId) {
    try {
      const doc = await db.collection('users').doc(userId).collection('lyraPatterns').doc('latest').get();
      if (doc.exists) {
        const data = doc.data();
        return {
          patterns: data.patterns,
          tradeCount: data.tradeCount,
          generatedAt: data.generatedAt
        };
      }
      return null;
    } catch (error) {
      console.error('Failed to load patterns:', error);
      return null;
    }
  }

  async function detectPatterns() {
    if (!apiKey) {
      setPatterns({ loading: false, error: "Please enter your Anthropic API key in the Lyra tab.", data: null });
      return;
    }

    if (trades.length < 10) {
      setPatterns({ loading: false, error: "Pattern detection needs at least 10 trades to find meaningful combinations.", data: null });
      return;
    }

    setPatterns({ loading: true, error: null, data: null });

    try {
      // Cross-tabulate combinations
      const buckets = {}; // key -> { fields, trades, pnl, wins }

      function addToBucket(key, fields, trade) {
        if (!buckets[key]) buckets[key] = { fields, trades: 0, pnl: 0, wins: 0 };
        buckets[key].trades++;
        buckets[key].pnl += trade.pnl;
        if (trade.pnl > 0) buckets[key].wins++;
      }

      const dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];

      trades.forEach(t => {
        const market = t.market || t.ticker || 'Unknown';
        // emotion x strategy
        addToBucket(`em_st|${t.emotion}|${t.strategy}`, { category: 'emotion_strategy', emotion: t.emotion, strategy: t.strategy }, t);
        // emotion x session
        addToBucket(`em_se|${t.emotion}|${t.session}`, { category: 'emotion_session', emotion: t.emotion, session: t.session }, t);
        // strategy x session
        addToBucket(`st_se|${t.strategy}|${t.session}`, { category: 'strategy_session', strategy: t.strategy, session: t.session }, t);
        // market x session
        addToBucket(`mk_se|${market}|${t.session}`, { category: 'market_session', market, session: t.session }, t);
        // emotion x market
        addToBucket(`em_mk|${t.emotion}|${market}`, { category: 'emotion_market', emotion: t.emotion, market }, t);
        // day of week
        const td = new Date(t.date);
        const day = dayNames[td.getDay()];
        addToBucket(`day|${day}`, { category: 'day_of_week', day }, t);
        // emotion alone
        addToBucket(`em|${t.emotion}`, { category: 'emotion', emotion: t.emotion }, t);

        // rule adherence level x strategy (if rule data exists for this trade's date)
        if (activeRules.length > 0 && t.date) {
          const dayCheckoffs = journalEntries[t.date]?.mindset?.ruleCheckoffs;
          if (dayCheckoffs && Object.keys(dayCheckoffs).length > 0) {
            const followed = activeRules.filter(r => dayCheckoffs[r.id] === true).length;
            const pct = Math.round((followed / activeRules.length) * 100);
            const level = pct === 100 ? "100% rules followed" : pct >= 80 ? "80-99% rules followed" : "< 80% rules followed";
            addToBucket(`rl_st|${level}|${t.strategy}`, { category: 'rules_strategy', ruleLevel: level, strategy: t.strategy }, t);
            addToBucket(`rl|${level}`, { category: 'rule_adherence', ruleLevel: level }, t);
          }
        }
      });

      // Filter and classify
      const candidates = [];
      Object.entries(buckets).forEach(([key, b]) => {
        if (b.trades < 3) return;
        const winRate = b.wins / b.trades * 100;
        const avgPnL = b.pnl / b.trades;

        let type = null;
        if (winRate < 40 || avgPnL < -100) type = 'losing';
        else if (winRate > 65 || avgPnL > 150) type = 'winning';
        if (!type) return;

        // Build description
        const f = b.fields;
        let description = '';
        if (f.category === 'emotion_strategy') description = `${f.emotion} + ${f.strategy}`;
        else if (f.category === 'emotion_session') description = `${f.emotion} + ${f.session}`;
        else if (f.category === 'strategy_session') description = `${f.strategy} + ${f.session}`;
        else if (f.category === 'market_session') description = `${f.market} + ${f.session}`;
        else if (f.category === 'emotion_market') description = `${f.emotion} + ${f.market}`;
        else if (f.category === 'day_of_week') description = `${f.day} trading`;
        else if (f.category === 'emotion') description = `${f.emotion} state`;
        else if (f.category === 'rules_strategy') description = `${f.ruleLevel} + ${f.strategy}`;
        else if (f.category === 'rule_adherence') description = `${f.ruleLevel}`;

        candidates.push({
          key,
          type,
          category: f.category,
          fields: f,
          description,
          stats: {
            occurrences: b.trades,
            winRate: parseFloat(winRate.toFixed(1)),
            totalPnL: parseFloat(b.pnl.toFixed(2)),
            avgPnL: parseFloat(avgPnL.toFixed(2))
          }
        });
      });

      if (candidates.length === 0) {
        setPatterns({ loading: false, error: "No statistically significant patterns yet. Keep trading and try again.", data: null });
        return;
      }

      // Sort by absolute impact (|totalPnL|) descending, take top 15
      candidates.sort((a, b) => Math.abs(b.stats.totalPnL) - Math.abs(a.stats.totalPnL));
      const top = candidates.slice(0, 15);

      // Build prompt for Claude
      const losingList = top.filter(p => p.type === 'losing');
      const winningList = top.filter(p => p.type === 'winning');

      const formatPattern = (p, i) => `${i + 1}. ${p.description} — ${p.stats.occurrences} trades, ${p.stats.winRate}% WR, $${p.stats.totalPnL} total ($${p.stats.avgPnL}/trade)`;

      const prompt = `You are an expert futures trading pattern analyst. Below are statistically significant patterns found in a trader's journal (${trades.length} trades analyzed).

For each pattern, provide:
- severity: "HIGH" (financial impact > $500 or critical psychological pattern), "MEDIUM" (notable but not urgent), or "LOW" (worth watching)
- explanation: 1-2 sentences on the likely psychological/market reason behind it
- recommendation: 1 specific actionable next step

LOSING PATTERNS:
${losingList.length > 0 ? losingList.map(formatPattern).join('\n') : '(none)'}

WINNING PATTERNS:
${winningList.length > 0 ? winningList.map(formatPattern).join('\n') : '(none)'}

Respond ONLY with valid JSON in this exact format (no markdown, no code fence):
{"patterns":[{"index":1,"type":"losing","severity":"HIGH","explanation":"...","recommendation":"..."}]}

Include every pattern listed above. Use the index number from each list (losing 1-N, winning 1-N).`;

      const res = await fetch('https://ultratrack-pi.vercel.app/api/analyze', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ prompt: prompt, apiKey: apiKey })
      });

      const apiData = await res.json();
      if (!res.ok || apiData.error) {
        const errorMsg = apiData.error || apiData.details?.message || `HTTP ${res.status} error`;
        setPatterns({ loading: false, error: `API Error: ${errorMsg}`, data: null });
        return;
      }

      const responseText = apiData.content?.map(b => b.text || "").join("") || "";
      const cleaned = responseText.replace(/^```(?:json)?\s*/i, '').replace(/\s*```\s*$/, '').trim();

      let parsed;
      try {
        parsed = JSON.parse(cleaned);
      } catch (e) {
        console.error('Failed to parse pattern detection JSON:', cleaned);
        setPatterns({ loading: false, error: "Couldn't parse Lyra's response. Try again.", data: null });
        return;
      }

      // Merge AI insights with computed patterns
      const merged = top.map((p, idx) => {
        // Find AI entry by matching type + position within type
        const sameTypeBefore = top.slice(0, idx).filter(x => x.type === p.type).length;
        const indexInType = sameTypeBefore + 1;
        const aiEntry = parsed.patterns?.find(a => a.type === p.type && a.index === indexInType);
        return {
          ...p,
          severity: aiEntry?.severity || "MEDIUM",
          aiInsight: aiEntry?.explanation || "",
          recommendation: aiEntry?.recommendation || ""
        };
      });

      const finalData = {
        patterns: merged,
        tradeCount: trades.length,
        generatedAt: new Date().toISOString()
      };

      setPatterns({ loading: false, error: null, data: finalData });

      if (user) {
        await savePatterns(user.uid, finalData);
      }
    } catch (error) {
      console.error('Pattern detection failed:', error);
      setPatterns({ loading: false, error: `Error: ${error.message || "Unknown error."}`, data: null });
    }
  }

  // ============================================================
  // CHAT WITH LYRA (Lyra Phase 4)
  // ============================================================

  async function saveChatHistory(userId, messages) {
    try {
      await db.collection('users').doc(userId).collection('lyraChatHistory').doc('latest').set({
        messages,
        updatedAt: firebase.firestore.FieldValue.serverTimestamp()
      });
    } catch (error) {
      console.error('Failed to save chat history:', error);
    }
  }

  async function loadChatHistory(userId) {
    try {
      const doc = await db.collection('users').doc(userId).collection('lyraChatHistory').doc('latest').get();
      if (doc.exists) {
        return doc.data().messages || [];
      }
      return [];
    } catch (error) {
      console.error('Failed to load chat history:', error);
      return [];
    }
  }

  function buildChatSystemContext() {
    // Build a condensed snapshot of the trader's data so Lyra has context
    // without sending the full journal each turn.
    const totalTrades = trades.length;
    if (totalTrades === 0) {
      return "You are Lyra, an expert AI futures trading coach. The trader has no trades logged yet. Encourage them to log trades so you can give specific guidance.";
    }

    const winners = trades.filter(t => t.pnl > 0);
    const totalPnL = trades.reduce((s, t) => s + t.pnl, 0);
    const winRate = (winners.length / totalTrades * 100).toFixed(1);

    // Recent 10 trades for specific reference
    const recentTrades = trades.slice(0, 10).map(t =>
      `${t.date} | ${t.ticker} ${t.direction} | $${t.pnl} | ${t.strategy} | ${t.emotion} | ${t.session}`
    ).join('\n');

    // Top strategies by P&L
    const stratMap = {};
    trades.forEach(t => {
      if (!stratMap[t.strategy]) stratMap[t.strategy] = { trades: 0, pnl: 0, wins: 0 };
      stratMap[t.strategy].trades++;
      stratMap[t.strategy].pnl += t.pnl;
      if (t.pnl > 0) stratMap[t.strategy].wins++;
    });
    const topStrategies = Object.entries(stratMap)
      .sort((a, b) => b[1].pnl - a[1].pnl)
      .slice(0, 5)
      .map(([name, s]) => `${name}: ${s.trades} trades, ${(s.wins/s.trades*100).toFixed(0)}% WR, $${s.pnl.toFixed(2)} P&L`)
      .join('\n');

    // Top emotions
    const emoMap = {};
    trades.forEach(t => {
      if (!emoMap[t.emotion]) emoMap[t.emotion] = { trades: 0, pnl: 0 };
      emoMap[t.emotion].trades++;
      emoMap[t.emotion].pnl += t.pnl;
    });
    const topEmotions = Object.entries(emoMap)
      .sort((a, b) => b[1].trades - a[1].trades)
      .slice(0, 5)
      .map(([name, e]) => `${name}: ${e.trades} trades, $${e.pnl.toFixed(2)} P&L`)
      .join('\n');

    // Current week P&L
    const now = new Date();
    const dow = now.getDay();
    const weekStart = new Date(now);
    weekStart.setDate(now.getDate() - dow);
    weekStart.setHours(0, 0, 0, 0);
    const weekTrades = trades.filter(t => new Date(t.date) >= weekStart);
    const weekPnL = weekTrades.reduce((s, t) => s + t.pnl, 0);

    // Patterns context
    let patternsContext = "";
    if (patterns.data && patterns.data.patterns) {
      const losing = patterns.data.patterns.filter(p => p.type === 'losing').slice(0, 3);
      const winning = patterns.data.patterns.filter(p => p.type === 'winning').slice(0, 3);
      if (losing.length || winning.length) {
        patternsContext = `\n\nDETECTED PATTERNS:\nLosing: ${losing.map(p => `${p.description} (${p.stats.winRate}% WR, $${p.stats.totalPnL})`).join('; ') || 'none'}\nWinning: ${winning.map(p => `${p.description} (${p.stats.winRate}% WR, $${p.stats.totalPnL})`).join('; ') || 'none'}`;
      }
    }

    // Strategy scores context
    let scoresContext = "";
    if (strategyScores.data && strategyScores.data.strategies) {
      scoresContext = `\n\nSTRATEGY GRADES: ${strategyScores.data.strategies.slice(0, 8).map(s => `${s.name} (${s.grade}, ${s.recommendation})`).join(', ')}`;
    }

    // Today's rule adherence context
    let rulesContext = "";
    if (activeRules.length > 0) {
      const today = new Date().toISOString().split("T")[0];
      const todayCheckoffs = journalEntries[today]?.mindset?.ruleCheckoffs;
      if (todayCheckoffs && Object.keys(todayCheckoffs).length > 0) {
        const ruleLines = activeRules.map(r => {
          const status = todayCheckoffs[r.id] === true ? "FOLLOWED" : "BROKEN";
          return `- ${r.text}: ${status}`;
        }).join('\n');
        const followed = activeRules.filter(r => todayCheckoffs[r.id] === true).length;
        const streak = calculateRuleAdherenceStreak();
        rulesContext = `\n\nTODAY'S RULE ADHERENCE:\n${ruleLines}\n- Overall: ${followed}/${activeRules.length} (${Math.round(followed/activeRules.length*100)}%)\n- Current streak: ${streak.current} day${streak.current !== 1 ? 's' : ''} of perfect adherence`;
      } else {
        rulesContext = `\n\nTODAY'S RULE ADHERENCE: Not yet filled in for today. The trader has ${activeRules.length} active rules configured.`;
      }
    }

    return `You are Lyra, an expert AI futures trading coach. You have access to this trader's journal data. Be direct, use futures terminology, and give actionable advice. Keep responses concise (under 250 words unless asked for detail).

TRADER SNAPSHOT:
- Total trades: ${totalTrades}
- Win rate: ${winRate}%
- Total P&L: $${totalPnL.toFixed(2)}
- Current week P&L: $${weekPnL.toFixed(2)} (${weekTrades.length} trades)

TOP STRATEGIES BY P&L:
${topStrategies}

EMOTIONAL STATES (most common):
${topEmotions}

RECENT 10 TRADES:
${recentTrades}${patternsContext}${scoresContext}${rulesContext}

When the trader asks about specific trades, dates, or patterns, reference the snapshot above. If they ask about something not in the snapshot, tell them to share more context or run a fresh analysis. If rule adherence data shows broken rules today, proactively flag concerns when relevant.`;
  }

  async function sendChatMessage(userMessage) {
    if (!apiKey) {
      setChatMessages(prev => [...prev, { role: 'user', content: userMessage }, { role: 'assistant', content: "Please add your Anthropic API key in the Lyra tab first." }]);
      return;
    }

    const trimmed = userMessage.trim();
    if (!trimmed) return;

    const newMessages = [...chatMessages, { role: 'user', content: trimmed }];
    setChatMessages(newMessages);
    setChatInput("");
    setChatLoading(true);

    try {
      const systemContext = buildChatSystemContext();

      // Send only role/content fields to Claude (strip any local metadata)
      const apiMessages = newMessages.map(m => ({ role: m.role, content: m.content }));

      // Call Anthropic API directly from the browser (same pattern as runAnalysis/analyzeOne).
      // This avoids the Vercel proxy so chat works without needing a proxy redeploy.
      const res = await fetch('https://api.anthropic.com/v1/messages', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'x-api-key': apiKey,
          'anthropic-version': '2023-06-01',
          'anthropic-dangerous-direct-browser-access': 'true'
        },
        body: JSON.stringify({
          model: 'claude-sonnet-4-20250514',
          max_tokens: 1500,
          system: systemContext,
          messages: apiMessages
        })
      });

      const apiData = await res.json();

      if (!res.ok || apiData.error) {
        const errorMsg = apiData.error?.message || apiData.error || `HTTP ${res.status} error`;
        const updated = [...newMessages, { role: 'assistant', content: `Error: ${errorMsg}` }];
        setChatMessages(updated);
      } else {
        const responseText = apiData.content?.map(b => b.text || "").join("") || "No response.";
        const updated = [...newMessages, { role: 'assistant', content: responseText }];
        setChatMessages(updated);

        if (user) {
          await saveChatHistory(user.uid, updated);
        }
      }
    } catch (error) {
      console.error('Chat failed:', error);
      const updated = [...newMessages, { role: 'assistant', content: `Error: ${error.message || 'Unknown error.'}` }];
      setChatMessages(updated);
    } finally {
      setChatLoading(false);
    }
  }

  function clearChat() {
    setChatMessages([]);
    if (user) {
      saveChatHistory(user.uid, []);
    }
  }

  function deleteTrade(id) {
    setTrades(prev => prev.filter(t => t.id !== id));
    setDeleteConfirm(null);
    setExpandedTrade(null);
  }

  function addCustomStrategy() {
    const trimmed = newStrategy.trim();
    if (!trimmed) return;
    if (STRATEGIES.includes(trimmed) || customStrategies.includes(trimmed)) {
      alert('Strategy already exists!');
      return;
    }
    setCustomStrategies(prev => [...prev, trimmed]);
    setNewStrategy("");
  }

  function deleteCustomStrategy(strategy) {
    setCustomStrategies(prev => prev.filter(s => s !== strategy));
  }

  function addCustomEmotion() {
    const trimmed = newEmotion.trim();
    if (!trimmed) return;
    if (EMOTIONS.includes(trimmed) || customEmotions.includes(trimmed)) {
      alert('Emotion already exists!');
      return;
    }
    setCustomEmotions(prev => [...prev, trimmed]);
    setNewEmotion("");
  }

  function deleteCustomEmotion(emotion) {
    setCustomEmotions(prev => prev.filter(e => e !== emotion));
  }

  function addCustomMistake() {
    const trimmed = newMistake.trim();
    if (!trimmed) return;
    if (MISTAKES.includes(trimmed) || customMistakes.includes(trimmed)) {
      alert('Mistake already exists!');
      return;
    }
    setCustomMistakes(prev => [...prev, trimmed]);
    setNewMistake("");
  }

  function deleteCustomMistake(mistake) {
    setCustomMistakes(prev => prev.filter(m => m !== mistake));
  }

  function openEditStrategy(trade) {
    setEditStrategyTrade(trade);
    setEditStrategyValue(trade.strategy);
  }

  function saveEditStrategy() {
    if (!editStrategyTrade || !editStrategyValue) return;
    setTrades(prev => prev.map(t =>
      t.id === editStrategyTrade.id
        ? { ...t, strategy: editStrategyValue }
        : t
    ));
    setEditStrategyTrade(null);
    setEditStrategyValue("");
  }

  function openEditEmotion(trade) {
    setEditEmotionTrade(trade);
    setEditEmotionValue(trade.emotion);
  }

  function saveEditEmotion() {
    if (!editEmotionTrade || !editEmotionValue) return;
    setTrades(prev => prev.map(t =>
      t.id === editEmotionTrade.id
        ? { ...t, emotion: editEmotionValue }
        : t
    ));
    setEditEmotionTrade(null);
    setEditEmotionValue("");
  }

  function openEditMistake(trade) {
    setEditMistakeTrade(trade);
    setEditMistakeValue(getMistakes(trade));
  }

  function toggleEditMistake(m) {
    setEditMistakeValue(prev => {
      if (m === "None") return ["None"];
      const without = prev.filter(x => x !== "None");
      if (without.includes(m)) {
        const result = without.filter(x => x !== m);
        return result.length === 0 ? ["None"] : result;
      }
      return [...without, m];
    });
  }

  function saveEditMistake() {
    if (!editMistakeTrade) return;
    setTrades(prev => prev.map(t =>
      t.id === editMistakeTrade.id
        ? { ...t, mistake: editMistakeValue }
        : t
    ));
    setEditMistakeTrade(null);
    setEditMistakeValue([]);
  }

  function openEditTime(trade) {
    setEditTimeTrade(trade);
    setEditEntryTime(trade.entryTime || "");
    setEditExitTime(trade.exitTime || "");
  }

  function saveEditTime() {
    if (!editTimeTrade) return;
    setTrades(prev => prev.map(t =>
      t.id === editTimeTrade.id
        ? { ...t, entryTime: editEntryTime, exitTime: editExitTime }
        : t
    ));
    setEditTimeTrade(null);
    setEditEntryTime("");
    setEditExitTime("");
  }

  function openEditNotes(trade) {
    setEditNotesTrade(trade);
    // Parse existing notes structure or use legacy text
    if (trade.notesData) {
      setNotesText(trade.notesData.text || "");
      setNotesImages(trade.notesData.images || []);
    } else {
      // Legacy notes field - just text
      setNotesText(trade.notes || "");
      setNotesImages([]);
    }
  }

  function handleImageUpload(e) {
    const files = e.target?.files ? Array.from(e.target.files) : e;
    files.forEach(file => {
      if (file.type.startsWith('image/')) {
        const reader = new FileReader();
        reader.onload = (event) => {
          const newImage = {
            id: Date.now() + Math.random(),
            dataUrl: event.target.result,
            name: file.name
          };
          setNotesImages(prev => [...prev, newImage]);
        };
        reader.readAsDataURL(file);
      }
    });
    // Reset input
    if (imageInputRef.current) imageInputRef.current.value = '';
  }

  function handleDragOver(e) {
    e.preventDefault();
    e.stopPropagation();
    setDragOver(true);
  }

  function handleDragLeave(e) {
    e.preventDefault();
    e.stopPropagation();
    setDragOver(false);
  }

  function handleDrop(e) {
    e.preventDefault();
    e.stopPropagation();
    setDragOver(false);

    const files = Array.from(e.dataTransfer.files);
    handleImageUpload(files);
  }

  function removeImage(imageId) {
    setNotesImages(prev => prev.filter(img => img.id !== imageId));
  }

  function insertBulletPoint() {
    const textarea = document.getElementById('notes-textarea');
    if (!textarea) return;

    const start = textarea.selectionStart;
    const end = textarea.selectionEnd;
    const text = notesText;

    // Check if we're at the start of a line
    const beforeCursor = text.substring(0, start);
    const afterCursor = text.substring(end);
    const lastNewline = beforeCursor.lastIndexOf('\n');
    const currentLineStart = lastNewline === -1 ? 0 : lastNewline + 1;
    const currentLine = text.substring(currentLineStart, start);

    let newText;
    let newCursorPos;

    if (currentLine.trim() === '') {
      // Empty line - add bullet
      newText = beforeCursor + '• ' + afterCursor;
      newCursorPos = start + 2;
    } else {
      // Has text - add bullet on new line
      newText = beforeCursor + '\n• ' + afterCursor;
      newCursorPos = start + 3;
    }

    setNotesText(newText);

    // Set cursor position after state update
    setTimeout(() => {
      textarea.focus();
      textarea.setSelectionRange(newCursorPos, newCursorPos);
    }, 0);
  }

  function saveEditNotes() {
    if (!editNotesTrade) return;

    const notesData = {
      text: notesText,
      images: notesImages
    };

    // Also update legacy 'notes' field for backwards compatibility
    const legacyNotes = notesText || (notesImages.length > 0 ? `[Has ${notesImages.length} image(s)]` : "");

    setTrades(prev => prev.map(t =>
      t.id === editNotesTrade.id
        ? { ...t, notes: legacyNotes, notesData }
        : t
    ));

    setEditNotesTrade(null);
    setNotesText("");
    setNotesImages([]);
  }

  // Combined lists (default + custom)
  const allStrategies = [...STRATEGIES, ...customStrategies];
  const allEmotions = [...EMOTIONS, ...customEmotions];
  const allMistakes = [...MISTAKES, ...customMistakes];

  const stratPerf = allStrategies.map(s => { const st = trades.filter(t => t.strategy === s); const w = st.filter(t => t.pnl > 0); return { name: s, count: st.length, pnl: st.reduce((a, t) => a + t.pnl, 0), wr: st.length ? Math.round(w.length / st.length * 100) : 0 }; }).filter(s => s.count > 0).sort((a, b) => b.pnl - a.pnl);
  const emotPerf = allEmotions.map(e => { const em = trades.filter(t => t.emotion === e); return { name: e, count: em.length, pnl: em.reduce((a, t) => a + t.pnl, 0) }; }).filter(e => e.count > 0).sort((a, b) => b.pnl - a.pnl);
  const mistakePerf = allMistakes.map(m => { const mk = trades.filter(t => getMistakes(t).includes(m)); return { name: m, count: mk.length, pnl: mk.reduce((a, t) => a + t.pnl, 0) }; }).filter(m => m.count > 0).sort((a, b) => b.pnl - a.pnl);
  const sessPerf = SESSIONS.map(s => { const st = trades.filter(t => t.session === s); return { name: s, count: st.length, pnl: st.reduce((a, t) => a + t.pnl, 0) }; }).filter(s => s.count > 0);

  // Calculate streaks
  const calculateDayStreaks = () => {
    // Group trades by date and calculate daily P&L
    const dailyMap = {};
    trades.forEach(t => {
      const date = t.date.split('T')[0];
      if (!dailyMap[date]) dailyMap[date] = 0;
      dailyMap[date] += t.pnl;
    });

    const sortedDays = Object.keys(dailyMap).sort();
    let currentStreak = 0;
    let currentType = null;
    let bestWinStreak = 0;
    let bestLossStreak = 0;

    sortedDays.forEach(day => {
      const isWin = dailyMap[day] > 0;
      if (currentType === null) {
        currentType = isWin ? 'win' : 'loss';
        currentStreak = 1;
      } else if ((isWin && currentType === 'win') || (!isWin && currentType === 'loss')) {
        currentStreak++;
      } else {
        if (currentType === 'win') bestWinStreak = Math.max(bestWinStreak, currentStreak);
        else bestLossStreak = Math.max(bestLossStreak, currentStreak);
        currentType = isWin ? 'win' : 'loss';
        currentStreak = 1;
      }
    });

    if (currentType === 'win') bestWinStreak = Math.max(bestWinStreak, currentStreak);
    else bestLossStreak = Math.max(bestLossStreak, currentStreak);

    const lastDayType = sortedDays.length > 0 ? (dailyMap[sortedDays[sortedDays.length - 1]] > 0 ? 'win' : 'loss') : null;

    return {
      current: lastDayType === currentType ? currentStreak : 0,
      currentType: lastDayType,
      bestWin: bestWinStreak,
      bestLoss: bestLossStreak
    };
  };

  const calculateTradeStreaks = () => {
    if (trades.length === 0) return { current: 0, currentType: null, bestWin: 0, bestLoss: 0 };

    const sortedTrades = [...trades].sort((a, b) => new Date(a.date) - new Date(b.date));
    let currentStreak = 0;
    let currentType = null;
    let bestWinStreak = 0;
    let bestLossStreak = 0;

    sortedTrades.forEach(t => {
      const isWin = t.pnl > 0;
      if (currentType === null) {
        currentType = isWin ? 'win' : 'loss';
        currentStreak = 1;
      } else if ((isWin && currentType === 'win') || (!isWin && currentType === 'loss')) {
        currentStreak++;
      } else {
        if (currentType === 'win') bestWinStreak = Math.max(bestWinStreak, currentStreak);
        else bestLossStreak = Math.max(bestLossStreak, currentStreak);
        currentType = isWin ? 'win' : 'loss';
        currentStreak = 1;
      }
    });

    if (currentType === 'win') bestWinStreak = Math.max(bestWinStreak, currentStreak);
    else bestLossStreak = Math.max(bestLossStreak, currentStreak);

    const lastTradeType = sortedTrades.length > 0 ? (sortedTrades[sortedTrades.length - 1].pnl > 0 ? 'win' : 'loss') : null;

    return {
      current: lastTradeType === currentType ? currentStreak : 0,
      currentType: lastTradeType,
      bestWin: bestWinStreak,
      bestLoss: bestLossStreak
    };
  };

  const dayStreaks = calculateDayStreaks();
  const tradeStreaks = calculateTradeStreaks();

  // Helper function to format time in MM:SS format
  const formatTime = (seconds) => {
    const mins = Math.floor(seconds / 60);
    const secs = seconds % 60;
    return `${mins}:${secs.toString().padStart(2, '0')}`;
  };

  return (
    <div style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", background: isDark ? "#06060d" : "#f9f9f2", minHeight: "100vh", color: "#ffffff" }}>
      <style>{`
        body { background: ${isDark ? "#06060d" : "#f9f9f2"}; margin: 0; }
        *{box-sizing:border-box;margin:0;padding:0;}
        ::-webkit-scrollbar{width:8px;}::-webkit-scrollbar-track{background:rgba(255,255,255,0.03);border-radius:10px;}::-webkit-scrollbar-thumb{background:rgba(255,255,255,0.12);border-radius:10px;border:2px solid transparent;background-clip:padding-box;}::-webkit-scrollbar-thumb:hover{background:rgba(255,255,255,0.18);background-clip:padding-box;}
        .nb{background:rgba(255,255,255,0.04);border:none;cursor:pointer;padding:10px 18px;border-radius:12px;font-family:-apple-system,BlinkMacSystemFont,'SF Mono','Monaco','Menlo','Consolas','Roboto Mono',monospace;font-size:11px;letter-spacing:.08em;transition:all .4s cubic-bezier(0.2, 0.8, 0.2, 1);color:#ffffff;text-transform:uppercase;position:relative;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);}
        .nb.on{color:#fff;background:rgba(255,255,255,0.12);backdrop-filter:blur(20px) saturate(180%);-webkit-backdrop-filter:blur(20px) saturate(180%);box-shadow:0 2px 12px rgba(0,0,0,0.2), 0 0 0 0.5px rgba(255,255,255,0.15), inset 0 1px 0 rgba(255,255,255,0.2), inset 0 -1px 0 rgba(255,255,255,0.05);}
        .nb:hover:not(.on){color:#ffffff;background:rgba(255,255,255,0.07);}
        .nb:active{transform:scale(0.96);}
        .card{background:rgba(255,255,255,0.06);backdrop-filter:blur(40px) saturate(180%);-webkit-backdrop-filter:blur(40px) saturate(180%);border:1px solid rgba(255,255,255,0.12);border-radius:16px;padding:24px;box-shadow:0 8px 32px rgba(0,0,0,0.2), inset 0 1px 0 rgba(255,255,255,0.1);}
        .gbtn{background:rgba(127,255,178,0.9);color:#06060d;border:none;cursor:pointer;padding:12px 24px;border-radius:12px;font-family:-apple-system,BlinkMacSystemFont,'SF Mono','Monaco','Menlo','Consolas','Roboto Mono',monospace;font-size:11px;font-weight:600;letter-spacing:.1em;transition:all .3s cubic-bezier(0.4, 0.0, 0.2, 1);text-transform:uppercase;box-shadow:0 4px 16px rgba(127,255,178,0.3), inset 0 1px 0 rgba(255,255,255,0.4);}
        .gbtn:hover{background:rgba(127,255,178,1);transform:translateY(-2px);box-shadow:0 8px 24px rgba(127,255,178,0.4), inset 0 1px 0 rgba(255,255,255,0.5);}
        .gbtn:disabled{opacity:.5;cursor:not-allowed;transform:none;}
        .ghost{background:rgba(255,255,255,0.04);border:1px solid rgba(255,255,255,0.1);color:#ffffff;cursor:pointer;padding:8px 16px;border-radius:10px;font-family:-apple-system,BlinkMacSystemFont,'SF Mono','Monaco','Menlo','Consolas','Roboto Mono',monospace;font-size:10px;letter-spacing:.08em;transition:all .3s cubic-bezier(0.4, 0.0, 0.2, 1);text-transform:uppercase;backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);}
        .ghost:hover{border-color:rgba(127,255,178,0.4);background:rgba(127,255,178,0.08);color:#7fffb2;box-shadow:0 4px 12px rgba(127,255,178,0.15);}
        input,select,textarea{background:rgba(255,255,255,0.05);border:1px solid rgba(255,255,255,0.1);color:#ffffff;padding:10px 14px;border-radius:10px;font-family:-apple-system,BlinkMacSystemFont,'SF Mono','Monaco','Menlo','Consolas','Roboto Mono',monospace;font-size:12px;width:100%;transition:all .3s cubic-bezier(0.4, 0.0, 0.2, 1);outline:none;backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);}
        input:focus,select:focus,textarea:focus{border-color:rgba(127,255,178,0.6);background:rgba(255,255,255,0.08);box-shadow:0 0 0 3px rgba(127,255,178,0.1), inset 0 1px 0 rgba(255,255,255,0.1);}
        select option{background:#0a0a14;}
        .pos{color:#7fffb2;}.neg{color:#ff4466;}
        .tag{display:inline-block;padding:2px 7px;border-radius:3px;font-size:10px;letter-spacing:.05em;}
        .ai-text{white-space:pre-wrap;line-height:1.8;font-size:12px;color:#ffffff;font-style:italic;opacity:0.8;}
        .trow{border-bottom:1px solid rgba(255,255,255,0.06);transition:all .3s cubic-bezier(0.4, 0.0, 0.2, 1);cursor:pointer;}
        .trow:hover{background:rgba(255,255,255,0.04);transform:scale(1.002);}
        .pulse{animation:p 1.8s infinite;}
        @keyframes p{0%,100%{opacity:1;}50%{opacity:.4;}}
        .ov{position:fixed;inset:0;background:rgba(0,0,0,.75);z-index:50;display:flex;align-items:center;justify-content:center;padding:20px;backdrop-filter:blur(20px) saturate(120%);-webkit-backdrop-filter:blur(20px) saturate(120%);}
        .modal{background:rgba(12,12,24,0.85);backdrop-filter:blur(60px) saturate(180%);-webkit-backdrop-filter:blur(60px) saturate(180%);border:1px solid rgba(255,255,255,0.15);border-radius:20px;padding:32px;width:100%;max-width:580px;max-height:92vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.15);}
        .lbl{font-size:10px;color:#ffffff;letter-spacing:.1em;text-transform:uppercase;margin-bottom:6px;display:block;opacity:0.7;}
        .tv-badge{display:inline-block;padding:1px 5px;border-radius:3px;font-size:8px;letter-spacing:.1em;background:rgba(0,221,255,.1);color:#00ddff;margin-left:6px;vertical-align:middle;}
      `}</style>

      {/* THEME TOGGLE */}
      <div style={{
        position: "fixed",
        bottom: 24,
        left: sidebarOpen ? "calc(260px / 2 - 22px)" : "calc(70px / 2 - 22px)",
        zIndex: 100,
        transition: "left 0.3s cubic-bezier(0.4, 0, 0.2, 1)"
      }}>
        <button className="ghost" onClick={() => setIsDark(d => !d)} style={{ width: 44, height: 44, borderRadius: "50%", padding: 0, display: "flex", alignItems: "center", justifyContent: "center", background: isDark ? "#111120" : "#ffffff", border: `1px solid ${isDark ? "#222235" : "#e0e0e0"}`, boxShadow: "0 4px 12px rgba(0,0,0,0.1)", fontSize: 20 }}>
          {isDark ? "☀️" : "🌙"}
        </button>
      </div>

      <div style={{
        background: "linear-gradient(135deg, #06060d 0%, #0a0a15 50%, #0d0d1a 100%)",
        minHeight: "100vh",
        filter: isDark ? "none" : "invert(1) hue-rotate(180deg)",
        transition: "filter 0.3s ease"
      }}>
        {/* LEFT SIDEBAR */}
        <style>
          {`
            .sidebar {
              position: fixed;
              left: 0;
              top: 0;
              height: 100vh;
              background: rgba(8,8,16,0.95);
              backdrop-filter: blur(30px) saturate(150%);
              -webkit-backdrop-filter: blur(30px) saturate(150%);
              border-right: 1px solid rgba(255,255,255,0.08);
              display: flex;
              flex-direction: column;
              transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
              z-index: 50;
              box-shadow: 2px 0 24px rgba(0,0,0,0.2);
            }

            .sidebar-nav-item {
              display: flex;
              align-items: center;
              gap: 12px;
              padding: 12px 12px;
              margin: 4px 12px;
              border-radius: 10px;
              cursor: pointer;
              font-family: -apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace;
              font-size: 13px;
              letter-spacing: 0.5px;
              color: #ffffff;
              transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
              border: none;
              background: none;
              text-align: left;
              width: calc(100% - 24px);
              white-space: nowrap;
              overflow: hidden;
            }

            .sidebar-nav-item:hover {
              background: rgba(255,255,255,0.05);
              color: #ffffff;
            }

            .sidebar-nav-item-active {
              background: rgba(255,255,255,0.1);
              color: #fff;
              box-shadow: 0 2px 8px rgba(0,0,0,0.15), inset 0 1px 0 rgba(255,255,255,0.1);
            }

            .sidebar-nav-icon {
              font-size: 18px;
              flex-shrink: 0;
              width: 24px;
              text-align: center;
            }

            .sidebar-nav-text {
              opacity: 1;
              transition: opacity 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            }

            .sidebar-collapsed .sidebar-nav-text {
              opacity: 0;
              width: 0;
            }

            .sidebar-action-btn {
              display: flex;
              align-items: center;
              justify-content: center;
              gap: 8px;
              padding: 12px 12px;
              margin: 6px 12px;
              border-radius: 10px;
              cursor: pointer;
              font-family: 'DM Mono', monospace;
              font-size: 12px;
              font-weight: 600;
              letter-spacing: 0.5px;
              transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
              border: 1px solid rgba(255,255,255,0.15);
              background: rgba(255,255,255,0.08);
              color: rgba(255,255,255,0.85);
              white-space: nowrap;
              overflow: hidden;
            }

            .sidebar-action-btn:hover {
              background: rgba(255,255,255,0.12);
              border-color: rgba(255,255,255,0.25);
              transform: translateY(-1px);
            }

            .sidebar-action-btn-primary {
              background: rgba(124,165,212,0.2);
              border-color: rgba(124,165,212,0.3);
              color: #7ca5d4;
            }

            .sidebar-action-btn-primary:hover {
              background: rgba(124,165,212,0.3);
              border-color: rgba(124,165,212,0.4);
            }

            .sidebar-action-btn-danger {
              background: rgba(228,94,84,0.15);
              border-color: rgba(228,94,84,0.25);
              color: #ff4466;
            }

            .sidebar-action-btn-danger:hover {
              background: rgba(228,94,84,0.25);
              border-color: rgba(228,94,84,0.35);
            }

            .sidebar-toggle {
              position: absolute;
              right: -12px;
              top: 24px;
              width: 24px;
              height: 24px;
              border-radius: 50%;
              background: rgba(8,8,16,0.95);
              border: 1px solid rgba(255,255,255,0.15);
              display: flex;
              align-items: center;
              justify-content: center;
              cursor: pointer;
              transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
              color: rgba(255,255,255,0.6);
              font-size: 12px;
            }

            .sidebar-toggle:hover {
              background: rgba(124,165,212,0.2);
              border-color: rgba(124,165,212,0.3);
              color: #7ca5d4;
              transform: scale(1.1);
            }

            .lyra-nav-text {
              font-family: 'Courier New', Courier, monospace;
              font-weight: 800;
              font-size: 13px;
              letter-spacing: 1px;
            }
          `}
        </style>

        <div className={`sidebar ${sidebarOpen ? '' : 'sidebar-collapsed'}`} style={{ width: sidebarOpen ? '260px' : '70px' }}>
          {/* Toggle Button */}
          <div className="sidebar-toggle" onClick={() => setSidebarOpen(!sidebarOpen)}>
            {sidebarOpen ? '‹' : '›'}
          </div>

          {/* Logo */}
          <div style={{
            padding: '24px 20px',
            borderBottom: '1px solid rgba(255,255,255,0.08)',
            cursor: 'pointer',
            transition: 'opacity 0.2s'
          }}
          onClick={() => setView("dashboard")}
          onMouseEnter={(e) => e.currentTarget.style.opacity = "0.7"}
          onMouseLeave={(e) => e.currentTarget.style.opacity = "1"}
          >
            <div style={{
              fontFamily: "'Courier New', Courier, monospace",
              fontWeight: 700,
              fontSize: sidebarOpen ? 24 : 20,
              letterSpacing: "1px",
              filter: isDark ? "none" : "invert(1) hue-rotate(180deg)",
              transition: 'font-size 0.3s cubic-bezier(0.4, 0, 0.2, 1)',
              textAlign: sidebarOpen ? 'left' : 'center'
            }}>
              {sidebarOpen ? (
                <>
                  <span style={{ color: "#e45e54" }}>u</span>
                  <span style={{ color: "#f28b57" }}>l</span>
                  <span style={{ color: "#fabf53" }}>t</span>
                  <span style={{ color: "#8bc268" }}>r</span>
                  <span style={{ color: "#7ca5d4" }}>a</span>
                  <span style={{ color: "#a08ecc" }}>t</span>
                  <span style={{ color: "#c581b6" }}>r</span>
                  <span style={{ color: "#e45e54" }}>a</span>
                  <span style={{ color: "#f28b57" }}>c</span>
                  <span style={{ color: "#fabf53" }}>k</span>
                </>
              ) : (
                <>
                  <span style={{ color: "#e45e54" }}>u</span>
                  <span style={{ color: "#7ca5d4" }}>t</span>
                </>
              )}
            </div>
          </div>

          {/* Navigation Items */}
          <div style={{ flex: 1, padding: '16px 0', overflowY: 'auto', overflowX: 'hidden' }}>
            <button
              className={`sidebar-nav-item ${view === "dashboard" ? "sidebar-nav-item-active" : ""}`}
              onClick={() => setView("dashboard")}
            >
              <span className="sidebar-nav-icon">📊</span>
              {sidebarOpen && <span className="sidebar-nav-text">Dashboard</span>}
            </button>

            <button
              className={`sidebar-nav-item ${view === "trades" ? "sidebar-nav-item-active" : ""}`}
              onClick={() => setView("trades")}
            >
              <span className="sidebar-nav-icon">💹</span>
              {sidebarOpen && <span className="sidebar-nav-text">Trades</span>}
            </button>

            <button
              className={`sidebar-nav-item ${view === "journal" ? "sidebar-nav-item-active" : ""}`}
              onClick={() => setView("journal")}
            >
              <span className="sidebar-nav-icon">📝</span>
              {sidebarOpen && <span className="sidebar-nav-text">Journal</span>}
            </button>

            <button
              className={`sidebar-nav-item ${view === "analytics" ? "sidebar-nav-item-active" : ""}`}
              onClick={() => setView("analytics")}
            >
              <span className="sidebar-nav-icon">📈</span>
              {sidebarOpen && <span className="sidebar-nav-text">Analytics</span>}
            </button>

            <button
              className={`sidebar-nav-item ${view === "videos" ? "sidebar-nav-item-active" : ""}`}
              onClick={() => setView("videos")}
            >
              <span className="sidebar-nav-icon">🎥</span>
              {sidebarOpen && <span className="sidebar-nav-text">Videos</span>}
            </button>

            <button
              className={`sidebar-nav-item ${view === "ai-coach" ? "sidebar-nav-item-active" : ""}`}
              onClick={() => setView("ai-coach")}
              style={{
                background: view === "ai-coach"
                  ? "rgba(124,165,212,0.2)"
                  : "transparent",
                boxShadow: view === "ai-coach"
                  ? "0 2px 8px rgba(0,0,0,0.15), 0 0 16px rgba(124,165,212,0.15)"
                  : "none"
              }}
            >
              <span className="sidebar-nav-icon">✨</span>
              {sidebarOpen && (
                <span className="lyra-nav-text">
                  <span style={{ color: "#7ca5d4" }}>l</span>
                  <span style={{ color: "#8bc268" }}>y</span>
                  <span style={{ color: "#e45e54" }}>r</span>
                  <span style={{ color: "#fabf53" }}>a</span>
                </span>
              )}
            </button>
          </div>

          {/* Action Buttons */}
          <div style={{
            padding: '16px 0 80px',
            borderTop: '1px solid rgba(255,255,255,0.08)'
          }}>
            <button
              className="sidebar-action-btn"
              onClick={() => { setShowImport(true); setImportResult(null); setImportPreview(null); }}
            >
              <span>📥</span>
              {sidebarOpen && <span>Import CSV</span>}
            </button>

            <button
              className="sidebar-action-btn sidebar-action-btn-primary"
              onClick={() => setShowForm(true)}
            >
              <span>+</span>
              {sidebarOpen && <span>Log Trade</span>}
            </button>

            <button
              className="sidebar-action-btn sidebar-action-btn-danger"
              onClick={() => auth.signOut()}
              title={`Signed in as ${user.email}`}
            >
              <span>🚪</span>
              {sidebarOpen && <span>Logout</span>}
            </button>
          </div>
        </div>

        <div style={{
          marginLeft: sidebarOpen ? '260px' : '70px',
          padding: "24px 48px",
          maxWidth: 1600,
          transition: 'margin-left 0.3s cubic-bezier(0.4, 0, 0.2, 1)'
        }}>

          {/* DASHBOARD */}
          {view === "dashboard" && (
            <div>
              {/* Header with Share Buttons */}
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 16 }}>
                <h2 style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 18, fontWeight: 700, color: "#fff", margin: 0 }}>Performance Overview</h2>
                <div style={{ display: "flex", gap: 8 }}>
                  <button onClick={() => setSharePnLCard("daily")} className="ghost" style={{ padding: "6px 12px", fontSize: 10 }} title="Share daily P&L card">
                    📤 Daily
                  </button>
                  <button onClick={() => setSharePnLCard("weekly")} className="ghost" style={{ padding: "6px 12px", fontSize: 10 }} title="Share weekly P&L card">
                    📤 Weekly
                  </button>
                  <button onClick={() => setSharePnLCard("monthly")} className="ghost" style={{ padding: "6px 12px", fontSize: 10 }} title="Share monthly P&L card">
                    📤 Monthly
                  </button>
                </div>
              </div>

              <div style={{ display: "grid", gridTemplateColumns: "repeat(5,1fr)", gap: 12, marginBottom: 20 }}>
                {[
                  { l: "Net P&L", v: `${totalPnl >= 0 ? "+" : ""}$${totalPnl.toLocaleString()}`, pos: totalPnl >= 0, big: true },
                  { l: "Win Rate", v: `${winRate}%`, pos: winRate >= 50 },
                  { l: "Profit Factor", v: profitFactor, pos: parseFloat(profitFactor) >= 1.5 },
                  { l: "Avg Win", v: `+$${avgWin.toFixed(0)}`, pos: true },
                  { l: "Max Drawdown", v: `-$${maxDD.toFixed(0)}`, pos: false },
                ].map(s => (
                  <div key={s.l} style={{ background: "#090912", border: "1px solid #131325", borderRadius: 6, padding: "14px 16px", position: "relative" }}>
                    <p className="lbl" style={{ marginBottom: 8 }}>{s.l}</p>
                    <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: s.big ? 22 : 18, fontWeight: 700, color: s.pos ? "#7fffb2" : "#ff4466" }}>{s.v}</p>
                    {s.l === "Net P&L" && (
                      <p style={{ position: "absolute", top: 14, right: 16, fontSize: 13, color: "#d0d0d0", margin: 0, fontWeight: 500 }}>{trades.length}</p>
                    )}
                  </div>
                ))}
              </div>

              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 12 }}>
                <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 16, fontWeight: 700, color: "#fff", margin: 0 }}></p>
                <div style={{ display: "flex", gap: 6 }}>
                  {["This Week", "This Month", "All Time"].map(tf => (
                    <button key={tf} className={`nb ${chartTimeframe === tf ? "on" : ""}`} style={{ border: "1px solid #181828", padding: "6px 12px", fontSize: 11 }} onClick={() => setChartTimeframe(tf)}>{tf}</button>
                  ))}
                </div>
              </div>

              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16, marginBottom: 16 }}>
                {/* Daily P&L Chart */}
                <div className="card">
                  <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 20 }}>
                    <p className="lbl" style={{ margin: 0, fontSize: 13, color: "#fff" }}>Net daily P&L</p>
                    <span style={{ color: "#8a8aa8", cursor: "pointer", fontSize: 13 }} title="View your daily net profit and loss">ⓘ</span>
                  </div>

                  <div style={{ display: "flex", height: 160, position: "relative" }}>
                    {/* Y-axis labels */}
                    <div style={{ width: 60, display: "flex", flexDirection: "column", justifyContent: "space-between", paddingRight: 10, alignItems: "flex-end", color: "#d0d0d0", fontSize: 11, fontFamily: "Inter, sans-serif" }}>
                      <span>${maxDailyPnl >= 1000 ? (maxDailyPnl / 1000).toFixed(1) + 'k' : maxDailyPnl}</span>
                      <span>${(maxDailyPnl * 0.8).toFixed(0)}</span>
                      <span>${(maxDailyPnl * 0.6).toFixed(0)}</span>
                      <span>${(maxDailyPnl * 0.4).toFixed(0)}</span>
                      <span>${(maxDailyPnl * 0.2).toFixed(0)}</span>
                      <span>$0</span>
                    </div>

                    {/* Chart and Grid */}
                    <div style={{ flex: 1, display: "flex", flexDirection: "column", justifyContent: "space-between", position: "relative" }}>

                      {/* Horizontal grid lines */}
                      {[1, 0.8, 0.6, 0.4, 0.2, 0].map((level, i) => (
                        <div key={i} style={{ position: "absolute", bottom: `${level * 100}%`, left: 0, right: 0, height: 1, borderTop: "1px dashed #222235", opacity: 0.6 }} />
                      ))}

                      <div style={{ flex: 1, display: "flex", alignItems: "flex-end", gap: dailyPnl.length <= 7 ? "8%" : "2%", padding: "0 2%", position: "relative", zIndex: 1, justifyContent: dailyPnl.length <= 7 ? "space-around" : "flex-start" }}>
                        {dailyPnl.slice(Math.max(0, dailyPnl.length - 30)).map((d, i) => {
                          const h = Math.max(2, (Math.abs(d.pnl) / maxDailyPnl) * 100);
                          const isPositive = d.pnl >= 0;

                          // Pick a few distinct dates to show underneath - show max 3-4 labels
                          // For small datasets (<=3), show all. For larger, show first, last, and evenly spaced in between
                          const maxLabels = 4;
                          const labelInterval = dailyPnl.length <= 3 ? 1 : Math.max(Math.ceil(dailyPnl.length / (maxLabels - 1)), 2);
                          const showLabel = dailyPnl.length <= 3 || i === 0 || i === dailyPnl.length - 1 || (i % labelInterval === 0 && i < dailyPnl.length - labelInterval);

                          return (
                            <div key={i} style={{ display: "flex", flexDirection: "column", alignItems: "center", height: "100%", justifyContent: "flex-end", flex: 1, maxWidth: 30, position: "relative" }}>
                              {isPositive && (
                                <div
                                  style={{ width: "100%", height: `${h}%`, background: "#51A877", transition: "opacity 0.2s ease" }}
                                  title={`${formatDateDisplay(d.date)}: +$${d.pnl.toLocaleString()}`}
                                  onMouseEnter={(e) => { e.currentTarget.style.opacity = 0.8; }}
                                  onMouseLeave={(e) => { e.currentTarget.style.opacity = 1; }}
                                />
                              )}
                              {!isPositive && (
                                /* Placeholder logic for negative layout if needed to look like screenshot where all are above 0 usually, but logic exists */
                                <div
                                  style={{ width: "100%", height: `${h}%`, background: "#ff4466", transition: "opacity 0.2s ease", marginTop: "auto" }}
                                  title={`${formatDateDisplay(d.date)}: -$${Math.abs(d.pnl).toLocaleString()}`}
                                  onMouseEnter={(e) => { e.currentTarget.style.opacity = 0.8; }}
                                  onMouseLeave={(e) => { e.currentTarget.style.opacity = 1; }}
                                />
                              )}

                              {/* Attached label underneath bar */}
                              {showLabel && (
                                <div style={{ position: "absolute", bottom: -24, left: "50%", transform: "translateX(-50%)", textAlign: "center", whiteSpace: "nowrap" }}>
                                  <p style={{ fontSize: 10, color: "#8a8aa8", margin: 0 }}>
                                    {formatDateDisplay(d.date)}
                                  </p>
                                </div>
                              )}
                            </div>
                          );
                        })}
                      </div>
                    </div>
                  </div>
                  {/* Spacer for bottom labels */}
                  <div style={{ height: 24 }} />
                </div>

                {/* Cumulative P&L Chart */}
                <div className="card">
                  <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 20 }}>
                    <p className="lbl" style={{ margin: 0, fontSize: 13, color: "#fff" }}>Daily net cumulative P&L</p>
                    <span style={{ color: "#8a8aa8", cursor: "pointer", fontSize: 13 }} title="View your cumulative profit and loss over time">ⓘ</span>
                  </div>

                  <div style={{ display: "flex", height: 160, position: "relative" }}>
                    {/* Y-axis labels */}
                    <div style={{ width: 60, display: "flex", flexDirection: "column", justifyContent: "space-between", paddingRight: 10, alignItems: "flex-end", color: "#d0d0d0", fontSize: 11, fontFamily: "Inter, sans-serif", zIndex: 2 }}>
                      {[1, 0.5, 0, -0.5, -1].map((level, i) => (
                        <span key={i}>{level < 0 ? "-" : ""}${Math.abs(maxCumPnl * level).toLocaleString(undefined, { maximumFractionDigits: 0 })}</span>
                      ))}
                    </div>

                    {/* Chart and Grid */}
                    <div style={{ flex: 1, position: "relative", paddingTop: 5, paddingBottom: 5 }}>

                      {/* Horizontal grid lines */}
                      {[1, 0.5, 0, -0.5, -1].map((level, i) => (
                        <div key={i} style={{ position: "absolute", top: `${(1 - level) / 2 * 100}%`, left: 0, right: 0, height: 1, borderTop: "1px dashed #222235", opacity: 0.6 }} />
                      ))}

                      {/* Line chart with filled area */}
                      <svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="none" style={{ position: "relative", zIndex: 1, overflow: "visible" }}>
                        <defs>
                          <linearGradient id="areaGrad" x1="0" y1="0" x2="0" y2="1">
                            <stop offset="0%" stopColor="#51A877" stopOpacity="0.5" />
                            <stop offset="100%" stopColor="#51A877" stopOpacity="0.0" />
                          </linearGradient>
                          <linearGradient id="lineGrad" x1="0" y1="0" x2="1" y2="0">
                            <stop offset="0%" stopColor="#8b5cf6" />
                            <stop offset="100%" stopColor="#00ddff" />
                          </linearGradient>
                        </defs>

                        {/* Area Polygon */}
                        <polygon
                          points={`0,50 ${cumulativePnl.slice(Math.max(0, cumulativePnl.length - 30)).map((d, i, arr) => {
                            const x = (i / Math.max(1, arr.length - 1)) * 100;
                            const y = 50 - ((d.cumPnl / maxCumPnl) * 50);
                            return `${x},${y}`;
                          }).join(' ')} 100,50`}
                          fill="url(#areaGrad)"
                        />

                        {/* Top Line */}
                        <polyline
                          points={cumulativePnl.slice(Math.max(0, cumulativePnl.length - 30)).map((d, i, arr) => {
                            const x = (i / Math.max(1, arr.length - 1)) * 100;
                            const y = 50 - ((d.cumPnl / maxCumPnl) * 50);
                            return `${x},${y}`;
                          }).join(' ')}
                          fill="none"
                          stroke="url(#lineGrad)"
                          strokeWidth="2"
                          vectorEffect="non-scaling-stroke"
                        />
                      </svg>

                      {/* Date labels mapped similarly to bars/lines below the chart */}
                      <div style={{ position: "absolute", bottom: -18, left: 0, right: 0, paddingLeft: "2%", paddingRight: "2%" }}>
                        {cumulativePnl.slice(Math.max(0, cumulativePnl.length - 30)).map((d, i, arr) => {
                          const maxLabels = 4;
                          const labelInterval = arr.length <= 3 ? 1 : Math.max(Math.ceil(arr.length / (maxLabels - 1)), 2);
                          const showLabel = arr.length <= 3 || i === 0 || i === arr.length - 1 || (i % labelInterval === 0 && i < arr.length - labelInterval);
                          const xPercent = (i / Math.max(1, arr.length - 1)) * 100;
                          // Adjust transform for first and last labels to prevent overflow
                          let transform = "translateX(-50%)";
                          if (i === 0) transform = "translateX(0)";
                          if (i === arr.length - 1) transform = "translateX(-100%)";

                          return showLabel ? (
                            <div key={i} style={{ position: "absolute", left: `${xPercent}%`, transform, textAlign: "center", whiteSpace: "nowrap" }}>
                              <p style={{ fontSize: 10, color: "#8a8aa8", margin: 0 }}>
                                {formatDateDisplay(d.date)}
                              </p>
                            </div>
                          ) : null;
                        })}
                      </div>

                    </div>
                  </div>

                  {/* Spacer for bottom labels */}
                  <div style={{ height: 24 }} />
                </div>
              </div>

              {/* CALENDAR */}
              <div style={{ marginTop: 20 }}>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 20 }}>
                  <div>
                    <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 20, fontWeight: 700, color: "#fff", marginBottom: 4 }}>Trading Calendar</p>
                    <p style={{ color: "#ffffff", fontSize: 11, letterSpacing: ".05em" }}>Daily performance breakdown</p>
                  </div>
                  <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
                    <button className="ghost" onClick={() => setCalendarDate(d => new Date(d.getFullYear(), d.getMonth() - 1, 1))}>←</button>
                    <span style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700, fontSize: 16, color: "#fff", minWidth: 180, textAlign: "center" }}>
                      {calendarDate.toLocaleDateString("en-US", { month: "long", year: "numeric" })}
                    </span>
                    <button className="ghost" onClick={() => setCalendarDate(d => new Date(d.getFullYear(), d.getMonth() + 1, 1))}>→</button>
                    <button className="ghost" onClick={() => setCalendarDate(new Date())}>Today</button>
                  </div>
                </div>

                <div className="card" style={{ padding: 20 }}>
                  {(() => {
                    const year = calendarDate.getFullYear();
                    const month = calendarDate.getMonth();
                    const firstDay = new Date(year, month, 1).getDay();
                    const daysInMonth = new Date(year, month + 1, 0).getDate();

                    // Group trades by date
                    const tradesByDate = {};
                    trades.forEach(t => {
                      // Normalize date to YYYY-MM-DD format
                      let dateKey = t.date;
                      if (dateKey && dateKey.includes('T')) {
                        dateKey = dateKey.split('T')[0];
                      }
                      if (dateKey && dateKey.includes(' ')) {
                        dateKey = dateKey.split(' ')[0];
                      }
                      if (!dateKey) return;

                      if (!tradesByDate[dateKey]) {
                        tradesByDate[dateKey] = [];
                      }
                      tradesByDate[dateKey].push(t);
                    });

                    // Calculate stats for each date
                    const dateStats = {};
                    Object.keys(tradesByDate).forEach(dateKey => {
                      const dayTrades = tradesByDate[dateKey];
                      const wins = dayTrades.filter(t => t.pnl > 0).length;
                      const totalPnl = dayTrades.reduce((sum, t) => sum + t.pnl, 0);
                      const winRate = dayTrades.length > 0 ? Math.round((wins / dayTrades.length) * 100) : 0;
                      dateStats[dateKey] = {
                        count: dayTrades.length,
                        pnl: totalPnl,
                        winRate: winRate
                      };
                    });

                    // Build calendar with weekly summaries in right column
                    const calendarRows = [];
                    const weekSummaries = [];
                    let currentRow = [];
                    let weekNumber = 1;
                    let weekStats = { pnl: 0, daysTraded: 0 };

                    // Add empty cells for days before month starts
                    for (let i = 0; i < firstDay; i++) {
                      currentRow.push(<div key={`empty-${i}`} style={{ padding: 8, minHeight: 90 }} />);
                    }

                    // Add calendar days
                    const todayDate = getTodayLocalDate();
                    for (let day = 1; day <= daysInMonth; day++) {
                      const dateKey = `${year}-${String(month + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
                      const stats = dateStats[dateKey];
                      const isToday = todayDate === dateKey;

                      // Track weekly stats
                      if (stats) {
                        weekStats.pnl += stats.pnl;
                        weekStats.daysTraded += 1;
                      }

                      currentRow.push(
                        <div
                          key={day}
                          onClick={() => {
                            if (stats) {
                              setSelectedCalendarDate({
                                date: dateKey,
                                trades: tradesByDate[dateKey],
                                stats: stats
                              });
                            }
                          }}
                          style={{
                            padding: 8,
                            minHeight: 90,
                            background: stats ? (stats.pnl >= 0 ? "rgba(127,255,178,0.08)" : "rgba(255,68,102,0.08)") : "#09090f",
                            border: isToday ? "2px solid #7fffb2" : "1px solid #0f0f1e",
                            borderRadius: 6,
                            position: "relative",
                            cursor: stats ? "pointer" : "default",
                            transition: "all 0.2s"
                          }}
                          onMouseEnter={(e) => { if (stats) e.currentTarget.style.transform = "scale(1.02)"; }}
                          onMouseLeave={(e) => { if (stats) e.currentTarget.style.transform = "scale(1)"; }}
                        >
                          <div style={{ fontSize: 11, color: isToday ? "#7fffb2" : "#e0e0e0", marginBottom: 6, fontWeight: isToday ? 700 : 400 }}>{day}</div>
                          {stats && (
                            <div style={{ fontSize: 10 }}>
                              <div style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700, fontSize: 13, marginBottom: 4 }} className={stats.pnl >= 0 ? "pos" : "neg"}>
                                {stats.pnl >= 0 ? "+" : ""}${stats.pnl.toLocaleString()}
                              </div>
                              <div style={{ color: "#d0d0d0", marginBottom: 2 }}>{stats.count} trade{stats.count !== 1 ? 's' : ''}</div>
                              <div style={{ color: stats.winRate >= 50 ? "#7fffb2" : "#ff4466", fontSize: 9 }}>{stats.winRate}% win</div>
                            </div>
                          )}
                        </div>
                      );

                      // End of week (Saturday) or end of month
                      if (currentRow.length === 7 || day === daysInMonth) {
                        // Fill remaining cells if needed
                        while (currentRow.length < 7) {
                          currentRow.push(<div key={`empty-end-${currentRow.length}`} style={{ padding: 8, minHeight: 90 }} />);
                        }

                        // Add the week row to calendar
                        calendarRows.push(currentRow);

                        // Add weekly summary
                        weekSummaries.push({
                          week: weekNumber,
                          pnl: weekStats.pnl,
                          daysTraded: weekStats.daysTraded
                        });

                        // Reset for next week
                        currentRow = [];
                        weekNumber++;
                        weekStats = { pnl: 0, daysTraded: 0 };
                      }
                    }

                    return (
                      <div>
                        {/* Header row */}
                        <div style={{ display: "grid", gridTemplateColumns: "1fr 140px", gap: 16, marginBottom: 8 }}>
                          <div style={{ display: "grid", gridTemplateColumns: "repeat(7, 1fr)", gap: 8 }}>
                            {["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"].map(d => (
                              <div key={d} style={{ textAlign: "center", fontSize: 10, color: "#d0d0d0", letterSpacing: ".1em", padding: "8px 0" }}>{d}</div>
                            ))}
                          </div>
                          <div style={{ textAlign: "center", fontSize: 10, color: "#d0d0d0", letterSpacing: ".1em", padding: "8px 0" }}>WEEKLY</div>
                        </div>

                        {/* Calendar rows with weekly summaries */}
                        {calendarRows.map((row, idx) => (
                          <div key={`row-${idx}`} style={{ display: "grid", gridTemplateColumns: "1fr 140px", gap: 16, marginBottom: 8 }}>
                            <div style={{ display: "grid", gridTemplateColumns: "repeat(7, 1fr)", gap: 8 }}>
                              {row}
                            </div>
                            <div style={{
                              padding: 12,
                              background: "rgba(255,255,255,0.02)",
                              border: "1px solid #0f0f1e",
                              borderRadius: 6,
                              display: "flex",
                              flexDirection: "column",
                              justifyContent: "center",
                              gap: 6
                            }}>
                              <div className="lbl" style={{ fontSize: 10, margin: 0, textAlign: "center" }}>WEEK {weekSummaries[idx].week}</div>
                              <div style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700, fontSize: 13, textAlign: "center" }} className={weekSummaries[idx].pnl >= 0 ? "pos" : "neg"}>
                                {weekSummaries[idx].pnl >= 0 ? "+" : ""}${weekSummaries[idx].pnl.toLocaleString()}
                              </div>
                              <div style={{ color: "#d0d0d0", fontSize: 10, textAlign: "center" }}>
                                {weekSummaries[idx].daysTraded} day{weekSummaries[idx].daysTraded !== 1 ? 's' : ''}
                              </div>
                            </div>
                          </div>
                        ))}
                      </div>
                    );
                  })()}
                </div>

                {/* Legend */}
                <div style={{ display: "flex", gap: 20, marginTop: 16, fontSize: 11, color: "#666", justifyContent: "center" }}>
                  <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
                    <div style={{ width: 12, height: 12, background: "rgba(127,255,178,0.08)", border: "1px solid rgba(127,255,178,0.3)", borderRadius: 2 }} />
                    <span>Profitable Day</span>
                  </div>
                  <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
                    <div style={{ width: 12, height: 12, background: "rgba(255,68,102,0.08)", border: "1px solid rgba(255,68,102,0.3)", borderRadius: 2 }} />
                    <span>Loss Day</span>
                  </div>
                  <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
                    <div style={{ width: 12, height: 12, border: "2px solid #7fffb2", borderRadius: 2 }} />
                    <span>Today</span>
                  </div>
                </div>
              </div>
            </div>
          )}

          {/* TRADES */}
          {view === "trades" && (
            <div>
              {/* Session filter buttons */}
              <div style={{ display: "flex", gap: 5, marginBottom: 10, flexWrap: "wrap" }}>
                {["All", ...SESSIONS].map(s => (
                  <button key={s} className={`nb ${filterSession === s ? "on" : ""}`} style={{ border: "1px solid #181828" }} onClick={() => setFilterSession(s)}>{s}</button>
                ))}
              </div>

              {/* Advanced filter bar */}
              <div style={{ display: "flex", gap: 8, marginBottom: 10, flexWrap: "wrap", alignItems: "center" }}>
                <select value={filterStrategy} onChange={e => setFilterStrategy(e.target.value)} style={{ fontSize: 12, padding: "5px 8px", background: "#0d0d1a", border: "1px solid #1e1e30", borderRadius: 6, color: "#ccc", cursor: "pointer" }}>
                  <option value="All">All Strategies</option>
                  {allStrategies.map(s => <option key={s} value={s}>{s}</option>)}
                </select>
                <select value={filterDirection} onChange={e => setFilterDirection(e.target.value)} style={{ fontSize: 12, padding: "5px 8px", background: "#0d0d1a", border: "1px solid #1e1e30", borderRadius: 6, color: "#ccc", cursor: "pointer" }}>
                  <option value="All">Both Directions</option>
                  <option value="Long">Long</option>
                  <option value="Short">Short</option>
                </select>
                <select value={filterOutcome} onChange={e => setFilterOutcome(e.target.value)} style={{ fontSize: 12, padding: "5px 8px", background: "#0d0d1a", border: "1px solid #1e1e30", borderRadius: 6, color: "#ccc", cursor: "pointer" }}>
                  <option value="All">All Outcomes</option>
                  <option value="Winners">Winners Only</option>
                  <option value="Losers">Losers Only</option>
                </select>
                <input type="date" value={filterDateFrom} onChange={e => setFilterDateFrom(e.target.value)} placeholder="From" style={{ fontSize: 12, padding: "5px 8px", background: "#0d0d1a", border: "1px solid #1e1e30", borderRadius: 6, color: "#ccc" }} />
                <input type="date" value={filterDateTo} onChange={e => setFilterDateTo(e.target.value)} placeholder="To" style={{ fontSize: 12, padding: "5px 8px", background: "#0d0d1a", border: "1px solid #1e1e30", borderRadius: 6, color: "#ccc" }} />
                {isFiltered && (
                  <button onClick={() => { setFilterSession("All"); setFilterStrategy("All"); setFilterDirection("All"); setFilterOutcome("All"); setFilterDateFrom(""); setFilterDateTo(""); }} style={{ fontSize: 11, padding: "5px 10px", background: "rgba(255,68,102,0.1)", border: "1px solid rgba(255,68,102,0.3)", borderRadius: 6, color: "#ff4466", cursor: "pointer" }}>✕ Clear</button>
                )}
              </div>

              {/* Filtered summary bar */}
              {isFiltered && (
                <div style={{ marginBottom: 14, padding: "8px 12px", background: "rgba(127,255,178,0.05)", border: "1px solid rgba(127,255,178,0.15)", borderRadius: 6, display: "flex", gap: 20, alignItems: "center" }}>
                  <span style={{ fontSize: 12, color: "#7fffb2" }}>{filtered.length} trade{filtered.length !== 1 ? "s" : ""} matched</span>
                  <span style={{ fontSize: 12, color: filtered.reduce((s, t) => s + t.pnl, 0) >= 0 ? "#7fffb2" : "#ff4466", fontWeight: 600 }}>
                    Net P&L: {filtered.reduce((s, t) => s + t.pnl, 0) >= 0 ? "+" : ""}${filtered.reduce((s, t) => s + t.pnl, 0).toFixed(2)}
                  </span>
                  <span style={{ fontSize: 12, color: "#888" }}>
                    Win rate: {filtered.length ? Math.round(filtered.filter(t => t.pnl > 0).length / filtered.length * 100) : 0}%
                  </span>
                </div>
              )}


              {/* Week Groups */}
              {sortedWeeks.map(weekKey => {
                const weekTrades = groupedByWeek[weekKey];
                const weekPnL = weekTrades.reduce((sum, t) => sum + t.pnl, 0);
                const isExpanded = expandedWeeks[weekKey];
                const isCurrent = isCurrentWeek(weekKey);

                return (
                  <div key={weekKey} className="card" style={{ marginBottom: 16, padding: 0, overflow: "hidden" }}>
                    {/* Week Header */}
                    <div
                      onClick={() => setExpandedWeeks(prev => ({ ...prev, [weekKey]: !prev[weekKey] }))}
                      style={{
                        padding: "16px 20px",
                        background: isCurrent ? "rgba(127,255,178,0.05)" : "rgba(255,255,255,0.02)",
                        borderBottom: isExpanded ? "1px solid #0f0f1e" : "none",
                        cursor: "pointer",
                        display: "flex",
                        justifyContent: "space-between",
                        alignItems: "center",
                        transition: "all 0.2s"
                      }}
                      onMouseEnter={(e) => e.currentTarget.style.background = isCurrent ? "rgba(127,255,178,0.08)" : "rgba(255,255,255,0.04)"}
                      onMouseLeave={(e) => e.currentTarget.style.background = isCurrent ? "rgba(127,255,178,0.05)" : "rgba(255,255,255,0.02)"}
                    >
                      <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
                        <span style={{ fontSize: 18, color: "#666", transition: "transform 0.2s", transform: isExpanded ? "rotate(90deg)" : "rotate(0deg)" }}>▶</span>
                        <div>
                          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                            <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700, fontSize: 15, color: "#fff", margin: 0 }}>
                              {isCurrent ? "This Week" : getWeekRange(weekKey)}
                            </p>
                            {isCurrent && <span style={{ fontSize: 9, color: "#7fffb2", background: "rgba(127,255,178,0.1)", padding: "2px 6px", borderRadius: 4, fontWeight: 600 }}>CURRENT</span>}
                          </div>
                          <p style={{ fontSize: 11, color: "#888", margin: 0, marginTop: 2 }}>{weekTrades.length} trade{weekTrades.length !== 1 ? 's' : ''}</p>
                        </div>
                      </div>
                      <div style={{ display: "flex", alignItems: "center", gap: 16 }}>
                        <div style={{ textAlign: "right" }}>
                          <p style={{ fontSize: 10, color: "#888", margin: 0, marginBottom: 2 }}>Week P&L</p>
                          <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700, fontSize: 16, margin: 0 }} className={weekPnL >= 0 ? "pos" : "neg"}>
                            {weekPnL >= 0 ? "+" : ""}${weekPnL.toLocaleString()}
                          </p>
                        </div>
                      </div>
                    </div>

                    {/* Week Trades - Collapsible */}
                    {isExpanded && (
                      <div>
                        <div style={{ display: "grid", gridTemplateColumns: "80px 55px 60px 110px 120px 120px 55px 80px 80px 100px 30px 30px 40px", padding: "11px 20px", borderBottom: "1px solid #0f0f1e", background: "#09090f", alignItems: "center", columnGap: "12px" }}>
                          {["Ticker", "Dir", "Session", "Strategy", "Emotion", "Mistake", "Size", "Entry", "Exit", "P&L", "", "", ""].map((h, i) => <span key={h + i} className="lbl" style={{ margin: 0, display: "block", textAlign: i === 9 ? "right" : "left" }}>{h}</span>)}
                        </div>
                        {weekTrades.map(t => (
                  <div key={t.id}>
                    <div className="trow" style={{ display: "grid", gridTemplateColumns: "80px 55px 60px 110px 120px 120px 55px 80px 80px 100px 30px 30px 40px", padding: "13px 20px", alignItems: "center", columnGap: "12px" }}>
                      <div onClick={() => setExpandedTrade(expandedTrade === t.id ? null : t.id)} style={{ cursor: "pointer" }}>
                        <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700, color: "#fff", margin: 0 }}>
                          {t.ticker}
                          {t.source === "csv" && <span className="tv-badge">CSV</span>}
                        </p>
                        <p style={{ fontSize: 9, color: "#9595b0", margin: "2px 0 0 0" }}>
                          {formatDateDisplay(t.date)}
                        </p>
                      </div>
                      <div className="tag" style={{ background: t.direction === "Long" ? "rgba(127,255,178,.1)" : "rgba(255,68,102,.1)", color: t.direction === "Long" ? "#7fffb2" : "#ff4466", display: "flex", alignItems: "center", justifyContent: "center", cursor: "pointer" }} onClick={() => setExpandedTrade(expandedTrade === t.id ? null : t.id)}>{t.direction}</div>
                      <div style={{ fontSize: 10, color: "#ffffff", cursor: "pointer", display: "flex", alignItems: "center" }} onClick={() => setExpandedTrade(expandedTrade === t.id ? null : t.id)}>{t.session.replace("RTH ", "")}</div>
                      <div style={{ fontSize: 11, color: "#ffffff", cursor: "pointer", display: "flex", alignItems: "center" }} onClick={(e) => { e.stopPropagation(); openEditStrategy(t); }} title="Click to edit strategy">
                        {t.strategy}
                        <span style={{ fontSize: 8, marginLeft: 4, opacity: 0.5 }}>✎</span>
                      </div>
                      <div className="tag" style={{ color: emotionColors[t.emotion] || "#888", background: `${emotionColors[t.emotion] || "#888"}12`, display: "flex", alignItems: "center", justifyContent: "center", cursor: "pointer" }} onClick={(e) => { e.stopPropagation(); openEditEmotion(t); }} title="Click to edit emotion">
                        {t.emotion}
                        <span style={{ fontSize: 8, marginLeft: 4, opacity: 0.5 }}>✎</span>
                      </div>
                      <div style={{ display: "flex", flexWrap: "wrap", gap: 3, cursor: "pointer", alignItems: "center" }} onClick={(e) => { e.stopPropagation(); openEditMistake(t); }} title="Click to edit mistakes">
                        {getMistakes(t).map((mk, i) => (
                          <span key={i} className="tag" style={{ color: mistakeColors[mk] || "#888", background: `${mistakeColors[mk] || "#888"}12`, fontSize: 9 }}>
                            {mk.length > 10 ? mk.substring(0, 10) + "…" : mk}
                          </span>
                        ))}
                        <span style={{ fontSize: 8, opacity: 0.5 }}>✎</span>
                      </div>
                      <div style={{ fontSize: 12, color: "#ffffff", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center" }} onClick={() => setExpandedTrade(expandedTrade === t.id ? null : t.id)}>{t.size}</div>
                      <div style={{ fontSize: 12, color: "#eee", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center" }} onClick={() => setExpandedTrade(expandedTrade === t.id ? null : t.id)}>{t.entry}</div>
                      <div style={{ fontSize: 12, color: "#eee", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center" }} onClick={() => setExpandedTrade(expandedTrade === t.id ? null : t.id)}>{t.exit}</div>
                      <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700, textAlign: "right", cursor: "pointer", margin: 0 }} className={t.pnl >= 0 ? "pos" : "neg"} onClick={() => setExpandedTrade(expandedTrade === t.id ? null : t.id)}>{t.pnl >= 0 ? "+" : ""}${t.pnl.toLocaleString()}</p>
                      <button onClick={(e) => { e.stopPropagation(); openEditNotes(t); }} style={{ background: "none", border: "none", cursor: "pointer", fontSize: 14, padding: 0, color: (t.notesData?.text || t.notesData?.images?.length) ? "#7fffb2" : "#666", opacity: 0.7, transition: "all 0.2s", display: "flex", alignItems: "center", justifyContent: "center" }} onMouseEnter={(e) => { e.target.style.opacity = 1; e.target.style.transform = "scale(1.1)"; }} onMouseLeave={(e) => { e.target.style.opacity = 0.7; e.target.style.transform = "scale(1)"; }} title="Edit notes">📝</button>
                      <button onClick={(e) => { e.stopPropagation(); setShareCardTrade(t); }} style={{ background: "none", border: "none", cursor: "pointer", fontSize: 14, padding: 0, color: "#7ca5d4", opacity: 0.7, transition: "all 0.2s", display: "flex", alignItems: "center", justifyContent: "center" }} onMouseEnter={(e) => { e.target.style.opacity = 1; e.target.style.transform = "scale(1.1)"; }} onMouseLeave={(e) => { e.target.style.opacity = 0.7; e.target.style.transform = "scale(1)"; }} title="Share trade card">📤</button>
                      <button onClick={(e) => { e.stopPropagation(); setDeleteConfirm(t.id); }} style={{ background: "none", border: "none", cursor: "pointer", fontSize: 16, padding: 0, color: "#ff4466", opacity: 0.6, transition: "opacity 0.2s", display: "flex", alignItems: "center", justifyContent: "center" }} onMouseEnter={(e) => e.target.style.opacity = 1} onMouseLeave={(e) => e.target.style.opacity = 0.6}>×</button>
                    </div>
                    {expandedTrade === t.id && (
                      <div style={{ background: "#09090f", borderBottom: "1px solid #0f0f1e" }}>
                        {/* Grid-aligned metrics matching table columns */}
                        <div style={{ display: "grid", gridTemplateColumns: "80px 55px 60px 110px 120px 120px 55px 80px 80px 100px 30px 30px 40px", padding: "14px 20px", gap: "8px 0", fontSize: 11 }}>
                          {/* Ticker column */}
                          <div style={{ gridColumn: "1" }}>
                            <p className="lbl" style={{ marginBottom: 4 }}>Date</p>
                            <p style={{ color: "#ddd", fontSize: 11 }}>{formatDateDisplay(t.date)}</p>
                          </div>

                          {/* Dir column */}
                          <div style={{ gridColumn: "2" }}>
                            <p className="lbl" style={{ marginBottom: 4 }}>Side</p>
                            <p style={{ color: t.direction === "Long" ? "#7fffb2" : "#ff4466", fontSize: 11 }}>{t.direction}</p>
                          </div>

                          {/* Session column */}
                          <div style={{ gridColumn: "3" }}>
                            <p className="lbl" style={{ marginBottom: 4 }}>Market</p>
                            <p style={{ color: "#ddd", fontSize: 11 }}>{t.market}</p>
                          </div>

                          {/* Strategy column */}
                          <div style={{ gridColumn: "4" }}>
                            <p className="lbl" style={{ marginBottom: 4 }}>Point Val</p>
                            <p style={{ color: "#ddd", fontSize: 11 }}>${POINT_VALUES[t.market]?.toLocaleString()}</p>
                          </div>

                          {/* Emotion column */}
                          <div style={{ gridColumn: "5" }}>
                            <p className="lbl" style={{ marginBottom: 4 }}>Entry Time</p>
                            <p style={{ color: "#ddd", fontSize: 11 }}>{t.entryTime || "—"}</p>
                          </div>

                          {/* Mistake column */}
                          <div style={{ gridColumn: "6" }}>
                            <p className="lbl" style={{ marginBottom: 4 }}>Exit Time</p>
                            <p style={{ color: "#ddd", fontSize: 11 }}>{t.exitTime || "—"}</p>
                          </div>

                          {/* Size column */}
                          <div style={{ gridColumn: "7" }}>
                            <p className="lbl" style={{ marginBottom: 4 }}>Qty</p>
                            <p style={{ color: "#ddd", fontSize: 11 }}>{t.size}</p>
                          </div>

                          {/* Entry column */}
                          <div style={{ gridColumn: "8" }}>
                            <p className="lbl" style={{ marginBottom: 4 }}>Entry</p>
                            <p style={{ color: "#ddd", fontSize: 11 }}>{t.entry}</p>
                          </div>

                          {/* Exit column */}
                          <div style={{ gridColumn: "9" }}>
                            <p className="lbl" style={{ marginBottom: 4 }}>Exit</p>
                            <p style={{ color: "#ddd", fontSize: 11 }}>{t.exit}</p>
                          </div>

                          {/* P&L column */}
                          <div style={{ gridColumn: "10" }}>
                            <p className="lbl" style={{ marginBottom: 4, textAlign: "right" }}>Move</p>
                            <p style={{ color: "#ddd", fontSize: 11, textAlign: "right" }}>{Math.abs(t.exit - t.entry).toFixed(2)} pts</p>
                          </div>
                        </div>

                        <div style={{ padding: "0 20px 14px 20px" }}>
                          <div style={{ marginBottom: 12 }}>
                            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 8 }}>
                              <p style={{ fontSize: 10, color: "#7fffb2", letterSpacing: ".1em" }}>NOTES</p>
                              <div style={{ display: "flex", gap: 8 }}>
                                <button className="ghost" onClick={(e) => { e.stopPropagation(); openEditNotes(t); }} style={{ padding: "4px 10px", fontSize: 9 }}>✎ Edit Notes</button>
                                <button className="ghost" onClick={(e) => { e.stopPropagation(); openEditTime(t); }} style={{ padding: "4px 10px", fontSize: 9 }}>🕐 Edit Time</button>
                                <button className="ghost" onClick={(e) => { e.stopPropagation(); setAttachVideoTrade(t); }} style={{ padding: "4px 10px", fontSize: 9 }}>🎥 {recordings.find(r => r.tradeId === t.id) ? "Change" : "Attach"} Video</button>
                              </div>
                            </div>
                            {t.notesData?.text && (
                              <p style={{ fontSize: 12, color: "#ffffff", marginBottom: 10, whiteSpace: "pre-wrap", lineHeight: 1.6 }}>{t.notesData.text}</p>
                            )}
                            {t.notesData?.images?.length > 0 && (
                              <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(120px, 1fr))", gap: 8, marginTop: 10 }}>
                                {t.notesData.images.map(img => (
                                  <img key={img.id} src={img.dataUrl} alt={img.name} style={{ width: "100%", height: 80, objectFit: "cover", borderRadius: 4, border: "1px solid #181828", cursor: "pointer" }} onClick={() => setPreviewImage(img)} />
                                ))}
                              </div>
                            )}
                            {!t.notesData?.text && !t.notesData?.images?.length && (
                              <p style={{ fontSize: 11, color: "#666", fontStyle: "italic" }}>No notes recorded. Click "Edit Notes" to add.</p>
                            )}
                          </div>

                          {/* Attached Video */}
                          {(() => {
                            const attachedVideo = recordings.find(r => r.tradeId === t.id);
                            if (attachedVideo) {
                              const createdDate = new Date(attachedVideo.createdAt);
                              const dateStr = createdDate.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
                              const timeStr = createdDate.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" });
                              const durationStr = formatTime(attachedVideo.duration || 0);
                              return (
                                <div style={{ marginBottom: 12, padding: "12px", background: "rgba(127,255,178,0.03)", borderRadius: 6, border: "1px solid rgba(127,255,178,0.1)" }}>
                                  <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 6 }}>
                                    <span style={{ fontSize: 14 }}>🎥</span>
                                    <p style={{ fontSize: 10, color: "#7fffb2", letterSpacing: ".1em" }}>ATTACHED VIDEO</p>
                                  </div>
                                  <p style={{ fontSize: 11, color: "#ffffff", fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", marginBottom: 6 }}>
                                    {attachedVideo.fileName}
                                  </p>
                                  <div style={{ display: "flex", gap: 12, fontSize: 10, color: "#888" }}>
                                    <span>📅 {dateStr} at {timeStr}</span>
                                    <span>⏱ {durationStr}</span>
                                  </div>
                                  <p style={{ fontSize: 9, color: "#666", fontStyle: "italic", marginTop: 6 }}>
                                    Video saved in Downloads folder
                                  </p>
                                </div>
                              );
                            }
                            return null;
                          })()}

                          {!tradeAi[t.id] && <button className="ghost" onClick={(e) => { e.stopPropagation(); analyzeOne(t); }}>AI Analysis</button>}
                          {tradeAi[t.id]?.loading && <p style={{ fontSize: 11, color: "#7fffb2" }} className="pulse">Analyzing trade...</p>}
                          {tradeAi[t.id]?.text && (
                            <div style={{ marginTop: 12, padding: 16, background: "#0c0c18", borderRadius: 6, border: "1px solid #1e1e30" }}>
                              <p style={{ fontSize: 9, color: "#7fffb2", letterSpacing: ".12em", marginBottom: 10 }}>LYRA COACHING</p>
                              <p className="ai-text">{tradeAi[t.id].text}</p>
                            </div>
                          )}
                        </div>
                      </div>
                    )}
                  </div>
                        ))}
                      </div>
                    )}
                  </div>
                );
              })}
            </div>
          )}

          {/* JOURNAL */}
          {view === "journal" && (
            <div>
              <div style={{ marginBottom: 20 }}>
                <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 20, fontWeight: 700, color: "#fff", marginBottom: 6 }}>Daily Trading Journal</p>
                <p style={{ color: "#aaa", fontSize: 12 }}>Document your pre-market plans, trade ideas, and daily reflections</p>
              </div>

              {/* Date Selector */}
              <div style={{ marginBottom: 20 }}>
                <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
                  <span className="lbl" style={{ marginBottom: 0 }}>Journal Date</span>
                  <input
                    type="date"
                    value={selectedJournalDate}
                    onChange={(e) => setSelectedJournalDate(e.target.value)}
                    style={{ width: 200 }}
                  />
                  <button className="gbtn" onClick={saveJournalEntries}>
                    Save Journal
                  </button>
                  {journalEntries[selectedJournalDate] && (
                    <button
                      className="ghost"
                      onClick={() => {
                        if (confirm(`Delete journal entry for ${formatDateDisplay(selectedJournalDate)}? This cannot be undone.`)) {
                          setJournalEntries(prev => {
                            const updated = { ...prev };
                            delete updated[selectedJournalDate];
                            return updated;
                          });
                        }
                      }}
                      style={{ color: "#ff4466", padding: "8px 16px", fontSize: 11 }}
                    >
                      🗑 Delete Entry
                    </button>
                  )}
                </div>
              </div>

              {/* Journal Entry */}
              <div className="card">
                <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 16, fontWeight: 700, color: "#fff", marginBottom: 16 }}>
                  {formatDateDisplay(selectedJournalDate)}
                </p>

                {/* Mindset Check-In — Morning */}
                <div style={{ marginBottom: 20, padding: "12px 14px", background: "rgba(127,255,178,0.03)", border: "1px solid rgba(127,255,178,0.15)", borderRadius: 8 }}>
                  <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 10 }}>
                    <p className="lbl" style={{ margin: 0 }}>Morning Check-In</p>
                    <span style={{ fontSize: 9, color: "#7fffb2", fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", letterSpacing: ".1em" }}>PRE-MARKET</span>
                  </div>
                  <div style={{ display: "flex", flexWrap: "wrap", gap: 14, alignItems: "flex-end", marginBottom: 10 }}>
                    <div style={{ display: "flex", flexDirection: "column" }}>
                      <span className="lbl" style={{ marginBottom: 4 }}>Sleep (h)</span>
                      <input
                        type="number"
                        step="0.5"
                        min="0"
                        max="24"
                        value={journalEntries[selectedJournalDate]?.mindset?.sleepHours ?? ""}
                        onChange={(e) => updateMindsetField(selectedJournalDate, "sleepHours", e.target.value === "" ? null : Number(e.target.value))}
                        style={{ width: 70 }}
                      />
                    </div>
                    <div style={{ display: "flex", flexDirection: "column" }}>
                      <span className="lbl" style={{ marginBottom: 4 }}>Stress 1-10</span>
                      <input
                        type="number"
                        min="1"
                        max="10"
                        value={journalEntries[selectedJournalDate]?.mindset?.stress ?? ""}
                        onChange={(e) => updateMindsetField(selectedJournalDate, "stress", e.target.value === "" ? null : Number(e.target.value))}
                        style={{ width: 60 }}
                      />
                    </div>
                    <div style={{ display: "flex", flexDirection: "column" }}>
                      <span className="lbl" style={{ marginBottom: 4 }}>Prep 1-10</span>
                      <input
                        type="number"
                        min="1"
                        max="10"
                        value={journalEntries[selectedJournalDate]?.mindset?.prepQuality ?? ""}
                        onChange={(e) => updateMindsetField(selectedJournalDate, "prepQuality", e.target.value === "" ? null : Number(e.target.value))}
                        style={{ width: 60 }}
                      />
                    </div>
                    <div style={{ display: "flex", flexDirection: "column" }}>
                      <span className="lbl" style={{ marginBottom: 4 }}>Energy 1-10</span>
                      <input
                        type="number"
                        min="1"
                        max="10"
                        value={journalEntries[selectedJournalDate]?.mindset?.energy ?? ""}
                        onChange={(e) => updateMindsetField(selectedJournalDate, "energy", e.target.value === "" ? null : Number(e.target.value))}
                        style={{ width: 60 }}
                      />
                    </div>
                  </div>
                  <div>
                    <span className="lbl" style={{ display: "block", marginBottom: 6 }}>Mood</span>
                    <div style={{ display: "flex", flexWrap: "wrap", gap: 6 }}>
                      {MOOD_OPTIONS.map(mood => {
                        const active = (journalEntries[selectedJournalDate]?.mindset?.mood || []).includes(mood);
                        return (
                          <button
                            key={mood}
                            type="button"
                            onClick={() => toggleMindsetChip(selectedJournalDate, "mood", mood)}
                            style={{
                              padding: "5px 12px",
                              fontSize: 10,
                              borderRadius: 999,
                              border: active ? "1px solid #7fffb2" : "1px solid rgba(255,255,255,0.15)",
                              background: active ? "rgba(127,255,178,0.15)" : "transparent",
                              color: active ? "#7fffb2" : "#aaa",
                              cursor: "pointer",
                              fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace"
                            }}
                          >
                            {mood}
                          </button>
                        );
                      })}
                    </div>
                  </div>
                </div>

                {/* Notes Section */}
                <div style={{ marginBottom: 20 }}>
                  <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 12 }}>
                    <p className="lbl" style={{ margin: 0 }}>Pre-Market Plan & Notes</p>
                    <button
                      className="ghost"
                      onClick={() => {
                        const currentText = journalEntries[selectedJournalDate]?.text || '';
                        const defaultPrompts = `📍 What are my key levels to watch today?

🎯 What's my primary setup I'm hunting for today?

⚠️ What must I avoid today based on yesterday's mistakes?

🧠 How am I feeling physically and mentally right now?

🎯 Today's main goal (beyond P&L):

✅ What 3 conditions confirm my A+ setup?
`;
                        setJournalEntries(prev => ({
                          ...prev,
                          [selectedJournalDate]: {
                            ...prev[selectedJournalDate],
                            text: currentText ? `${currentText}\n\n${defaultPrompts}` : defaultPrompts,
                            images: prev[selectedJournalDate]?.images || [],
                            postSession: prev[selectedJournalDate]?.postSession || ''
                          }
                        }));
                      }}
                      style={{ padding: "4px 10px", fontSize: 9 }}
                    >
                      📋 Insert Prompts
                    </button>
                  </div>
                  <textarea
                    value={(() => {
                      const currentText = journalEntries[selectedJournalDate]?.text;
                      if (!currentText) {
                        return `📍 What are my key levels to watch today?

🎯 What's my primary setup I'm hunting for today?

⚠️ What must I avoid today based on yesterday's mistakes?

🧠 How am I feeling physically and mentally right now?

🎯 Today's main goal (beyond P&L):

✅ What 3 conditions confirm my A+ setup?
`;
                      }
                      return currentText;
                    })()}
                    onChange={(e) => {
                      setJournalEntries(prev => ({
                        ...prev,
                        [selectedJournalDate]: {
                          ...prev[selectedJournalDate],
                          text: e.target.value
                        }
                      }));
                    }}
                    style={{
                      width: "100%",
                      minHeight: 200,
                      resize: "vertical",
                      fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace",
                      fontSize: 12,
                      lineHeight: 1.6,
                      background: "#09090f",
                      border: "1px solid rgba(255,255,255,0.1)"
                    }}
                  />
                </div>

                {/* Mindset Check-In — Evening */}
                <div style={{ marginBottom: 20, padding: "12px 14px", background: "rgba(127,255,178,0.03)", border: "1px solid rgba(127,255,178,0.15)", borderRadius: 8 }}>
                  <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 10 }}>
                    <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                      <p className="lbl" style={{ margin: 0 }}>Evening Check-In</p>
                      <button
                        onClick={() => setShowRulesManager(true)}
                        title="Manage Trading Rules"
                        style={{ background: "none", border: "none", cursor: "pointer", fontSize: 14, color: "#555", padding: "2px 4px" }}
                      >
                        ⚙
                      </button>
                    </div>
                    <span style={{ fontSize: 9, color: "#7fffb2", fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", letterSpacing: ".1em" }}>END OF DAY</span>
                  </div>

                  {/* Rules Checklist */}
                  {activeRules.length > 0 ? (
                    <div style={{ marginBottom: 14 }}>
                      <span className="lbl" style={{ display: "block", marginBottom: 8 }}>Trading Rules</span>
                      {["risk", "process", "mindset"].map(cat => {
                        const catRules = activeRules.filter(r => r.category === cat);
                        if (catRules.length === 0) return null;
                        return (
                          <div key={cat} style={{ marginBottom: 8 }}>
                            <span style={{ fontSize: 9, color: RULE_CATEGORY_COLORS[cat], fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", letterSpacing: ".08em", display: "block", marginBottom: 4 }}>
                              {RULE_CATEGORY_LABELS[cat].toUpperCase()}
                            </span>
                            {catRules.map(rule => {
                              const checked = journalEntries[selectedJournalDate]?.mindset?.ruleCheckoffs?.[rule.id] === true;
                              return (
                                <label
                                  key={rule.id}
                                  style={{
                                    display: "flex", alignItems: "center", gap: 8,
                                    padding: "5px 8px", cursor: "pointer",
                                    borderRadius: 4,
                                    background: checked ? `${RULE_CATEGORY_COLORS[cat]}08` : "transparent",
                                    transition: "background .15s"
                                  }}
                                >
                                  <input
                                    type="checkbox"
                                    checked={checked}
                                    onChange={(e) => updateRuleCheckoff(selectedJournalDate, rule.id, e.target.checked)}
                                    style={{ accentColor: RULE_CATEGORY_COLORS[cat], width: 14, height: 14 }}
                                  />
                                  <span style={{
                                    fontSize: 11, color: checked ? "#ccc" : "#888",
                                    textDecoration: checked ? "line-through" : "none",
                                    fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace"
                                  }}>
                                    {rule.text}
                                  </span>
                                </label>
                              );
                            })}
                          </div>
                        );
                      })}

                      {/* Score bar */}
                      {(() => {
                        const score = computeRuleScore(journalEntries[selectedJournalDate]?.mindset?.ruleCheckoffs);
                        if (!score) return null;
                        const barColor = score.percent >= 80 ? "#7fffb2" : score.percent >= 50 ? "#ffdd00" : "#ff5566";
                        return (
                          <div style={{ marginTop: 10, padding: "8px 10px", background: "#0a0a14", borderRadius: 6, border: "1px solid #1a1a2a" }}>
                            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 4 }}>
                              <span style={{ fontSize: 10, color: "#888", fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace" }}>
                                {score.followed}/{score.total} rules followed
                              </span>
                              <span style={{ fontSize: 12, fontWeight: 700, color: barColor, fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace" }}>
                                {score.percent}%
                              </span>
                            </div>
                            <div style={{ height: 4, background: "#1a1a2a", borderRadius: 2, overflow: "hidden" }}>
                              <div style={{ height: "100%", width: `${score.percent}%`, background: barColor, borderRadius: 2, transition: "width .3s" }} />
                            </div>
                          </div>
                        );
                      })()}

                      {/* Streak display */}
                      {(() => {
                        const streak = calculateRuleAdherenceStreak();
                        if (streak.current === 0 && streak.best === 0) return null;
                        return (
                          <div style={{ marginTop: 8, display: "flex", gap: 16, fontSize: 10, color: "#666", fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace" }}>
                            <span>Current streak: <span style={{ color: streak.current > 0 ? "#7fffb2" : "#ff5566", fontWeight: 600 }}>{streak.current} day{streak.current !== 1 ? "s" : ""}</span></span>
                            <span>Best: <span style={{ color: "#ffdd00", fontWeight: 600 }}>{streak.best} day{streak.best !== 1 ? "s" : ""}</span></span>
                          </div>
                        );
                      })()}
                    </div>
                  ) : (
                    <div style={{ marginBottom: 14, textAlign: "center", padding: "16px 0" }}>
                      <p style={{ fontSize: 11, color: "#666", marginBottom: 10 }}>Set up your trading rules to track daily adherence</p>
                      <button className="gbtn" onClick={() => setShowRulesManager(true)} style={{ fontSize: 11, padding: "6px 16px" }}>
                        Set Up Rules
                      </button>
                    </div>
                  )}

                  {/* Day Rating */}
                  <div style={{ display: "flex", flexWrap: "wrap", gap: 14, alignItems: "flex-end", marginBottom: 10 }}>
                    <div style={{ display: "flex", flexDirection: "column" }}>
                      <span className="lbl" style={{ marginBottom: 4 }}>Day Rating 1-10</span>
                      <input
                        type="number"
                        min="1"
                        max="10"
                        value={journalEntries[selectedJournalDate]?.mindset?.dayRating ?? ""}
                        onChange={(e) => updateMindsetField(selectedJournalDate, "dayRating", e.target.value === "" ? null : Number(e.target.value))}
                        style={{ width: 70 }}
                      />
                    </div>
                  </div>

                  {/* Discipline Tags */}
                  <div>
                    <span className="lbl" style={{ display: "block", marginBottom: 6 }}>Discipline Tags</span>
                    <div style={{ display: "flex", flexWrap: "wrap", gap: 6 }}>
                      {DISCIPLINE_TAG_OPTIONS.map(tag => {
                        const active = (journalEntries[selectedJournalDate]?.mindset?.disciplineTags || []).includes(tag);
                        const isPositive = tag === "Followed plan";
                        const accent = isPositive ? "#7fffb2" : "#ff7744";
                        return (
                          <button
                            key={tag}
                            type="button"
                            onClick={() => toggleMindsetChip(selectedJournalDate, "disciplineTags", tag)}
                            style={{
                              padding: "5px 12px",
                              fontSize: 10,
                              borderRadius: 999,
                              border: active ? `1px solid ${accent}` : "1px solid rgba(255,255,255,0.15)",
                              background: active ? `${accent}22` : "transparent",
                              color: active ? accent : "#aaa",
                              cursor: "pointer",
                              fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace"
                            }}
                          >
                            {tag}
                          </button>
                        );
                      })}
                    </div>
                  </div>
                </div>

                {/* Post-Session Review */}
                <div style={{ marginBottom: 20 }}>
                  <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 12 }}>
                    <p className="lbl" style={{ margin: 0 }}>Post-Session Review</p>
                    <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
                      <button
                        className="ghost"
                        onClick={() => {
                          const currentText = journalEntries[selectedJournalDate]?.postSession || '';
                          const defaultPrompts = `📊 Did I follow my pre-market plan today?

🏆 What was my best trade today and why?

📉 What was my worst trade today and why?

😤 What emotions impacted my decisions?

💡 What's ONE lesson I'm taking into tomorrow?

🔄 What would I do differently if I could replay today?
`;
                          setJournalEntries(prev => ({
                            ...prev,
                            [selectedJournalDate]: {
                              ...prev[selectedJournalDate],
                              text: prev[selectedJournalDate]?.text || '',
                              images: prev[selectedJournalDate]?.images || [],
                              postSession: currentText ? `${currentText}\n\n${defaultPrompts}` : defaultPrompts
                            }
                          }));
                        }}
                        style={{ padding: "4px 10px", fontSize: 9 }}
                      >
                        📋 Insert Prompts
                      </button>
                      <span style={{ fontSize: 9, color: "#7fffb2", fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", letterSpacing: ".1em" }}>END OF DAY</span>
                    </div>
                  </div>
                  <textarea
                    value={(() => {
                      const currentText = journalEntries[selectedJournalDate]?.postSession;
                      if (!currentText) {
                        return `📊 Did I follow my pre-market plan today?

🏆 What was my best trade today and why?

📉 What was my worst trade today and why?

😤 What emotions impacted my decisions?

💡 What's ONE lesson I'm taking into tomorrow?

🔄 What would I do differently if I could replay today?
`;
                      }
                      return currentText;
                    })()}
                    onChange={(e) => {
                      setJournalEntries(prev => {
                        const updated = {
                          ...prev,
                          [selectedJournalDate]: {
                            ...prev[selectedJournalDate],
                            postSession: e.target.value
                          }
                        };
                        return updated;
                      });
                    }}
                    style={{
                      width: "100%",
                      minHeight: 250,
                      resize: "vertical",
                      fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace",
                      fontSize: 12,
                      lineHeight: 1.6,
                      background: "#09090f",
                      border: "1px solid #7fffb222"
                    }}
                  />
                </div>

                {/* Screenshots Section */}
                <div
                  onDragOver={(e) => {
                    e.preventDefault();
                    setJournalDragOver(true);
                  }}
                  onDragLeave={(e) => {
                    e.preventDefault();
                    setJournalDragOver(false);
                  }}
                  onDrop={(e) => {
                    e.preventDefault();
                    setJournalDragOver(false);
                    const files = Array.from(e.dataTransfer.files).filter(file => file.type.startsWith('image/'));
                    files.forEach(file => {
                      const reader = new FileReader();
                      reader.onload = (event) => {
                        const newImage = {
                          id: Date.now() + Math.random(),
                          dataUrl: event.target.result,
                          name: file.name
                        };
                        console.log('Image uploaded via drag/drop for date:', selectedJournalDate);
                        setJournalEntries(prev => {
                          const updated = {
                            ...prev,
                            [selectedJournalDate]: {
                              ...prev[selectedJournalDate],
                              text: prev[selectedJournalDate]?.text || '',
                              images: [...(prev[selectedJournalDate]?.images || []), newImage]
                            }
                          };
                          console.log('Updated journal entries with image:', updated);
                          return updated;
                        });
                      };
                      reader.readAsDataURL(file);
                    });
                  }}
                  style={{
                    position: "relative",
                    border: journalDragOver ? "2px dashed #7fffb2" : "2px dashed transparent",
                    borderRadius: 8,
                    padding: 16,
                    transition: "all 0.2s",
                    background: journalDragOver ? "rgba(127, 255, 178, 0.05)" : "transparent"
                  }}
                >
                  <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 12 }}>
                    <p className="lbl" style={{ margin: 0 }}>Screenshots & Charts</p>
                    <input
                      type="file"
                      accept="image/*"
                      multiple
                      style={{ display: "none" }}
                      id="journal-image-upload"
                      onChange={(e) => {
                        const files = Array.from(e.target.files);
                        files.forEach(file => {
                          const reader = new FileReader();
                          reader.onload = (event) => {
                            const newImage = {
                              id: Date.now() + Math.random(),
                              dataUrl: event.target.result,
                              name: file.name
                            };
                            console.log('Image uploaded via button for date:', selectedJournalDate);
                            setJournalEntries(prev => {
                              const updated = {
                                ...prev,
                                [selectedJournalDate]: {
                                  ...prev[selectedJournalDate],
                                  text: prev[selectedJournalDate]?.text || '',
                                  images: [...(prev[selectedJournalDate]?.images || []), newImage]
                                }
                              };
                              console.log('Updated journal entries with image:', updated);
                              return updated;
                            });
                          };
                          reader.readAsDataURL(file);
                        });
                        e.target.value = '';
                      }}
                    />
                    <button
                      className="ghost"
                      onClick={() => document.getElementById('journal-image-upload').click()}
                      style={{ padding: "4px 10px", fontSize: 9 }}
                    >
                      📷 Upload Images
                    </button>
                  </div>

                  {/* Drag and Drop Indicator */}
                  {journalDragOver && (
                    <div style={{
                      position: "absolute",
                      top: "50%",
                      left: "50%",
                      transform: "translate(-50%, -50%)",
                      pointerEvents: "none",
                      textAlign: "center",
                      zIndex: 10
                    }}>
                      <p style={{ fontSize: 24, marginBottom: 8 }}>📷</p>
                      <p style={{ fontSize: 14, color: "#7fffb2", fontWeight: 600 }}>Drop screenshots here</p>
                    </div>
                  )}

                  {/* Display uploaded images */}
                  {journalEntries[selectedJournalDate]?.images?.length > 0 && (
                    <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(200px, 1fr))", gap: 12 }}>
                      {journalEntries[selectedJournalDate].images.map(img => (
                        <div key={img.id} style={{ position: "relative", borderRadius: 6, overflow: "hidden", border: "1px solid #181828" }}>
                          <img
                            src={img.dataUrl}
                            alt={img.name}
                            style={{ width: "100%", height: 150, objectFit: "cover", cursor: "pointer" }}
                            onClick={() => setPreviewImage(img)}
                          />
                          <button
                            onClick={() => {
                              setJournalEntries(prev => ({
                                ...prev,
                                [selectedJournalDate]: {
                                  ...prev[selectedJournalDate],
                                  images: prev[selectedJournalDate].images.filter(i => i.id !== img.id)
                                }
                              }));
                            }}
                            style={{
                              position: "absolute",
                              top: 8,
                              right: 8,
                              background: "rgba(255, 68, 102, 0.9)",
                              border: "none",
                              color: "#fff",
                              width: 28,
                              height: 28,
                              borderRadius: "50%",
                              cursor: "pointer",
                              fontSize: 16,
                              display: "flex",
                              alignItems: "center",
                              justifyContent: "center",
                              padding: 0,
                              boxShadow: "0 2px 8px rgba(0,0,0,0.3)"
                            }}
                            title="Remove image"
                          >
                            ×
                          </button>
                        </div>
                      ))}
                    </div>
                  )}
                </div>
              </div>

              {/* Historical Entries - Collapsible Accordion */}
              {Object.keys(journalEntries).length > 1 && (
                <div className="card" style={{ marginTop: 20 }}>
                  <div
                    style={{
                      display: "flex",
                      justifyContent: "space-between",
                      alignItems: "center",
                      cursor: "pointer",
                      padding: 16,
                      background: "rgba(255,255,255,0.02)",
                      borderRadius: 8,
                      border: "1px solid rgba(255,255,255,0.05)"
                    }}
                    onClick={() => setJournalHistoryExpanded(!journalHistoryExpanded)}
                  >
                    <div>
                      <span style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 14, fontWeight: 700, color: "#7fffb2" }}>
                        Previous Journal Entries
                      </span>
                      <span style={{ fontSize: 11, color: "#666", marginLeft: 12 }}>
                        {Object.keys(journalEntries).filter(date => date !== selectedJournalDate).length} entries
                      </span>
                    </div>
                    <span style={{ fontSize: 20, color: "#7fffb2" }}>
                      {journalHistoryExpanded ? "▲" : "▼"}
                    </span>
                  </div>

                  {journalHistoryExpanded && (
                    <div style={{ display: "flex", flexDirection: "column", gap: 8, marginTop: 12 }}>
                      {Object.keys(journalEntries)
                        .filter(date => date !== selectedJournalDate)
                        .sort((a, b) => new Date(b) - new Date(a))
                        .slice(0, 10)
                        .map(date => (
                          <div
                            key={date}
                            className="card"
                            style={{ padding: 12, cursor: "pointer" }}
                            onClick={() => setSelectedJournalDate(date)}
                          >
                            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
                              <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 13, fontWeight: 700, color: "#7fffb2", margin: 0 }}>
                                {formatDateDisplay(date)}
                              </p>
                              <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                                {journalEntries[date]?.images?.length > 0 && (
                                  <span style={{
                                    display: "inline-block",
                                    padding: "2px 8px",
                                    background: "rgba(127,255,178,0.1)",
                                    borderRadius: 4,
                                    fontSize: 10,
                                    color: "#7fffb2"
                                  }}>
                                    {journalEntries[date].images.length} image{journalEntries[date].images.length !== 1 ? 's' : ''}
                                  </span>
                                )}
                                <button
                                  onClick={(e) => {
                                    e.stopPropagation();
                                    if (confirm(`Delete journal entry for ${formatDateDisplay(date)}? This cannot be undone.`)) {
                                      setJournalEntries(prev => {
                                        const updated = { ...prev };
                                        delete updated[date];
                                        return updated;
                                      });
                                    }
                                  }}
                                  style={{ background: "none", border: "none", color: "#ff4466", cursor: "pointer", fontSize: 16, padding: "2px 6px", opacity: 0.5, transition: "opacity 0.2s" }}
                                  onMouseEnter={(e) => e.target.style.opacity = 1}
                                  onMouseLeave={(e) => e.target.style.opacity = 0.5}
                                  title="Delete this entry"
                                >×</button>
                              </div>
                            </div>
                            {journalEntries[date]?.text && (
                              <p style={{ fontSize: 11, color: "#ffffff", lineHeight: 1.6, margin: "8px 0 0 0" }}>
                                {journalEntries[date].text.substring(0, 100)}{journalEntries[date].text.length > 100 ? '...' : ''}
                              </p>
                            )}
                          </div>
                        ))}
                    </div>
                  )}
                </div>
              )}
            </div>
          )}

          {/* ANALYTICS */}
          {view === "analytics" && (
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
              {/* Day Streak Tracker */}
              <div className="card">
                <p className="lbl" style={{ marginBottom: 16 }}>Day Streak Tracker</p>

                {/* Current Streak */}
                <div style={{ marginBottom: 24, textAlign: "center", padding: "20px", background: "rgba(255,255,255,0.02)", borderRadius: 12, border: `2px solid ${dayStreaks.currentType === 'win' ? 'rgba(127,255,178,0.3)' : 'rgba(255,68,102,0.3)'}` }}>
                  <p style={{ fontSize: 10, color: "#888", marginBottom: 8, textTransform: "uppercase", letterSpacing: 1 }}>Current Streak</p>
                  <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 48, fontWeight: 700, color: dayStreaks.currentType === 'win' ? "#7fffb2" : "#ff4466", margin: 0, lineHeight: 1 }}>
                    {dayStreaks.current}
                  </p>
                  <p style={{ fontSize: 12, color: dayStreaks.currentType === 'win' ? "#7fffb2" : "#ff4466", marginTop: 8, textTransform: "uppercase", letterSpacing: 1 }}>
                    {dayStreaks.currentType === 'win' ? '🔥 Winning Days' : '❄️ Losing Days'}
                  </p>
                </div>

                {/* Best Streaks */}
                <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
                  <div style={{ background: "rgba(127,255,178,0.05)", padding: 16, borderRadius: 8, border: "1px solid rgba(127,255,178,0.2)" }}>
                    <p style={{ fontSize: 10, color: "#888", marginBottom: 8, textTransform: "uppercase", letterSpacing: 1 }}>Best Win Streak</p>
                    <div style={{ display: "flex", alignItems: "baseline", gap: 6 }}>
                      <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 32, fontWeight: 700, color: "#7fffb2", margin: 0 }}>{dayStreaks.bestWin}</p>
                      <p style={{ fontSize: 12, color: "#7fffb2" }}>days</p>
                    </div>
                  </div>
                  <div style={{ background: "rgba(255,68,102,0.05)", padding: 16, borderRadius: 8, border: "1px solid rgba(255,68,102,0.2)" }}>
                    <p style={{ fontSize: 10, color: "#888", marginBottom: 8, textTransform: "uppercase", letterSpacing: 1 }}>Worst Loss Streak</p>
                    <div style={{ display: "flex", alignItems: "baseline", gap: 6 }}>
                      <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 32, fontWeight: 700, color: "#ff4466", margin: 0 }}>{dayStreaks.bestLoss}</p>
                      <p style={{ fontSize: 12, color: "#ff4466" }}>days</p>
                    </div>
                  </div>
                </div>
              </div>

              {/* Trade Streak Tracker */}
              <div className="card">
                <p className="lbl" style={{ marginBottom: 16 }}>Trade Streak Tracker</p>

                {/* Current Streak */}
                <div style={{ marginBottom: 24, textAlign: "center", padding: "20px", background: "rgba(255,255,255,0.02)", borderRadius: 12, border: `2px solid ${tradeStreaks.currentType === 'win' ? 'rgba(127,255,178,0.3)' : 'rgba(255,68,102,0.3)'}` }}>
                  <p style={{ fontSize: 10, color: "#888", marginBottom: 8, textTransform: "uppercase", letterSpacing: 1 }}>Current Streak</p>
                  <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 48, fontWeight: 700, color: tradeStreaks.currentType === 'win' ? "#7fffb2" : "#ff4466", margin: 0, lineHeight: 1 }}>
                    {tradeStreaks.current}
                  </p>
                  <p style={{ fontSize: 12, color: tradeStreaks.currentType === 'win' ? "#7fffb2" : "#ff4466", marginTop: 8, textTransform: "uppercase", letterSpacing: 1 }}>
                    {tradeStreaks.currentType === 'win' ? '🔥 Winning Trades' : '❄️ Losing Trades'}
                  </p>
                </div>

                {/* Best Streaks */}
                <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
                  <div style={{ background: "rgba(127,255,178,0.05)", padding: 16, borderRadius: 8, border: "1px solid rgba(127,255,178,0.2)" }}>
                    <p style={{ fontSize: 10, color: "#888", marginBottom: 8, textTransform: "uppercase", letterSpacing: 1 }}>Best Win Streak</p>
                    <div style={{ display: "flex", alignItems: "baseline", gap: 6 }}>
                      <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 32, fontWeight: 700, color: "#7fffb2", margin: 0 }}>{tradeStreaks.bestWin}</p>
                      <p style={{ fontSize: 12, color: "#7fffb2" }}>trades</p>
                    </div>
                  </div>
                  <div style={{ background: "rgba(255,68,102,0.05)", padding: 16, borderRadius: 8, border: "1px solid rgba(255,68,102,0.2)" }}>
                    <p style={{ fontSize: 10, color: "#888", marginBottom: 8, textTransform: "uppercase", letterSpacing: 1 }}>Worst Loss Streak</p>
                    <div style={{ display: "flex", alignItems: "baseline", gap: 6 }}>
                      <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 32, fontWeight: 700, color: "#ff4466", margin: 0 }}>{tradeStreaks.bestLoss}</p>
                      <p style={{ fontSize: 12, color: "#ff4466" }}>trades</p>
                    </div>
                  </div>
                </div>
              </div>

              <div className="card">
                <p className="lbl" style={{ marginBottom: 16 }}>Strategy Performance</p>
                {stratPerf.map(s => {
                  const max = Math.max(...stratPerf.map(x => Math.abs(x.pnl)), 1);
                  return (
                    <div key={s.name} style={{ marginBottom: 14 }}>
                      <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 4 }}>
                        <span style={{ fontSize: 12 }}>{s.name}</span>
                        <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
                          <span style={{ fontSize: 10, color: "#aaa" }}>{s.wr}% WR · {s.count}t</span>
                          <span className={s.pnl >= 0 ? "pos" : "neg"} style={{ fontSize: 13, fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700 }}>{s.pnl >= 0 ? "+" : ""}${s.pnl.toLocaleString()}</span>
                        </div>
                      </div>
                      <div style={{ background: "#111120", borderRadius: 3, height: 4 }}>
                        <div style={{ width: `${(Math.abs(s.pnl) / max) * 100}%`, height: 4, borderRadius: 3, background: s.pnl >= 0 ? "linear-gradient(90deg,#7fffb2,#00cc66)" : "linear-gradient(90deg,#ff4466,#cc2244)" }} />
                      </div>
                    </div>
                  );
                })}
              </div>

              <div className="card">
                <p className="lbl" style={{ marginBottom: 16 }}>Emotion \u2192 P&L</p>
                {emotPerf.map(e => {
                  const max = Math.max(...emotPerf.map(x => Math.abs(x.pnl)), 1);
                  const col = emotionColors[e.name] || "#888";
                  return (
                    <div key={e.name} style={{ marginBottom: 14 }}>
                      <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 4 }}>
                        <span style={{ fontSize: 12, color: col }}>{e.name}</span>
                        <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
                          <span style={{ fontSize: 10, color: "#aaa" }}>{e.count}t</span>
                          <span className={e.pnl >= 0 ? "pos" : "neg"} style={{ fontSize: 13, fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700 }}>{e.pnl >= 0 ? "+" : ""}${e.pnl.toLocaleString()}</span>
                        </div>
                      </div>
                      <div style={{ background: "#111120", borderRadius: 3, height: 4 }}>
                        <div style={{ width: `${(Math.abs(e.pnl) / max) * 100}%`, height: 4, borderRadius: 3, background: e.pnl >= 0 ? col : "#ff4466" }} />
                      </div>
                    </div>
                  );
                })}
              </div>

              <div className="card">
                <p className="lbl" style={{ marginBottom: 16 }}>Mistakes \u2192 P&L</p>
                {mistakePerf.map(m => {
                  const max = Math.max(...mistakePerf.map(x => Math.abs(x.pnl)), 1);
                  const col = mistakeColors[m.name] || "#888";
                  return (
                    <div key={m.name} style={{ marginBottom: 14 }}>
                      <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 4 }}>
                        <span style={{ fontSize: 12, color: col }}>{m.name}</span>
                        <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
                          <span style={{ fontSize: 10, color: "#aaa" }}>{m.count}t</span>
                          <span className={m.pnl >= 0 ? "pos" : "neg"} style={{ fontSize: 13, fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700 }}>{m.pnl >= 0 ? "+" : ""}${m.pnl.toLocaleString()}</span>
                        </div>
                      </div>
                      <div style={{ background: "#111120", borderRadius: 3, height: 4 }}>
                        <div style={{ width: `${(Math.abs(m.pnl) / max) * 100}%`, height: 4, borderRadius: 3, background: m.pnl >= 0 ? col : "#ff4466" }} />
                      </div>
                    </div>
                  );
                })}
              </div>

              <div className="card">
                <p className="lbl" style={{ marginBottom: 16 }}>Session Breakdown</p>
                {sessPerf.map(s => (
                  <div key={s.name} style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "10px 0", borderBottom: "1px solid #0f0f1e" }}>
                    <span style={{ fontSize: 12 }}>{s.name}</span>
                    <span style={{ fontSize: 11, color: "#aaa" }}>{s.count} trades</span>
                    <span className={s.pnl >= 0 ? "pos" : "neg"} style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700 }}>{s.pnl >= 0 ? "+" : ""}${s.pnl.toLocaleString()}</span>
                  </div>
                ))}
              </div>

              <div className="card">
                <p className="lbl" style={{ marginBottom: 16 }}>Risk Metrics</p>
                {[
                  ["Total Trades", trades.length],
                  ["Win Rate", `${winRate}%`],
                  ["Profit Factor", profitFactor],
                  ["Avg Win", `$${avgWin.toFixed(0)}`],
                  ["Avg Loss", `-$${avgLoss.toFixed(0)}`],
                  ["Win/Loss Ratio", avgLoss > 0 ? (avgWin / avgLoss).toFixed(2) : "\u221e"],
                  ["Max Drawdown", `-$${maxDD.toFixed(0)}`],
                  ["Net P&L", `${totalPnl >= 0 ? "+" : ""}$${totalPnl.toLocaleString()}`],
                ].map(([l, v]) => (
                  <div key={l} style={{ display: "flex", justifyContent: "space-between", padding: "8px 0", borderBottom: "1px solid #0c0c1c" }}>
                    <span style={{ fontSize: 12, color: "#ffffff" }}>{l}</span>
                    <span style={{ fontSize: 13, fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 600, color: "#ffffff" }}>{v}</span>
                  </div>
                ))}
              </div>
            </div>
          )}

          {/* NEWS / ECONOMIC CALENDAR */}
          {/* VIDEOS / RECORDINGS */}
          {view === "videos" && (
            <div>
              <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 20, fontWeight: 700, color: "#fff", marginBottom: 6 }}>Trading Videos</p>
              <p style={{ color: "#aaa", fontSize: 12, marginBottom: 22 }}>Manage your screen recordings — Review your trading sessions and attach videos to specific trades.</p>

              {/* Recordings List */}
              <div className="card">
                <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 16 }}>
                  <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700, fontSize: 16, color: "#7fffb2" }}>
                    {recordings.filter(r => !r.attached).length > 0
                      ? `Unattached Recordings (${recordings.filter(r => !r.attached).length})`
                      : "Unattached Recordings"
                    }
                  </p>
                  <span style={{ fontSize: 10, color: "#666", fontStyle: "italic" }}>
                    Videos saved locally in Downloads folder
                  </span>
                </div>

                {!recordingsLoaded ? (
                  <p style={{ color: "#666", fontSize: 12, fontStyle: "italic" }}>Loading recordings...</p>
                ) : recordings.filter(r => !r.attached).length === 0 ? (
                  <div style={{ textAlign: "center", padding: "40px 20px" }}>
                    <p style={{ fontSize: 40, marginBottom: 12 }}>🎥</p>
                    <p style={{ color: "#666", fontSize: 12, fontStyle: "italic", marginBottom: 8 }}>No recordings yet</p>
                    <p style={{ color: "#555", fontSize: 11 }}>
                      Click the blue <span style={{ color: "#4da6ff" }}>⏺</span> button to start recording your trading sessions
                    </p>
                  </div>
                ) : (
                  <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
                    {recordings
                      .filter(r => !r.attached)
                      .map((recording) => {
                        const createdDate = new Date(recording.createdAt);
                        const dateStr = createdDate.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
                        const timeStr = createdDate.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" });
                        const durationStr = formatTime(recording.duration || 0);
                        const sizeStr = (recording.size / (1024 * 1024)).toFixed(1) + " MB";

                        return (
                          <div key={recording.id} style={{
                            padding: "16px",
                            background: "rgba(255,255,255,0.02)",
                            borderRadius: 10,
                            border: "1px solid rgba(255,255,255,0.05)",
                            transition: "all 0.2s"
                          }}
                          onMouseEnter={(e) => {
                            e.currentTarget.style.background = "rgba(255,255,255,0.04)";
                            e.currentTarget.style.borderColor = "rgba(255,255,255,0.1)";
                          }}
                          onMouseLeave={(e) => {
                            e.currentTarget.style.background = "rgba(255,255,255,0.02)";
                            e.currentTarget.style.borderColor = "rgba(255,255,255,0.05)";
                          }}>
                            <div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: 16 }}>
                              <div style={{ flex: 1 }}>
                                <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 8 }}>
                                  <span style={{ fontSize: 16 }}>🎥</span>
                                  <p style={{ fontSize: 13, fontWeight: 600, color: "#fff", fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace" }}>
                                    {recording.fileName}
                                  </p>
                                </div>
                                <div style={{ display: "flex", gap: 16, fontSize: 11, color: "#888", marginBottom: 8 }}>
                                  <span>📅 {dateStr} at {timeStr}</span>
                                  <span>⏱ {durationStr}</span>
                                  <span>💾 {sizeStr}</span>
                                </div>
                                <p style={{ fontSize: 10, color: "#666", fontStyle: "italic" }}>
                                  Saved locally in Downloads folder
                                </p>
                              </div>
                              <div style={{ display: "flex", gap: 8 }}>
                                <button
                                  className="ghost"
                                  onClick={async () => {
                                    if (confirm(`Delete recording "${recording.fileName}"?\n\nNote: This will only remove it from this list. The video file in your Downloads folder will not be deleted.`)) {
                                      try {
                                        await db.collection('recordings').doc(recording.id).delete();
                                        setRecordings(prev => prev.filter(r => r.id !== recording.id));
                                      } catch (error) {
                                        console.error('Failed to delete recording:', error);
                                        alert('Failed to delete recording. Please try again.');
                                      }
                                    }
                                  }}
                                  style={{ padding: "6px 12px", fontSize: 11, color: "#ff4466" }}
                                >
                                  🗑 Delete
                                </button>
                              </div>
                            </div>
                          </div>
                        );
                      })}
                  </div>
                )}
              </div>

              {/* Attached Recordings */}
              {recordings.filter(r => r.attached).length > 0 && (
                <div className="card" style={{ marginTop: 20 }}>
                  <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 16 }}>
                    <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700, fontSize: 16, color: "#7ca5d4" }}>
                      Attached to Trades ({recordings.filter(r => r.attached).length})
                    </p>
                  </div>

                  <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
                    {recordings
                      .filter(r => r.attached)
                      .map((recording) => {
                        const createdDate = new Date(recording.createdAt);
                        const dateStr = createdDate.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
                        const timeStr = createdDate.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" });
                        const durationStr = formatTime(recording.duration || 0);
                        const sizeStr = (recording.size / (1024 * 1024)).toFixed(1) + " MB";

                        return (
                          <div key={recording.id} style={{
                            padding: "16px",
                            background: "rgba(255,255,255,0.02)",
                            borderRadius: 10,
                            border: "1px solid rgba(124,165,212,0.2)"
                          }}>
                            <div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: 16 }}>
                              <div style={{ flex: 1 }}>
                                <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 8 }}>
                                  <span style={{ fontSize: 16 }}>🎥</span>
                                  <p style={{ fontSize: 13, fontWeight: 600, color: "#fff", fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace" }}>
                                    {recording.fileName}
                                  </p>
                                  <span style={{ fontSize: 9, color: "#7ca5d4", fontWeight: 600, background: "rgba(124,165,212,0.1)", padding: "2px 6px", borderRadius: 4 }}>
                                    ATTACHED
                                  </span>
                                </div>
                                <div style={{ display: "flex", gap: 16, fontSize: 11, color: "#888", marginBottom: 8 }}>
                                  <span>📅 {dateStr} at {timeStr}</span>
                                  <span>⏱ {durationStr}</span>
                                  <span>💾 {sizeStr}</span>
                                </div>
                                {recording.tradeId && (
                                  <p style={{ fontSize: 10, color: "#7ca5d4" }}>
                                    📎 Linked to trade ID: {recording.tradeId}
                                  </p>
                                )}
                              </div>
                              <div style={{ display: "flex", gap: 8 }}>
                                <button
                                  className="ghost"
                                  onClick={async () => {
                                    if (confirm(`Delete recording "${recording.fileName}"?\n\nThis will also unlink it from the trade. The video file in your Downloads folder will not be deleted.`)) {
                                      try {
                                        await db.collection('recordings').doc(recording.id).delete();
                                        setRecordings(prev => prev.filter(r => r.id !== recording.id));
                                      } catch (error) {
                                        console.error('Failed to delete recording:', error);
                                        alert('Failed to delete recording. Please try again.');
                                      }
                                    }
                                  }}
                                  style={{ padding: "6px 12px", fontSize: 11, color: "#ff4466" }}
                                >
                                  🗑 Delete
                                </button>
                              </div>
                            </div>
                          </div>
                        );
                      })}
                  </div>
                </div>
              )}

              {/* Help Card */}
              <div className="card" style={{ marginTop: 20 }}>
                <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700, fontSize: 14, color: "#fff", marginBottom: 12 }}>💡 How to use Trading Videos</p>
                <div style={{ fontSize: 11, color: "#aaa", lineHeight: 1.6, display: "flex", flexDirection: "column", gap: 12 }}>
                  <p>
                    <strong style={{ color: "#7fffb2" }}>Recording your trades:</strong> Click the blue ⏺ button in the bottom-right corner to start recording. Select the monitor/window showing your trading platform (TradingView, Tradovate, etc.). Trade as normal, then click ⬛ to stop recording.
                  </p>
                  <p>
                    <strong style={{ color: "#7ca5d4" }}>Where are videos saved?</strong> Videos download instantly to your Downloads folder with timestamped filenames (e.g., <code style={{ background: "rgba(255,255,255,0.05)", padding: "2px 6px", borderRadius: 4, fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace" }}>ultratrack_recording_2026-03-23_14-30-45.webm</code>). We recommend creating a "Trading Videos" folder to organize them.
                  </p>
                  <p>
                    <strong style={{ color: "#ffbb00" }}>Attaching to trades:</strong> When you upload your CSV trades later, you'll be able to attach these recordings to specific trades for review. This helps you analyze what you did right and wrong during live trading sessions.
                  </p>
                  <p style={{ background: "rgba(255,255,255,0.02)", padding: "10px", borderRadius: 6, marginTop: 4 }}>
                    <strong style={{ color: "#ff9900" }}>⚠️ Note:</strong> Videos are stored locally on your device only. Make sure to back them up if needed. Deleting a recording from this list won't delete the actual video file from your Downloads folder.
                  </p>
                </div>
              </div>
            </div>
          )}

          {/* AI COACH */}
          {view === "ai-coach" && (
            <div>
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 22 }}>
                <div>
                  <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 20, fontWeight: 700, color: "#fff", marginBottom: 6 }}>Lyra</p>
                  <p style={{ color: "#aaa", fontSize: 12 }}>Your AI Trading Coach \u2014 Powered by Claude. Deep analysis of your futures edge, psychology & risk management.</p>
                </div>
                <button
                  className="gbtn"
                  onClick={() => setChatPanelOpen(true)}
                  style={{ display: "flex", alignItems: "center", gap: 8, padding: "8px 14px", fontSize: 12 }}
                >
                  <span style={{ fontSize: 14 }}>{"\u{1F4AC}"}</span>
                  Chat with Lyra
                </button>
              </div>

              {/* API Key Input */}
              <div className="card" style={{ marginBottom: 20 }}>
                <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700, fontSize: 14, color: "#fff", marginBottom: 8 }}>API Configuration</p>
                <p style={{ fontSize: 11, color: "#aaa", marginBottom: 12 }}>
                  Enter your Anthropic API key to enable AI coaching. Get your key at{" "}
                  <a href="https://console.anthropic.com/" target="_blank" rel="noopener noreferrer" style={{ color: "#7fffb2", textDecoration: "none" }}>
                    console.anthropic.com
                  </a>
                </p>
                <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
                  <input
                    type="password"
                    value={apiKey}
                    onChange={(e) => setApiKey(e.target.value)}
                    placeholder="sk-ant-api03-..."
                    style={{
                      flex: 1,
                      padding: "10px 14px",
                      background: "#09090f",
                      border: "1px solid #1e1e30",
                      borderRadius: 6,
                      color: "#fff",
                      fontSize: 12,
                      fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace"
                    }}
                  />
                  {apiKey && (
                    <span style={{ fontSize: 11, color: "#7fffb2" }}>✓ Key saved</span>
                  )}
                </div>
              </div>

              {/* Weekly Batch Analysis */}
              <div className="card" style={{ marginBottom: 20 }}>
                <div style={{ marginBottom: 16 }}>
                  <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700, fontSize: 15, color: "#fff", marginBottom: 5 }}>Weekly Batch Review</p>
                  <p style={{ fontSize: 12, color: "#aaa" }}>Comprehensive analysis of all trades in a week with patterns, insights & action items</p>
                </div>

                {/* Week Selector */}
                <div style={{ display: "flex", gap: 10, alignItems: "center", marginBottom: 16 }}>
                  <button
                    className="ghost"
                    onClick={() => {
                      const newStart = new Date(selectedWeek.start);
                      newStart.setDate(newStart.getDate() - 7);
                      const newEnd = new Date(selectedWeek.end);
                      newEnd.setDate(newEnd.getDate() - 7);
                      setSelectedWeek({ start: newStart, end: newEnd });
                    }}
                    style={{ padding: "6px 12px", fontSize: 11 }}
                  >
                    ← Prev Week
                  </button>
                  <div style={{ flex: 1, textAlign: "center" }}>
                    <p style={{ fontSize: 12, color: "#fff", fontWeight: 600 }}>
                      {selectedWeek.start.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })} - {selectedWeek.end.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })}
                    </p>
                    <p style={{ fontSize: 10, color: "#666" }}>
                      {trades.filter(t => {
                        const td = new Date(t.date);
                        return td >= selectedWeek.start && td <= selectedWeek.end;
                      }).length} trades
                    </p>
                  </div>
                  <button
                    className="ghost"
                    onClick={() => {
                      const newStart = new Date(selectedWeek.start);
                      newStart.setDate(newStart.getDate() + 7);
                      const newEnd = new Date(selectedWeek.end);
                      newEnd.setDate(newEnd.getDate() + 7);
                      setSelectedWeek({ start: newStart, end: newEnd });
                    }}
                    style={{ padding: "6px 12px", fontSize: 11 }}
                  >
                    Next Week →
                  </button>
                  <button
                    className="ghost"
                    onClick={() => {
                      const now = new Date();
                      const dayOfWeek = now.getDay();
                      const startOfWeek = new Date(now);
                      startOfWeek.setDate(now.getDate() - dayOfWeek);
                      startOfWeek.setHours(0, 0, 0, 0);
                      const endOfWeek = new Date(startOfWeek);
                      endOfWeek.setDate(startOfWeek.getDate() + 6);
                      endOfWeek.setHours(23, 59, 59, 999);
                      setSelectedWeek({ start: startOfWeek, end: endOfWeek });
                    }}
                    style={{ padding: "6px 12px", fontSize: 11 }}
                  >
                    This Week
                  </button>
                </div>

                {/* Previous Week Comparison Indicator */}
                {(() => {
                  const prevStart = new Date(selectedWeek.start);
                  prevStart.setDate(prevStart.getDate() - 7);
                  const prevEnd = new Date(selectedWeek.end);
                  prevEnd.setDate(prevEnd.getDate() - 7);
                  const prevWeekKey = `${prevStart.toISOString().split('T')[0]}_${prevEnd.toISOString().split('T')[0]}`;
                  const hasPrevTrades = trades.some(t => {
                    const td = new Date(t.date);
                    return td >= prevStart && td <= prevEnd;
                  });
                  return hasPrevTrades ? (
                    <div style={{ display: "flex", alignItems: "center", gap: 6, marginBottom: 10, padding: "6px 10px", background: "rgba(127,255,178,0.04)", borderRadius: 6, border: "1px solid rgba(127,255,178,0.1)" }}>
                      <div style={{ width: 5, height: 5, borderRadius: "50%", background: "#7fffb2", boxShadow: "0 0 4px #7fffb2" }} />
                      <p style={{ fontSize: 10, color: "#7fffb2", letterSpacing: ".05em" }}>
                        Previous week data available — Lyra will include week-over-week comparison
                      </p>
                    </div>
                  ) : null;
                })()}

                {/* Analyze Button */}
                <button
                  className="gbtn"
                  onClick={() => analyzeWeekly(selectedWeek.start, selectedWeek.end)}
                  disabled={weeklyAnalysis.loading}
                  style={{ width: "100%", marginBottom: weeklyAnalysis.loading || weeklyAnalysis.data || weeklyAnalysis.error ? 16 : 0 }}
                >
                  {weeklyAnalysis.loading ? "Analyzing Week..." : "Run Weekly Analysis"}
                </button>

                {/* Loading State */}
                {weeklyAnalysis.loading && (
                  <div style={{ padding: 20, background: "#09090f", borderRadius: 6, textAlign: "center" }}>
                    <p style={{ color: "#7fffb2", fontSize: 12 }} className="pulse">Claude is analyzing your week...</p>
                  </div>
                )}

                {/* Error State */}
                {weeklyAnalysis.error && (
                  <p style={{ color: "#ff4466", fontSize: 12 }}>{weeklyAnalysis.error}</p>
                )}

                {/* Analysis Results */}
                {weeklyAnalysis.data && (
                  <div>
                    {/* Stats Overview */}
                    <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(120px, 1fr))", gap: 10, marginBottom: 16 }}>
                      <div style={{ padding: 12, background: "#09090f", borderRadius: 6, border: "1px solid #1e1e30" }}>
                        <p style={{ fontSize: 9, color: "#666", letterSpacing: ".1em", marginBottom: 4 }}>TOTAL TRADES</p>
                        <p style={{ fontSize: 16, fontWeight: 700, color: "#fff" }}>{weeklyAnalysis.data.stats.totalTrades}</p>
                      </div>
                      <div style={{ padding: 12, background: "#09090f", borderRadius: 6, border: "1px solid #1e1e30" }}>
                        <p style={{ fontSize: 9, color: "#666", letterSpacing: ".1em", marginBottom: 4 }}>WIN RATE</p>
                        <p style={{ fontSize: 16, fontWeight: 700, color: weeklyAnalysis.data.stats.winRate >= 50 ? "#7fffb2" : "#ff4466" }}>
                          {weeklyAnalysis.data.stats.winRate}%
                        </p>
                      </div>
                      <div style={{ padding: 12, background: "#09090f", borderRadius: 6, border: "1px solid #1e1e30" }}>
                        <p style={{ fontSize: 9, color: "#666", letterSpacing: ".1em", marginBottom: 4 }}>TOTAL P&L</p>
                        <p style={{ fontSize: 16, fontWeight: 700, color: weeklyAnalysis.data.stats.totalPnL >= 0 ? "#7fffb2" : "#ff4466" }}>
                          {weeklyAnalysis.data.stats.totalPnL >= 0 ? "+" : ""}${weeklyAnalysis.data.stats.totalPnL.toFixed(2)}
                        </p>
                      </div>
                      <div style={{ padding: 12, background: "#09090f", borderRadius: 6, border: "1px solid #1e1e30" }}>
                        <p style={{ fontSize: 9, color: "#666", letterSpacing: ".1em", marginBottom: 4 }}>AVG WIN</p>
                        <p style={{ fontSize: 16, fontWeight: 700, color: "#7fffb2" }}>
                          ${weeklyAnalysis.data.stats.avgWin}
                        </p>
                      </div>
                      <div style={{ padding: 12, background: "#09090f", borderRadius: 6, border: "1px solid #1e1e30" }}>
                        <p style={{ fontSize: 9, color: "#666", letterSpacing: ".1em", marginBottom: 4 }}>AVG LOSS</p>
                        <p style={{ fontSize: 16, fontWeight: 700, color: "#ff4466" }}>
                          ${weeklyAnalysis.data.stats.avgLoss}
                        </p>
                      </div>
                    </div>

                    {/* AI Analysis */}
                    <div style={{ padding: 20, background: "#09090f", borderRadius: 6, border: "1px solid #7fffb218" }}>
                      <div style={{ display: "flex", gap: 7, alignItems: "center", marginBottom: 14, justifyContent: "space-between" }}>
                        <div style={{ display: "flex", gap: 7, alignItems: "center" }}>
                          <div style={{ width: 5, height: 5, borderRadius: "50%", background: "#7fffb2", boxShadow: "0 0 6px #7fffb2" }} />
                          <p style={{ fontSize: 9, color: "#7fffb2", letterSpacing: ".12em" }}>LYRA WEEKLY REVIEW</p>
                        </div>
                        <button
                          className="ghost"
                          onClick={() => downloadLyraReviewPDF(weeklyAnalysis.data, selectedWeek.start, selectedWeek.end)}
                          style={{ padding: "5px 12px", fontSize: 10, display: "flex", alignItems: "center", gap: 6 }}
                        >
                          <span style={{ fontSize: 13 }}>{"\u2913"}</span> Download PDF
                        </button>
                      </div>
                      <p className="ai-text" style={{ whiteSpace: "pre-wrap" }}>{weeklyAnalysis.data.analysis}</p>
                    </div>
                  </div>
                )}
              </div>

              {/* Monthly Review */}
              <div className="card" style={{ marginBottom: 20 }}>
                <div style={{ marginBottom: 16 }}>
                  <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700, fontSize: 15, color: "#fff", marginBottom: 5 }}>Monthly Review</p>
                  <p style={{ fontSize: 12, color: "#aaa" }}>Higher-level trends across the whole month — strategy evolution, emotional shifts, milestones & next-month focus</p>
                </div>

                {/* Month Selector */}
                <div style={{ display: "flex", gap: 10, alignItems: "center", marginBottom: 16 }}>
                  <button
                    className="ghost"
                    onClick={() => {
                      const newMonth = selectedMonth.month === 0 ? 11 : selectedMonth.month - 1;
                      const newYear = selectedMonth.month === 0 ? selectedMonth.year - 1 : selectedMonth.year;
                      setSelectedMonth({ year: newYear, month: newMonth });
                    }}
                    style={{ padding: "6px 12px", fontSize: 11 }}
                  >
                    ← Prev Month
                  </button>
                  <div style={{ flex: 1, textAlign: "center" }}>
                    <p style={{ fontSize: 12, color: "#fff", fontWeight: 600 }}>
                      {new Date(selectedMonth.year, selectedMonth.month, 1).toLocaleDateString('en-US', { month: 'long', year: 'numeric' })}
                    </p>
                    <p style={{ fontSize: 10, color: "#666" }}>
                      {trades.filter(t => {
                        const td = new Date(t.date);
                        return td.getFullYear() === selectedMonth.year && td.getMonth() === selectedMonth.month;
                      }).length} trades
                    </p>
                  </div>
                  <button
                    className="ghost"
                    onClick={() => {
                      const newMonth = selectedMonth.month === 11 ? 0 : selectedMonth.month + 1;
                      const newYear = selectedMonth.month === 11 ? selectedMonth.year + 1 : selectedMonth.year;
                      setSelectedMonth({ year: newYear, month: newMonth });
                    }}
                    style={{ padding: "6px 12px", fontSize: 11 }}
                  >
                    Next Month →
                  </button>
                  <button
                    className="ghost"
                    onClick={() => {
                      const now = new Date();
                      setSelectedMonth({ year: now.getFullYear(), month: now.getMonth() });
                    }}
                    style={{ padding: "6px 12px", fontSize: 11 }}
                  >
                    This Month
                  </button>
                </div>

                {/* Previous Month Comparison Indicator */}
                {(() => {
                  const prevMonth = selectedMonth.month === 0 ? 11 : selectedMonth.month - 1;
                  const prevYear = selectedMonth.month === 0 ? selectedMonth.year - 1 : selectedMonth.year;
                  const hasPrevTrades = trades.some(t => {
                    const td = new Date(t.date);
                    return td.getFullYear() === prevYear && td.getMonth() === prevMonth;
                  });
                  return hasPrevTrades ? (
                    <div style={{ display: "flex", alignItems: "center", gap: 6, marginBottom: 10, padding: "6px 10px", background: "rgba(127,255,178,0.04)", borderRadius: 6, border: "1px solid rgba(127,255,178,0.1)" }}>
                      <div style={{ width: 5, height: 5, borderRadius: "50%", background: "#7fffb2", boxShadow: "0 0 4px #7fffb2" }} />
                      <p style={{ fontSize: 10, color: "#7fffb2", letterSpacing: ".05em" }}>
                        Previous month data available — Lyra will include month-over-month comparison
                      </p>
                    </div>
                  ) : null;
                })()}

                {/* Analyze Button */}
                <button
                  className="gbtn"
                  onClick={() => analyzeMonthly(selectedMonth.year, selectedMonth.month)}
                  disabled={monthlyAnalysis.loading}
                  style={{ width: "100%", marginBottom: monthlyAnalysis.loading || monthlyAnalysis.data || monthlyAnalysis.error ? 16 : 0 }}
                >
                  {monthlyAnalysis.loading ? "Analyzing Month..." : "Run Monthly Analysis"}
                </button>

                {monthlyAnalysis.loading && (
                  <div style={{ padding: 20, background: "#09090f", borderRadius: 6, textAlign: "center" }}>
                    <p style={{ color: "#7fffb2", fontSize: 12 }} className="pulse">Claude is reviewing your month...</p>
                  </div>
                )}

                {monthlyAnalysis.error && (
                  <p style={{ color: "#ff4466", fontSize: 12 }}>{monthlyAnalysis.error}</p>
                )}

                {monthlyAnalysis.data && (
                  <div>
                    <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(120px, 1fr))", gap: 10, marginBottom: 16 }}>
                      <div style={{ padding: 12, background: "#09090f", borderRadius: 6, border: "1px solid #1e1e30" }}>
                        <p style={{ fontSize: 9, color: "#666", letterSpacing: ".1em", marginBottom: 4 }}>TOTAL TRADES</p>
                        <p style={{ fontSize: 16, fontWeight: 700, color: "#fff" }}>{monthlyAnalysis.data.stats.totalTrades}</p>
                      </div>
                      <div style={{ padding: 12, background: "#09090f", borderRadius: 6, border: "1px solid #1e1e30" }}>
                        <p style={{ fontSize: 9, color: "#666", letterSpacing: ".1em", marginBottom: 4 }}>WIN RATE</p>
                        <p style={{ fontSize: 16, fontWeight: 700, color: monthlyAnalysis.data.stats.winRate >= 50 ? "#7fffb2" : "#ff4466" }}>
                          {monthlyAnalysis.data.stats.winRate}%
                        </p>
                      </div>
                      <div style={{ padding: 12, background: "#09090f", borderRadius: 6, border: "1px solid #1e1e30" }}>
                        <p style={{ fontSize: 9, color: "#666", letterSpacing: ".1em", marginBottom: 4 }}>TOTAL P&L</p>
                        <p style={{ fontSize: 16, fontWeight: 700, color: monthlyAnalysis.data.stats.totalPnL >= 0 ? "#7fffb2" : "#ff4466" }}>
                          {monthlyAnalysis.data.stats.totalPnL >= 0 ? "+" : ""}${monthlyAnalysis.data.stats.totalPnL.toFixed(2)}
                        </p>
                      </div>
                      <div style={{ padding: 12, background: "#09090f", borderRadius: 6, border: "1px solid #1e1e30" }}>
                        <p style={{ fontSize: 9, color: "#666", letterSpacing: ".1em", marginBottom: 4 }}>AVG WIN</p>
                        <p style={{ fontSize: 16, fontWeight: 700, color: "#7fffb2" }}>
                          ${monthlyAnalysis.data.stats.avgWin}
                        </p>
                      </div>
                      <div style={{ padding: 12, background: "#09090f", borderRadius: 6, border: "1px solid #1e1e30" }}>
                        <p style={{ fontSize: 9, color: "#666", letterSpacing: ".1em", marginBottom: 4 }}>AVG LOSS</p>
                        <p style={{ fontSize: 16, fontWeight: 700, color: "#ff4466" }}>
                          ${monthlyAnalysis.data.stats.avgLoss}
                        </p>
                      </div>
                    </div>

                    <div style={{ padding: 20, background: "#09090f", borderRadius: 6, border: "1px solid #7fffb218" }}>
                      <div style={{ display: "flex", gap: 7, alignItems: "center", marginBottom: 14, justifyContent: "space-between" }}>
                        <div style={{ display: "flex", gap: 7, alignItems: "center" }}>
                          <div style={{ width: 5, height: 5, borderRadius: "50%", background: "#7fffb2", boxShadow: "0 0 6px #7fffb2" }} />
                          <p style={{ fontSize: 9, color: "#7fffb2", letterSpacing: ".12em" }}>LYRA MONTHLY REVIEW</p>
                        </div>
                        <button
                          className="ghost"
                          onClick={() => downloadMonthlyReviewPDF(monthlyAnalysis.data, selectedMonth.year, selectedMonth.month)}
                          style={{ padding: "5px 12px", fontSize: 10, display: "flex", alignItems: "center", gap: 6 }}
                        >
                          <span style={{ fontSize: 13 }}>{"\u2913"}</span> Download PDF
                        </button>
                      </div>
                      <p className="ai-text" style={{ whiteSpace: "pre-wrap" }}>{monthlyAnalysis.data.analysis}</p>
                    </div>
                  </div>
                )}
              </div>

              {/* Strategy Scorecard */}
              <div className="card" style={{ marginBottom: 20 }}>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 16 }}>
                  <div>
                    <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700, fontSize: 15, color: "#fff", marginBottom: 5 }}>Strategy Scorecard</p>
                    <p style={{ fontSize: 12, color: "#aaa" }}>Data-driven scoring of every strategy with at least 3 trades — grade, recommendation & next steps</p>
                  </div>
                  <button className="gbtn" onClick={scoreStrategies} disabled={strategyScores.loading}>
                    {strategyScores.loading ? "Scoring..." : "Score Strategies"}
                  </button>
                </div>

                {strategyScores.loading && (
                  <div style={{ padding: 20, background: "#09090f", borderRadius: 6, textAlign: "center" }}>
                    <p style={{ color: "#7fffb2", fontSize: 12 }} className="pulse">Lyra is grading your strategies...</p>
                  </div>
                )}

                {strategyScores.error && (
                  <p style={{ color: "#ff4466", fontSize: 12 }}>{strategyScores.error}</p>
                )}

                {strategyScores.data && strategyScores.data.strategies && (
                  <div>
                    {/* Portfolio Health */}
                    {strategyScores.data.portfolioHealth && (
                      <div style={{ padding: 14, background: "#09090f", borderRadius: 6, border: "1px solid #7fffb218", marginBottom: 16 }}>
                        <div style={{ display: "flex", gap: 7, alignItems: "center", marginBottom: 8 }}>
                          <div style={{ width: 5, height: 5, borderRadius: "50%", background: "#7fffb2", boxShadow: "0 0 6px #7fffb2" }} />
                          <p style={{ fontSize: 9, color: "#7fffb2", letterSpacing: ".12em" }}>PORTFOLIO HEALTH</p>
                        </div>
                        <p style={{ fontSize: 12, color: "#ccc", lineHeight: 1.5 }}>{strategyScores.data.portfolioHealth}</p>
                      </div>
                    )}

                    {/* Strategy cards grid */}
                    <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(280px, 1fr))", gap: 12 }}>
                      {strategyScores.data.strategies.map(s => {
                        const recColor = s.recommendation === "Focus" ? "#7fffb2"
                          : s.recommendation === "Refine" ? "#ffbb00"
                          : s.recommendation === "Retire" ? "#ff4466"
                          : "#7ca5d4";
                        const gradeColor = s.compositeScore >= 80 ? "#7fffb2"
                          : s.compositeScore >= 60 ? "#ffbb00"
                          : "#ff4466";
                        const consistencyPct = Math.round((s.metrics.consistency || 0) * 100);
                        return (
                          <div key={s.name} style={{ padding: 16, background: "#09090f", borderRadius: 8, border: "1px solid #1e1e30" }}>
                            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 12 }}>
                              <div style={{ flex: 1, minWidth: 0 }}>
                                <p style={{ fontSize: 14, fontWeight: 700, color: "#fff", marginBottom: 4, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{s.name}</p>
                                <span style={{ display: "inline-block", padding: "2px 8px", fontSize: 9, fontWeight: 700, letterSpacing: ".1em", borderRadius: 4, background: `${recColor}22`, color: recColor, border: `1px solid ${recColor}55` }}>
                                  {s.recommendation.toUpperCase()}
                                </span>
                              </div>
                              <div style={{ textAlign: "center", marginLeft: 12 }}>
                                <div style={{ width: 48, height: 48, borderRadius: "50%", background: `${gradeColor}18`, border: `2px solid ${gradeColor}`, display: "flex", alignItems: "center", justifyContent: "center" }}>
                                  <p style={{ fontSize: 16, fontWeight: 700, color: gradeColor }}>{s.grade}</p>
                                </div>
                                <p style={{ fontSize: 9, color: "#666", marginTop: 4 }}>{s.compositeScore}/100</p>
                              </div>
                            </div>

                            {/* Metric rows */}
                            <div style={{ marginBottom: 10 }}>
                              <div style={{ display: "flex", justifyContent: "space-between", fontSize: 10, color: "#888", padding: "3px 0" }}>
                                <span>Win Rate</span>
                                <span style={{ color: s.metrics.winRate >= 50 ? "#7fffb2" : "#ff4466", fontWeight: 600 }}>{s.metrics.winRate}%</span>
                              </div>
                              <div style={{ display: "flex", justifyContent: "space-between", fontSize: 10, color: "#888", padding: "3px 0" }}>
                                <span>Profit Factor</span>
                                <span style={{ color: s.metrics.profitFactor >= 1.5 ? "#7fffb2" : s.metrics.profitFactor >= 1 ? "#ffbb00" : "#ff4466", fontWeight: 600 }}>{s.metrics.profitFactor}x</span>
                              </div>
                              <div style={{ display: "flex", justifyContent: "space-between", fontSize: 10, color: "#888", padding: "3px 0" }}>
                                <span>Avg W/L</span>
                                <span style={{ color: s.metrics.avgWinLossRatio >= 1 ? "#7fffb2" : "#ff4466", fontWeight: 600 }}>{s.metrics.avgWinLossRatio}:1</span>
                              </div>
                              <div style={{ display: "flex", justifyContent: "space-between", fontSize: 10, color: "#888", padding: "3px 0" }}>
                                <span>Trades</span>
                                <span style={{ color: "#ccc", fontWeight: 600 }}>{s.metrics.frequency}</span>
                              </div>
                              <div style={{ display: "flex", justifyContent: "space-between", fontSize: 10, color: "#888", padding: "3px 0" }}>
                                <span>Total P&L</span>
                                <span style={{ color: s.metrics.totalPnL >= 0 ? "#7fffb2" : "#ff4466", fontWeight: 600 }}>
                                  {s.metrics.totalPnL >= 0 ? "+" : ""}${s.metrics.totalPnL.toFixed(2)}
                                </span>
                              </div>
                              <div style={{ display: "flex", justifyContent: "space-between", fontSize: 10, color: "#888", padding: "3px 0", alignItems: "center" }}>
                                <span>Consistency</span>
                                <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
                                  <div style={{ width: 50, height: 4, background: "#1e1e30", borderRadius: 2, overflow: "hidden" }}>
                                    <div style={{ width: `${consistencyPct}%`, height: "100%", background: consistencyPct >= 60 ? "#7fffb2" : consistencyPct >= 40 ? "#ffbb00" : "#ff4466" }} />
                                  </div>
                                  <span style={{ color: "#ccc", fontWeight: 600, minWidth: 28, textAlign: "right" }}>{consistencyPct}%</span>
                                </div>
                              </div>
                            </div>

                            {s.aiAnalysis && (
                              <p style={{ fontSize: 10, color: "#9595b0", lineHeight: 1.5, paddingTop: 8, borderTop: "1px solid #1e1e30" }}>{s.aiAnalysis}</p>
                            )}
                          </div>
                        );
                      })}
                    </div>
                  </div>
                )}
              </div>

              {/* Pattern Detection */}
              <div className="card" style={{ marginBottom: 20 }}>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 16 }}>
                  <div>
                    <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700, fontSize: 15, color: "#fff", marginBottom: 5 }}>Pattern Detection</p>
                    <p style={{ fontSize: 12, color: "#aaa" }}>Lyra finds recurring winning and losing combinations across your trade history</p>
                  </div>
                  <button className="gbtn" onClick={detectPatterns} disabled={patterns.loading}>
                    {patterns.loading ? "Detecting..." : "Detect Patterns"}
                  </button>
                </div>

                {patterns.loading && (
                  <div style={{ padding: 20, background: "#09090f", borderRadius: 6, textAlign: "center" }}>
                    <p style={{ color: "#7fffb2", fontSize: 12 }} className="pulse">Lyra is scanning for patterns...</p>
                  </div>
                )}

                {patterns.error && (
                  <p style={{ color: "#ff4466", fontSize: 12 }}>{patterns.error}</p>
                )}

                {patterns.data && patterns.data.patterns && (
                  <div>
                    <p style={{ fontSize: 10, color: "#666", marginBottom: 12 }}>
                      Analyzed {patterns.data.tradeCount} trades · {patterns.data.patterns.length} significant patterns
                    </p>

                    <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(320px, 1fr))", gap: 16 }}>
                      {/* LOSING patterns column */}
                      <div>
                        <div style={{ display: "flex", alignItems: "center", gap: 7, marginBottom: 10 }}>
                          <div style={{ width: 5, height: 5, borderRadius: "50%", background: "#ff4466", boxShadow: "0 0 6px #ff4466" }} />
                          <p style={{ fontSize: 9, color: "#ff4466", letterSpacing: ".12em" }}>LOSING PATTERNS</p>
                        </div>
                        {patterns.data.patterns.filter(p => p.type === 'losing').length === 0 ? (
                          <p style={{ fontSize: 11, color: "#666", fontStyle: "italic", padding: 12 }}>No significant losing patterns. Nice work.</p>
                        ) : (
                          <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
                            {patterns.data.patterns.filter(p => p.type === 'losing').map((p, i) => {
                              const sevColor = p.severity === "HIGH" ? "#ff4466" : p.severity === "MEDIUM" ? "#ffbb00" : "#9595b0";
                              return (
                                <div key={i} style={{ padding: 14, background: "#09090f", borderRadius: 6, border: "1px solid #ff446618" }}>
                                  <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 8 }}>
                                    <p style={{ fontSize: 13, fontWeight: 700, color: "#fff", flex: 1 }}>{p.description}</p>
                                    <span style={{ fontSize: 8, fontWeight: 700, letterSpacing: ".1em", padding: "2px 6px", borderRadius: 3, background: `${sevColor}22`, color: sevColor, border: `1px solid ${sevColor}55`, marginLeft: 8 }}>
                                      {p.severity}
                                    </span>
                                  </div>
                                  <p style={{ fontSize: 10, color: "#888", marginBottom: 8 }}>
                                    {p.stats.occurrences} trades · <span style={{ color: "#ff4466" }}>{p.stats.winRate}% WR</span> · <span style={{ color: "#ff4466" }}>${p.stats.totalPnL.toFixed(2)} total</span> · ${p.stats.avgPnL.toFixed(2)}/trade
                                  </p>
                                  {p.aiInsight && (
                                    <p style={{ fontSize: 11, color: "#bbb", lineHeight: 1.5, marginBottom: 6 }}>{p.aiInsight}</p>
                                  )}
                                  {p.recommendation && (
                                    <p style={{ fontSize: 10, color: "#7fffb2", lineHeight: 1.5, paddingTop: 6, borderTop: "1px solid #1e1e30" }}>
                                      <strong>→</strong> {p.recommendation}
                                    </p>
                                  )}
                                </div>
                              );
                            })}
                          </div>
                        )}
                      </div>

                      {/* WINNING patterns column */}
                      <div>
                        <div style={{ display: "flex", alignItems: "center", gap: 7, marginBottom: 10 }}>
                          <div style={{ width: 5, height: 5, borderRadius: "50%", background: "#7fffb2", boxShadow: "0 0 6px #7fffb2" }} />
                          <p style={{ fontSize: 9, color: "#7fffb2", letterSpacing: ".12em" }}>WINNING PATTERNS</p>
                        </div>
                        {patterns.data.patterns.filter(p => p.type === 'winning').length === 0 ? (
                          <p style={{ fontSize: 11, color: "#666", fontStyle: "italic", padding: 12 }}>No significant winning patterns yet — keep building your edge.</p>
                        ) : (
                          <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
                            {patterns.data.patterns.filter(p => p.type === 'winning').map((p, i) => {
                              const sevColor = p.severity === "HIGH" ? "#7fffb2" : p.severity === "MEDIUM" ? "#ffbb00" : "#9595b0";
                              return (
                                <div key={i} style={{ padding: 14, background: "#09090f", borderRadius: 6, border: "1px solid #7fffb218" }}>
                                  <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 8 }}>
                                    <p style={{ fontSize: 13, fontWeight: 700, color: "#fff", flex: 1 }}>{p.description}</p>
                                    <span style={{ fontSize: 8, fontWeight: 700, letterSpacing: ".1em", padding: "2px 6px", borderRadius: 3, background: `${sevColor}22`, color: sevColor, border: `1px solid ${sevColor}55`, marginLeft: 8 }}>
                                      {p.severity}
                                    </span>
                                  </div>
                                  <p style={{ fontSize: 10, color: "#888", marginBottom: 8 }}>
                                    {p.stats.occurrences} trades · <span style={{ color: "#7fffb2" }}>{p.stats.winRate}% WR</span> · <span style={{ color: "#7fffb2" }}>+${p.stats.totalPnL.toFixed(2)} total</span> · ${p.stats.avgPnL.toFixed(2)}/trade
                                  </p>
                                  {p.aiInsight && (
                                    <p style={{ fontSize: 11, color: "#bbb", lineHeight: 1.5, marginBottom: 6 }}>{p.aiInsight}</p>
                                  )}
                                  {p.recommendation && (
                                    <p style={{ fontSize: 10, color: "#7fffb2", lineHeight: 1.5, paddingTop: 6, borderTop: "1px solid #1e1e30" }}>
                                      <strong>→</strong> {p.recommendation}
                                    </p>
                                  )}
                                </div>
                              );
                            })}
                          </div>
                        )}
                      </div>
                    </div>
                  </div>
                )}
              </div>

              <div className="card" style={{ marginBottom: 20 }}>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: aiReport || aiLoading || aiError ? 20 : 0 }}>
                  <div>
                    <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700, fontSize: 15, color: "#fff", marginBottom: 5 }}>Full Portfolio Review</p>
                    <p style={{ fontSize: 12, color: "#aaa" }}>Analyzes all {trades.length} trades \u2014 strategy edge, psychology, session timing & risk</p>
                  </div>
                  <button className="gbtn" onClick={runAnalysis} disabled={aiLoading}>{aiLoading ? "Analyzing..." : "Run Analysis"}</button>
                </div>
                {aiLoading && <div style={{ padding: 20, background: "#09090f", borderRadius: 6, textAlign: "center" }}><p style={{ color: "#7fffb2", fontSize: 12 }} className="pulse">Claude is reviewing your trading journal...</p></div>}
                {aiError && <p style={{ color: "#ff4466", fontSize: 12 }}>{aiError}</p>}
                {aiReport && (
                  <div style={{ padding: 20, background: "#09090f", borderRadius: 6, border: "1px solid #7fffb218" }}>
                    <div style={{ display: "flex", gap: 7, alignItems: "center", marginBottom: 14 }}>
                      <div style={{ width: 5, height: 5, borderRadius: "50%", background: "#7fffb2", boxShadow: "0 0 6px #7fffb2" }} />
                      <p style={{ fontSize: 9, color: "#7fffb2", letterSpacing: ".12em" }}>LYRA ANALYSIS COMPLETE</p>
                    </div>
                    <p className="ai-text">{aiReport}</p>
                  </div>
                )}
              </div>

              <div className="card">
                <p className="lbl" style={{ marginBottom: 4 }}>Trade-by-Trade Coaching</p>
                <p style={{ fontSize: 11, color: "#9595b0", marginBottom: 16 }}>Get specific AI feedback on execution, psychology & improvement for each trade.</p>
                {trades.map(t => (
                  <div key={t.id} style={{ padding: "12px 0", borderBottom: "1px solid #0f0f1e" }}>
                    <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
                      <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
                        <span style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700, color: "#fff", fontSize: 14 }}>
                          {t.ticker}
                          {t.source === "csv" && <span className="tv-badge">CSV</span>}
                        </span>
                        <span style={{ fontSize: 10, color: "#9595b0" }}>{formatDateDisplay(t.date)}</span>
                        <span className="tag" style={{ background: "#111120", color: "#ffffff" }}>{t.strategy}</span>
                        <span className="tag" style={{ color: emotionColors[t.emotion] || "#888", background: `${emotionColors[t.emotion] || "#888"}12` }}>{t.emotion}</span>
                        <span className="tag" style={{ background: "#111120", color: "#aaa", fontSize: 9 }}>{t.session}</span>
                      </div>
                      <div style={{ display: "flex", gap: 12, alignItems: "center" }}>
                        <span className={t.pnl >= 0 ? "pos" : "neg"} style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700 }}>{t.pnl >= 0 ? "+" : ""}${t.pnl.toLocaleString()}</span>
                        {!tradeAi[t.id] && <button className="ghost" onClick={() => analyzeOne(t)}>Analyze</button>}
                        {tradeAi[t.id]?.loading && <span style={{ fontSize: 10, color: "#7fffb2" }} className="pulse">Thinking...</span>}
                      </div>
                    </div>
                    {tradeAi[t.id]?.text && (
                      <div style={{ marginTop: 10, padding: 14, background: "#09090f", borderRadius: 6, border: "1px solid #181828" }}>
                        <p className="ai-text">{tradeAi[t.id].text}</p>
                      </div>
                    )}
                  </div>
                ))}
              </div>

              {/* CHAT WITH LYRA PANEL */}
              {chatPanelOpen && (
                <>
                  {/* Mobile backdrop */}
                  <div
                    onClick={() => setChatPanelOpen(false)}
                    style={{
                      position: "fixed",
                      inset: 0,
                      background: "rgba(0,0,0,0.5)",
                      zIndex: 998,
                      display: "block"
                    }}
                  />
                  <div style={{
                    position: "fixed",
                    top: 0,
                    right: 0,
                    bottom: 0,
                    width: "min(420px, 100vw)",
                    background: "#0a0a12",
                    borderLeft: "1px solid #1e1e30",
                    boxShadow: "-4px 0 24px rgba(0,0,0,0.5)",
                    zIndex: 999,
                    display: "flex",
                    flexDirection: "column"
                  }}>
                    {/* Header */}
                    <div style={{ padding: "16px 18px", borderBottom: "1px solid #1e1e30", display: "flex", justifyContent: "space-between", alignItems: "center" }}>
                      <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                        <div style={{ width: 8, height: 8, borderRadius: "50%", background: "#7fffb2", boxShadow: "0 0 8px #7fffb2" }} />
                        <div>
                          <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 14, fontWeight: 700, color: "#fff" }}>Chat with Lyra</p>
                          <p style={{ fontSize: 9, color: "#666", letterSpacing: ".1em" }}>HAS ACCESS TO YOUR JOURNAL</p>
                        </div>
                      </div>
                      <div style={{ display: "flex", gap: 6 }}>
                        {chatMessages.length > 0 && (
                          <button
                            onClick={clearChat}
                            style={{ background: "none", border: "1px solid #1e1e30", color: "#888", padding: "4px 10px", borderRadius: 4, cursor: "pointer", fontSize: 10 }}
                            title="Clear chat history"
                          >
                            Clear
                          </button>
                        )}
                        <button
                          onClick={() => setChatPanelOpen(false)}
                          style={{ background: "none", border: "none", color: "#aaa", cursor: "pointer", fontSize: 22, lineHeight: 1, padding: "0 4px" }}
                        >
                          {"\u00D7"}
                        </button>
                      </div>
                    </div>

                    {/* Messages area */}
                    <div style={{ flex: 1, overflowY: "auto", padding: "16px 18px", display: "flex", flexDirection: "column", gap: 12 }}>
                      {chatMessages.length === 0 && (
                        <div style={{ textAlign: "center", padding: "40px 20px" }}>
                          <p style={{ fontSize: 32, marginBottom: 12 }}>{"\u{1F4AC}"}</p>
                          <p style={{ fontSize: 13, color: "#aaa", marginBottom: 8, fontWeight: 600 }}>Ask Lyra anything about your trading</p>
                          <p style={{ fontSize: 11, color: "#666", lineHeight: 1.5 }}>Lyra knows your trade history, patterns, strategy grades, and recent performance. Try one of the prompts below or type your own.</p>
                        </div>
                      )}
                      {chatMessages.map((m, i) => (
                        <div key={i} style={{ display: "flex", justifyContent: m.role === "user" ? "flex-end" : "flex-start" }}>
                          <div style={{
                            maxWidth: "85%",
                            padding: "10px 14px",
                            borderRadius: 10,
                            background: m.role === "user" ? "#1a1a3a" : "#111120",
                            border: m.role === "user" ? "1px solid #2a2a4a" : "1px solid #7fffb218",
                            fontSize: 12,
                            color: m.role === "user" ? "#fff" : "#ddd",
                            lineHeight: 1.5,
                            whiteSpace: "pre-wrap",
                            wordWrap: "break-word"
                          }}>
                            {m.role === "assistant" && (
                              <div style={{ display: "flex", alignItems: "center", gap: 6, marginBottom: 6 }}>
                                <div style={{ width: 4, height: 4, borderRadius: "50%", background: "#7fffb2" }} />
                                <p style={{ fontSize: 8, color: "#7fffb2", letterSpacing: ".1em" }}>LYRA</p>
                              </div>
                            )}
                            {m.content}
                          </div>
                        </div>
                      ))}
                      {chatLoading && (
                        <div style={{ display: "flex", justifyContent: "flex-start" }}>
                          <div style={{ padding: "10px 14px", borderRadius: 10, background: "#111120", border: "1px solid #7fffb218", fontSize: 12 }}>
                            <p style={{ color: "#7fffb2" }} className="pulse">Lyra is thinking...</p>
                          </div>
                        </div>
                      )}
                    </div>

                    {/* Quick prompts */}
                    {chatMessages.length === 0 && (
                      <div style={{ padding: "0 18px 12px", display: "flex", flexWrap: "wrap", gap: 6 }}>
                        {[
                          "Why do I lose on Fridays?",
                          "What's my best setup?",
                          "Which emotions cost me most?",
                          "Should I retire any strategies?",
                          "Compare this week to last month"
                        ].map(prompt => (
                          <button
                            key={prompt}
                            onClick={() => sendChatMessage(prompt)}
                            disabled={chatLoading}
                            style={{
                              background: "#111120",
                              border: "1px solid #1e1e30",
                              color: "#aaa",
                              padding: "6px 10px",
                              borderRadius: 14,
                              fontSize: 10,
                              cursor: chatLoading ? "not-allowed" : "pointer",
                              opacity: chatLoading ? 0.5 : 1
                            }}
                          >
                            {prompt}
                          </button>
                        ))}
                      </div>
                    )}

                    {/* Input area */}
                    <div style={{ padding: "12px 18px 18px", borderTop: "1px solid #1e1e30" }}>
                      <div style={{ display: "flex", gap: 8 }}>
                        <input
                          type="text"
                          value={chatInput}
                          onChange={e => setChatInput(e.target.value)}
                          onKeyDown={e => {
                            if (e.key === "Enter" && !e.shiftKey && !chatLoading && chatInput.trim()) {
                              e.preventDefault();
                              sendChatMessage(chatInput);
                            }
                          }}
                          placeholder="Ask Lyra about your trading..."
                          disabled={chatLoading}
                          style={{
                            flex: 1,
                            padding: "10px 12px",
                            background: "#09090f",
                            border: "1px solid #1e1e30",
                            borderRadius: 6,
                            color: "#fff",
                            fontSize: 12,
                            outline: "none"
                          }}
                        />
                        <button
                          onClick={() => sendChatMessage(chatInput)}
                          disabled={chatLoading || !chatInput.trim()}
                          className="gbtn"
                          style={{ padding: "10px 16px", fontSize: 12, opacity: (chatLoading || !chatInput.trim()) ? 0.5 : 1 }}
                        >
                          Send
                        </button>
                      </div>
                    </div>
                  </div>
                </>
              )}
            </div>
          )}
        </div>
      </div>

      {/* CSV IMPORT MODAL */}
      {showImport && (
        <div className="ov" onClick={e => { if (e.target === e.currentTarget) setShowImport(false); }}>
          <div className="modal" style={{ filter: isDark ? "none" : "invert(1) hue-rotate(180deg)" }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 22 }}>
              <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 800, fontSize: 17, color: "#fff" }}>Import Tradovate CSV</p>
              <button onClick={() => setShowImport(false)} style={{ background: "none", border: "none", color: "#aaa", cursor: "pointer", fontSize: 24 }}>{"\u00D7"}</button>
            </div>

            <div
              onDragOver={e => { e.preventDefault(); setImportDragOver(true); }}
              onDragLeave={() => setImportDragOver(false)}
              onDrop={e => { e.preventDefault(); setImportDragOver(false); handleCsvFile(e.dataTransfer.files[0]); }}
              onClick={() => fileInputRef.current?.click()}
              style={{
                border: `2px dashed ${importDragOver ? "#7fffb2" : "#1e1e38"}`,
                borderRadius: 8,
                padding: "40px 20px",
                textAlign: "center",
                cursor: "pointer",
                background: importDragOver ? "rgba(127,255,178,.04)" : "transparent",
                transition: "all .2s",
                marginBottom: 16,
              }}
            >
              <input
                ref={fileInputRef}
                type="file"
                accept=".csv"
                style={{ display: "none" }}
                onChange={e => handleCsvFile(e.target.files[0])}
              />
              <p style={{ fontSize: 28, marginBottom: 8, opacity: 0.3 }}>{"\uD83D\uDCC4"}</p>
              <p style={{ fontSize: 13, color: "#ffffff", marginBottom: 6 }}>Drag & drop your Tradovate CSV here</p>
              <p style={{ fontSize: 11, color: "#aaa" }}>or click to browse files</p>
            </div>

            <div style={{ background: "#09090f", borderRadius: 6, padding: "14px 16px", marginBottom: 16 }}>
              <p style={{ fontSize: 10, color: "#7fffb2", letterSpacing: ".1em", marginBottom: 8 }}>HOW TO EXPORT FROM TRADOVATE</p>
              <ol style={{ fontSize: 11, color: "#ffffff", lineHeight: 1.8, paddingLeft: 16, margin: 0 }}>
                <li>Open Tradovate &rarr; click your account name dropdown</li>
                <li>Click the gear icon &rarr; <b style={{ color: "#eee" }}>Account Reports</b></li>
                <li>Go to the <b style={{ color: "#7fffb2" }}>Orders</b> tab (not Performance)</li>
                <li>Select your date range &rarr; click <b style={{ color: "#eee" }}>Download Report</b></li>
                <li>Drop the downloaded CSV file here</li>
              </ol>
            </div>

            {/* Import preview */}
            {importPreview && (
              <div style={{ marginBottom: 16 }}>
                <p style={{ fontSize: 11, color: "#7fffb2", marginBottom: 10 }}>Found {importPreview.length} trade{importPreview.length !== 1 ? "s" : ""} to import:</p>
                <div style={{ maxHeight: 200, overflowY: "auto", border: "1px solid #181828", borderRadius: 6 }}>
                  {importPreview.map((t, i) => (
                    <div key={i} style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "8px 12px", borderBottom: "1px solid #0f0f1e" }}>
                      <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
                        <span style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700, color: "#fff", fontSize: 13 }}>{t.ticker}</span>
                        <span className="tag" style={{ background: t.direction === "Long" ? "rgba(127,255,178,.1)" : "rgba(255,68,102,.1)", color: t.direction === "Long" ? "#7fffb2" : "#ff4466" }}>{t.direction}</span>
                        <span style={{ fontSize: 10, color: "#aaa" }}>{t.date}</span>
                        <span style={{ fontSize: 10, color: "#ffffff" }}>{t.size}ct</span>
                      </div>
                      <span className={t.pnl >= 0 ? "pos" : "neg"} style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 700, fontSize: 13 }}>{t.pnl >= 0 ? "+" : ""}${t.pnl.toLocaleString()}</span>
                    </div>
                  ))}
                </div>
                <div style={{ display: "flex", gap: 10, marginTop: 12 }}>
                  <button className="gbtn" onClick={confirmImport} style={{ flex: 1 }}>Import {importPreview.length} Trade{importPreview.length !== 1 ? "s" : ""}</button>
                  <button className="ghost" onClick={() => { setImportPreview(null); setImportResult(null); }}>Cancel</button>
                </div>
              </div>
            )}

            {/* Import result message */}
            {importResult && (
              <div style={{ padding: "12px 16px", borderRadius: 6, background: importResult.error ? "rgba(255,68,102,.08)" : "rgba(127,255,178,.08)", border: `1px solid ${importResult.error ? "#ff446633" : "#7fffb233"}` }}>
                <p style={{ fontSize: 12, color: importResult.error ? "#ff4466" : "#7fffb2" }}>
                  {importResult.error || `Successfully imported ${importResult.count} trade${importResult.count !== 1 ? "s" : ""}!`}
                </p>
              </div>
            )}
          </div>
        </div>
      )}

      {/* LOG TRADE MODAL */}
      {showForm && (
        <div className="ov" onClick={e => { if (e.target === e.currentTarget) setShowForm(false); }}>
          <div className="modal" style={{ filter: isDark ? "none" : "invert(1) hue-rotate(180deg)" }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 22 }}>
              <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontWeight: 800, fontSize: 17, color: "#fff" }}>Log Futures Trade</p>
              <button onClick={() => setShowForm(false)} style={{ background: "none", border: "none", color: "#aaa", cursor: "pointer", fontSize: 24 }}>\u00D7</button>
            </div>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }}>
              <div><span className="lbl">Date</span><input type="date" value={form.date} onChange={e => setForm(p => ({ ...p, date: e.target.value }))} /></div>
              <div>
                <span className="lbl">Instrument</span>
                <select value={form.market} onChange={e => setForm(p => ({ ...p, market: e.target.value, ticker: e.target.value }))}>
                  {INSTRUMENTS.map(i => <option key={i}>{i}</option>)}
                </select>
                {form.market && POINT_VALUES[form.market] && <p style={{ fontSize: 9, color: "#aaa", marginTop: 4 }}>Point value: ${POINT_VALUES[form.market]?.toLocaleString()}/pt</p>}
              </div>
              <div>
                <span className="lbl">Direction</span>
                <div style={{ display: "flex", gap: 6 }}>
                  {["Long", "Short"].map(d => (
                    <button key={d} onClick={() => setForm(p => ({ ...p, direction: d }))} style={{ flex: 1, padding: "8px", border: `1px solid ${form.direction === d ? (d === "Long" ? "#7fffb2" : "#ff4466") : "#181828"}`, borderRadius: 4, background: form.direction === d ? (d === "Long" ? "rgba(127,255,178,.1)" : "rgba(255,68,102,.1)") : "none", color: form.direction === d ? (d === "Long" ? "#7fffb2" : "#ff4466") : "#ccc", cursor: "pointer", fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 12, letterSpacing: ".05em" }}>{d}</button>
                  ))}
                </div>
              </div>
              <div><span className="lbl">Contracts</span><input type="number" min="1" placeholder="1" value={form.size} onChange={e => setForm(p => ({ ...p, size: e.target.value }))} /></div>
              <div><span className="lbl">Entry Price</span><input type="number" step="0.25" placeholder="0.00" value={form.entry} onChange={e => setForm(p => ({ ...p, entry: e.target.value }))} /></div>
              <div><span className="lbl">Exit Price</span><input type="number" step="0.25" placeholder="0.00" value={form.exit} onChange={e => setForm(p => ({ ...p, exit: e.target.value }))} /></div>
              <div><span className="lbl">Entry Time</span><input type="time" step="1" placeholder="HH:MM:SS" value={form.entryTime} onChange={e => setForm(p => ({ ...p, entryTime: e.target.value }))} /></div>
              <div><span className="lbl">Exit Time</span><input type="time" step="1" placeholder="HH:MM:SS" value={form.exitTime} onChange={e => setForm(p => ({ ...p, exitTime: e.target.value }))} /></div>
              <div>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 6 }}>
                  <span className="lbl" style={{ margin: 0 }}>Strategy</span>
                  <button type="button" className="ghost" onClick={() => setShowStrategyManager(true)} style={{ padding: "4px 8px", fontSize: 9 }}>Manage</button>
                </div>
                <select value={form.strategy} onChange={e => setForm(p => ({ ...p, strategy: e.target.value }))}>
                  {allStrategies.map(s => <option key={s}>{s}</option>)}
                </select>
              </div>
              <div>
                <span className="lbl">Session</span>
                <select value={form.session} onChange={e => setForm(p => ({ ...p, session: e.target.value }))}>
                  {SESSIONS.map(s => <option key={s}>{s}</option>)}
                </select>
              </div>
              <div style={{ gridColumn: "span 2" }}>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 6 }}>
                  <span className="lbl" style={{ margin: 0 }}>Emotional State</span>
                  <button className="ghost" onClick={() => setShowEmotionManager(true)} style={{ padding: "2px 8px", fontSize: 9 }}>Manage</button>
                </div>
                <div style={{ display: "flex", flexWrap: "wrap", gap: 5 }}>
                  {allEmotions.map(e => {
                    const col = emotionColors[e] || "#888";
                    const isCustom = customEmotions.includes(e);
                    return (
                      <button key={e} onClick={() => setForm(p => ({ ...p, emotion: e }))} style={{ padding: "4px 9px", border: `1px solid ${form.emotion === e ? col : "#1a1a2a"}`, borderRadius: 4, background: form.emotion === e ? `${col}18` : "none", color: form.emotion === e ? (isCustom ? "#7fffb2" : col) : (isCustom ? "#7fffb2" : "#bbb"), cursor: "pointer", fontSize: 10, fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", transition: "all .15s", letterSpacing: ".05em" }}>{e}</button>
                    );
                  })}
                </div>
              </div>
              <div style={{ gridColumn: "span 2" }}>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 6 }}>
                  <span className="lbl" style={{ margin: 0 }}>Mistakes / Errors</span>
                  <button className="ghost" onClick={() => setShowMistakeManager(true)} style={{ padding: "2px 8px", fontSize: 9 }}>Manage</button>
                </div>
                <div style={{ display: "flex", flexWrap: "wrap", gap: 5 }}>
                  {allMistakes.map(m => {
                    const col = mistakeColors[m] || "#888";
                    const isCustom = customMistakes.includes(m);
                    const isSelected = (form.mistake || []).includes(m);
                    return (
                      <button key={m} onClick={() => setForm(p => {
                        const cur = p.mistake || ["None"];
                        if (m === "None") return { ...p, mistake: ["None"] };
                        const without = cur.filter(x => x !== "None");
                        if (without.includes(m)) {
                          const result = without.filter(x => x !== m);
                          return { ...p, mistake: result.length === 0 ? ["None"] : result };
                        }
                        return { ...p, mistake: [...without, m] };
                      })} style={{ padding: "4px 9px", border: `1px solid ${isSelected ? col : "#1a1a2a"}`, borderRadius: 4, background: isSelected ? `${col}18` : "none", color: isSelected ? (isCustom ? "#7fffb2" : col) : (isCustom ? "#7fffb2" : "#bbb"), cursor: "pointer", fontSize: 10, fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", transition: "all .15s", letterSpacing: ".05em" }}>{m}</button>
                    );
                  })}
                </div>
              </div>
              <div style={{ gridColumn: "span 2" }}>
                <span className="lbl">Trade Notes</span>
                <textarea rows={3} placeholder="Setup rationale, what happened, what you learned..." value={form.notes} onChange={e => setForm(p => ({ ...p, notes: e.target.value }))} />
              </div>
            </div>

            {previewPnl !== null && (
              <div style={{ margin: "16px 0", padding: "12px 16px", background: "#09090f", borderRadius: 6, border: `1px solid ${previewPnl >= 0 ? "#7fffb222" : "#ff446622"}`, display: "flex", justifyContent: "space-between", alignItems: "center" }}>
                <div>
                  <p style={{ fontSize: 9, color: "#aaa", letterSpacing: ".1em", marginBottom: 3 }}>ESTIMATED P&L</p>
                  <p style={{ fontSize: 10, color: "#9595b0" }}>{Math.abs((+form.exit) - (+form.entry)).toFixed(2)} pts × {form.size}ct × ${POINT_VALUES[form.market]}</p>
                </div>
                <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 22, fontWeight: 700 }} className={previewPnl >= 0 ? "pos" : "neg"}>{previewPnl >= 0 ? "+" : ""}${previewPnl.toLocaleString()}</p>
              </div>
            )}
            <button className="gbtn" onClick={handleSubmit} style={{ width: "100%", marginTop: 4 }}>Save Trade</button>
          </div>
        </div>
      )}

      {/* STRATEGY MANAGER */}
      {showStrategyManager && (
        <div onClick={() => setShowStrategyManager(false)} style={{ position: "fixed", top: 0, left: 0, right: 0, bottom: 0, background: "rgba(0,0,0,0.85)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 1000 }}>
          <div onClick={e => e.stopPropagation()} style={{ background: "#0c0c18", border: "1px solid #1e1e30", borderRadius: 8, padding: "28px 32px", maxWidth: 500, width: "90%", maxHeight: "80vh", overflow: "auto" }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 20 }}>
              <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 18, fontWeight: 700, color: "#fff", margin: 0 }}>Manage Strategies</p>
              <button onClick={() => setShowStrategyManager(false)} style={{ background: "none", border: "none", color: "#aaa", cursor: "pointer", fontSize: 24 }}>×</button>
            </div>

            <div style={{ marginBottom: 24 }}>
              <p className="lbl" style={{ marginBottom: 8 }}>Add Custom Strategy</p>
              <div style={{ display: "flex", gap: 8 }}>
                <input
                  type="text"
                  placeholder="e.g., Supply & Demand"
                  value={newStrategy}
                  onChange={e => setNewStrategy(e.target.value)}
                  onKeyPress={e => e.key === 'Enter' && addCustomStrategy()}
                  style={{ flex: 1 }}
                />
                <button className="gbtn" onClick={addCustomStrategy}>Add</button>
              </div>
            </div>

            <div>
              <p className="lbl" style={{ marginBottom: 12 }}>Default Strategies</p>
              <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginBottom: 20 }}>
                {STRATEGIES.map(s => (
                  <div key={s} style={{ padding: "6px 12px", background: "#111120", border: "1px solid #222235", borderRadius: 4, fontSize: 11, color: "#aaa" }}>
                    {s}
                  </div>
                ))}
              </div>
            </div>

            {customStrategies.length > 0 && (
              <div>
                <p className="lbl" style={{ marginBottom: 12 }}>Custom Strategies</p>
                <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
                  {customStrategies.map(s => (
                    <div key={s} style={{ padding: "6px 12px", background: "#7fffb218", border: "1px solid #7fffb244", borderRadius: 4, fontSize: 11, color: "#7fffb2", display: "flex", alignItems: "center", gap: 8 }}>
                      {s}
                      <button onClick={() => deleteCustomStrategy(s)} style={{ background: "none", border: "none", color: "#ff4466", cursor: "pointer", fontSize: 14, padding: 0, lineHeight: 1 }}>×</button>
                    </div>
                  ))}
                </div>
              </div>
            )}
          </div>
        </div>
      )}

      {/* EMOTION MANAGER MODAL */}
      {showEmotionManager && (
        <div onClick={() => setShowEmotionManager(false)} style={{ position: "fixed", top: 0, left: 0, right: 0, bottom: 0, background: "rgba(0,0,0,0.85)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 1000 }}>
          <div onClick={e => e.stopPropagation()} style={{ background: "#0c0c18", border: "1px solid #1e1e30", borderRadius: 8, padding: "28px 32px", maxWidth: 500, width: "90%", maxHeight: "80vh", overflow: "auto" }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 20 }}>
              <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 18, fontWeight: 700, color: "#fff", margin: 0 }}>Manage Emotions</p>
              <button onClick={() => setShowEmotionManager(false)} style={{ background: "none", border: "none", color: "#aaa", cursor: "pointer", fontSize: 24 }}>×</button>
            </div>

            <div style={{ marginBottom: 24 }}>
              <p className="lbl" style={{ marginBottom: 8 }}>Add Custom Emotion</p>
              <div style={{ display: "flex", gap: 8 }}>
                <input
                  type="text"
                  placeholder="e.g., Frustrated"
                  value={newEmotion}
                  onChange={e => setNewEmotion(e.target.value)}
                  onKeyPress={e => e.key === 'Enter' && addCustomEmotion()}
                  style={{ flex: 1 }}
                />
                <button className="gbtn" onClick={addCustomEmotion}>Add</button>
              </div>
            </div>

            <div>
              <p className="lbl" style={{ marginBottom: 12 }}>Default Emotions</p>
              <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginBottom: 20 }}>
                {EMOTIONS.map(e => (
                  <div key={e} style={{ padding: "6px 12px", background: "#111120", border: "1px solid #222235", borderRadius: 4, fontSize: 11, color: "#aaa" }}>
                    {e}
                  </div>
                ))}
              </div>
            </div>

            {customEmotions.length > 0 && (
              <div>
                <p className="lbl" style={{ marginBottom: 12 }}>Custom Emotions</p>
                <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
                  {customEmotions.map(e => (
                    <div key={e} style={{ padding: "6px 12px", background: "#7fffb218", border: "1px solid #7fffb244", borderRadius: 4, fontSize: 11, color: "#7fffb2", display: "flex", alignItems: "center", gap: 8 }}>
                      {e}
                      <button onClick={() => deleteCustomEmotion(e)} style={{ background: "none", border: "none", color: "#ff4466", cursor: "pointer", fontSize: 14, padding: 0, lineHeight: 1 }}>×</button>
                    </div>
                  ))}
                </div>
              </div>
            )}
          </div>
        </div>
      )}

      {/* MISTAKE MANAGER MODAL */}
      {showMistakeManager && (
        <div onClick={() => setShowMistakeManager(false)} style={{ position: "fixed", top: 0, left: 0, right: 0, bottom: 0, background: "rgba(0,0,0,0.85)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 1000 }}>
          <div onClick={e => e.stopPropagation()} style={{ background: "#0c0c18", border: "1px solid #1e1e30", borderRadius: 8, padding: "28px 32px", maxWidth: 500, width: "90%", maxHeight: "80vh", overflow: "auto" }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 20 }}>
              <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 18, fontWeight: 700, color: "#fff", margin: 0 }}>Manage Mistakes</p>
              <button onClick={() => setShowMistakeManager(false)} style={{ background: "none", border: "none", color: "#aaa", cursor: "pointer", fontSize: 24 }}>×</button>
            </div>

            <div style={{ marginBottom: 24 }}>
              <p className="lbl" style={{ marginBottom: 8 }}>Add Custom Mistake</p>
              <div style={{ display: "flex", gap: 8 }}>
                <input
                  type="text"
                  placeholder="e.g., Ignored Setup"
                  value={newMistake}
                  onChange={e => setNewMistake(e.target.value)}
                  onKeyPress={e => e.key === 'Enter' && addCustomMistake()}
                  style={{ flex: 1 }}
                />
                <button className="gbtn" onClick={addCustomMistake}>Add</button>
              </div>
            </div>

            <div>
              <p className="lbl" style={{ marginBottom: 12 }}>Default Mistakes</p>
              <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginBottom: 20 }}>
                {MISTAKES.map(m => (
                  <div key={m} style={{ padding: "6px 12px", background: "#111120", border: "1px solid #222235", borderRadius: 4, fontSize: 11, color: "#aaa" }}>
                    {m}
                  </div>
                ))}
              </div>
            </div>

            {customMistakes.length > 0 && (
              <div>
                <p className="lbl" style={{ marginBottom: 12 }}>Custom Mistakes</p>
                <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
                  {customMistakes.map(m => (
                    <div key={m} style={{ padding: "6px 12px", background: "#7fffb218", border: "1px solid #7fffb244", borderRadius: 4, fontSize: 11, color: "#7fffb2", display: "flex", alignItems: "center", gap: 8 }}>
                      {m}
                      <button onClick={() => deleteCustomMistake(m)} style={{ background: "none", border: "none", color: "#ff4466", cursor: "pointer", fontSize: 14, padding: 0, lineHeight: 1 }}>×</button>
                    </div>
                  ))}
                </div>
              </div>
            )}
          </div>
        </div>
      )}

      {/* RULES MANAGER MODAL */}
      {showRulesManager && (
        <div onClick={() => setShowRulesManager(false)} style={{ position: "fixed", top: 0, left: 0, right: 0, bottom: 0, background: "rgba(0,0,0,0.85)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 1000 }}>
          <div onClick={e => e.stopPropagation()} style={{ background: "#0c0c18", border: "1px solid #1e1e30", borderRadius: 8, padding: "28px 32px", maxWidth: 560, width: "90%", maxHeight: "80vh", overflow: "auto" }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 20 }}>
              <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 18, fontWeight: 700, color: "#fff", margin: 0 }}>Manage Trading Rules</p>
              <button onClick={() => setShowRulesManager(false)} style={{ background: "none", border: "none", color: "#aaa", cursor: "pointer", fontSize: 24 }}>×</button>
            </div>

            {/* Add new rule */}
            <div style={{ marginBottom: 24 }}>
              <p className="lbl" style={{ marginBottom: 8 }}>Add New Rule</p>
              <div style={{ display: "flex", gap: 8 }}>
                <input
                  type="text"
                  placeholder="e.g., No trading during news events"
                  value={newRuleText}
                  onChange={e => setNewRuleText(e.target.value)}
                  onKeyPress={e => e.key === 'Enter' && addTradingRule()}
                  style={{ flex: 1 }}
                />
                <select
                  value={newRuleCategory}
                  onChange={e => setNewRuleCategory(e.target.value)}
                  style={{ width: 120, fontSize: 11 }}
                >
                  <option value="risk">Risk</option>
                  <option value="process">Process</option>
                  <option value="mindset">Mindset</option>
                </select>
                <button className="gbtn" onClick={addTradingRule}>Add</button>
              </div>
            </div>

            {/* Load defaults button */}
            <div style={{ marginBottom: 24, display: "flex", justifyContent: "flex-end" }}>
              <button
                className="ghost"
                onClick={loadDefaultRules}
                style={{ fontSize: 11, padding: "6px 14px" }}
              >
                {tradingRules.length === 0 ? "Load Default Rules" : "Reset to Defaults"}
              </button>
            </div>

            {/* Rules by category */}
            {["risk", "process", "mindset"].map(cat => {
              const catRules = tradingRules.filter(r => r.category === cat);
              if (catRules.length === 0 && tradingRules.length > 0) return null;
              return (
                <div key={cat} style={{ marginBottom: 20 }}>
                  <p className="lbl" style={{ marginBottom: 10, color: RULE_CATEGORY_COLORS[cat] }}>
                    {RULE_CATEGORY_LABELS[cat]}
                  </p>
                  {catRules.length === 0 ? (
                    <p style={{ fontSize: 11, color: "#555", fontStyle: "italic" }}>No rules in this category</p>
                  ) : (
                    <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
                      {catRules.map(rule => (
                        <div key={rule.id} style={{
                          display: "flex", alignItems: "center", gap: 8,
                          padding: "8px 12px",
                          background: rule.active !== false ? `${RULE_CATEGORY_COLORS[cat]}08` : "#111120",
                          border: `1px solid ${rule.active !== false ? RULE_CATEGORY_COLORS[cat] + "33" : "#222235"}`,
                          borderRadius: 6,
                          opacity: rule.active !== false ? 1 : 0.5
                        }}>
                          {editingRuleId === rule.id ? (
                            <div style={{ flex: 1, display: "flex", gap: 6 }}>
                              <input
                                type="text"
                                value={editingRuleText}
                                onChange={e => setEditingRuleText(e.target.value)}
                                onKeyPress={e => e.key === 'Enter' && saveEditRule(rule.id)}
                                style={{ flex: 1, fontSize: 11 }}
                                autoFocus
                              />
                              <button className="gbtn" onClick={() => saveEditRule(rule.id)} style={{ fontSize: 10, padding: "4px 10px" }}>Save</button>
                              <button className="ghost" onClick={() => setEditingRuleId(null)} style={{ fontSize: 10, padding: "4px 10px" }}>Cancel</button>
                            </div>
                          ) : (
                            <>
                              <span style={{ flex: 1, fontSize: 12, color: rule.active !== false ? "#ddd" : "#666", fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace" }}>
                                {rule.text}
                              </span>
                              <button
                                onClick={() => toggleRuleActive(rule.id)}
                                title={rule.active !== false ? "Disable rule" : "Enable rule"}
                                style={{ background: "none", border: "none", cursor: "pointer", fontSize: 14, color: rule.active !== false ? "#7fffb2" : "#555", padding: "2px 4px" }}
                              >
                                {rule.active !== false ? "ON" : "OFF"}
                              </button>
                              <button
                                onClick={() => { setEditingRuleId(rule.id); setEditingRuleText(rule.text); }}
                                style={{ background: "none", border: "none", cursor: "pointer", fontSize: 12, color: "#666", padding: "2px 4px" }}
                              >
                                Edit
                              </button>
                              <button
                                onClick={() => deleteTradingRule(rule.id)}
                                style={{ background: "none", border: "none", color: "#ff4466", cursor: "pointer", fontSize: 14, padding: "2px 4px", lineHeight: 1 }}
                              >
                                ×
                              </button>
                            </>
                          )}
                        </div>
                      ))}
                    </div>
                  )}
                </div>
              );
            })}

            {tradingRules.length === 0 && (
              <div style={{ textAlign: "center", padding: "20px 0" }}>
                <p style={{ fontSize: 12, color: "#666", marginBottom: 12 }}>No rules configured yet</p>
                <button className="gbtn" onClick={loadDefaultRules}>Load Default Rules</button>
              </div>
            )}
          </div>
        </div>
      )}

      {/* EDIT STRATEGY MODAL */}
      {editStrategyTrade && (
        <div onClick={() => setEditStrategyTrade(null)} style={{ position: "fixed", top: 0, left: 0, right: 0, bottom: 0, background: "rgba(0,0,0,0.85)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 1000 }}>
          <div onClick={e => e.stopPropagation()} style={{ background: "#0c0c18", border: "1px solid #1e1e30", borderRadius: 8, padding: "28px 32px", maxWidth: 450, width: "90%" }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 20 }}>
              <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 18, fontWeight: 700, color: "#fff", margin: 0 }}>Edit Strategy</p>
              <button onClick={() => setEditStrategyTrade(null)} style={{ background: "none", border: "none", color: "#aaa", cursor: "pointer", fontSize: 24 }}>×</button>
            </div>
            <div style={{ marginBottom: 20 }}>
              <p style={{ fontSize: 12, color: "#ffffff", marginBottom: 8 }}>
                Trade: <span style={{ color: "#fff", fontWeight: 600 }}>{editStrategyTrade.ticker}</span> | {formatDateDisplay(editStrategyTrade.date)}
                {editStrategyTrade.source === "csv" && <span className="tv-badge" style={{ marginLeft: 8 }}>CSV</span>}
              </p>
              <p className="lbl" style={{ marginBottom: 8 }}>Strategy</p>
              <select value={editStrategyValue} onChange={e => setEditStrategyValue(e.target.value)} style={{ width: "100%", marginBottom: 16 }}>
                {allStrategies.map(s => <option key={s}>{s}</option>)}
              </select>
              <p style={{ fontSize: 11, color: "#666", fontStyle: "italic" }}>You can also create custom strategies from the "Manage" button in the trade form.</p>
            </div>
            <div style={{ display: "flex", gap: 10 }}>
              <button className="ghost" onClick={() => setEditStrategyTrade(null)} style={{ flex: 1 }}>Cancel</button>
              <button className="gbtn" onClick={saveEditStrategy} style={{ flex: 1 }}>Save Changes</button>
            </div>
          </div>
        </div>
      )}

      {/* EDIT EMOTION MODAL */}
      {editEmotionTrade && (
        <div onClick={() => setEditEmotionTrade(null)} style={{ position: "fixed", top: 0, left: 0, right: 0, bottom: 0, background: "rgba(0,0,0,0.85)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 1000 }}>
          <div onClick={e => e.stopPropagation()} style={{ background: "#0c0c18", border: "1px solid #1e1e30", borderRadius: 8, padding: "28px 32px", maxWidth: 500, width: "90%" }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 20 }}>
              <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 18, fontWeight: 700, color: "#fff", margin: 0 }}>Edit Emotional State</p>
              <button onClick={() => setEditEmotionTrade(null)} style={{ background: "none", border: "none", color: "#aaa", cursor: "pointer", fontSize: 24 }}>×</button>
            </div>
            <div style={{ marginBottom: 20 }}>
              <p style={{ fontSize: 12, color: "#ffffff", marginBottom: 16 }}>
                Trade: <span style={{ color: "#fff", fontWeight: 600 }}>{editEmotionTrade.ticker}</span> | {formatDateDisplay(editEmotionTrade.date)}
                {editEmotionTrade.source === "csv" && <span className="tv-badge" style={{ marginLeft: 8 }}>CSV</span>}
              </p>
              <p className="lbl" style={{ marginBottom: 12 }}>Emotional State</p>
              <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
                {allEmotions.map(e => {
                  const col = emotionColors[e] || "#888";
                  const isSelected = editEmotionValue === e;
                  return (
                    <button
                      key={e}
                      onClick={() => setEditEmotionValue(e)}
                      style={{
                        padding: "8px 14px",
                        border: `1px solid ${isSelected ? col : "#1a1a2a"}`,
                        borderRadius: 4,
                        background: isSelected ? `${col}18` : "none",
                        color: isSelected ? col : "#666",
                        cursor: "pointer",
                        fontSize: 11,
                        fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace",
                        transition: "all .15s",
                        letterSpacing: ".05em"
                      }}
                    >
                      {e}
                    </button>
                  );
                })}
              </div>
            </div>
            <div style={{ display: "flex", gap: 10 }}>
              <button className="ghost" onClick={() => setEditEmotionTrade(null)} style={{ flex: 1 }}>Cancel</button>
              <button className="gbtn" onClick={saveEditEmotion} style={{ flex: 1 }}>Save Changes</button>
            </div>
          </div>
        </div>
      )}

      {/* EDIT MISTAKE MODAL */}
      {editMistakeTrade && (
        <div onClick={() => setEditMistakeTrade(null)} style={{ position: "fixed", top: 0, left: 0, right: 0, bottom: 0, background: "rgba(0,0,0,0.85)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 1000 }}>
          <div onClick={e => e.stopPropagation()} style={{ background: "#0c0c18", border: "1px solid #1e1e30", borderRadius: 8, padding: "28px 32px", maxWidth: 500, width: "90%" }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 20 }}>
              <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 18, fontWeight: 700, color: "#fff", margin: 0 }}>Edit Mistake/Error</p>
              <button onClick={() => setEditMistakeTrade(null)} style={{ background: "none", border: "none", color: "#aaa", cursor: "pointer", fontSize: 24 }}>×</button>
            </div>
            <div style={{ marginBottom: 20 }}>
              <p style={{ fontSize: 12, color: "#ffffff", marginBottom: 16 }}>
                Trade: <span style={{ color: "#fff", fontWeight: 600 }}>{editMistakeTrade.ticker}</span> | {formatDateDisplay(editMistakeTrade.date)}
                {editMistakeTrade.source === "csv" && <span className="tv-badge" style={{ marginLeft: 8 }}>CSV</span>}
              </p>
              <p className="lbl" style={{ marginBottom: 12 }}>Mistake/Error</p>
              <p style={{ fontSize: 10, color: "#666", marginBottom: 8 }}>Select multiple mistakes (click to toggle)</p>
              <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }}>
                {allMistakes.map(m => {
                  const col = mistakeColors[m] || "#888";
                  const isSelected = (editMistakeValue || []).includes(m);
                  return (
                    <button
                      key={m}
                      onClick={() => toggleEditMistake(m)}
                      style={{
                        padding: "8px 14px",
                        border: `1px solid ${isSelected ? col : "#1a1a2a"}`,
                        borderRadius: 4,
                        background: isSelected ? `${col}18` : "none",
                        color: isSelected ? col : "#666",
                        cursor: "pointer",
                        fontSize: 11,
                        fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace",
                        transition: "all .15s",
                        letterSpacing: ".05em"
                      }}
                    >
                      {m}
                    </button>
                  );
                })}
              </div>
            </div>
            <div style={{ display: "flex", gap: 10 }}>
              <button className="ghost" onClick={() => setEditMistakeTrade(null)} style={{ flex: 1 }}>Cancel</button>
              <button className="gbtn" onClick={saveEditMistake} style={{ flex: 1 }}>Save Changes</button>
            </div>
          </div>
        </div>
      )}

      {/* EDIT TIME MODAL */}
      {editTimeTrade && (
        <div onClick={() => setEditTimeTrade(null)} style={{ position: "fixed", top: 0, left: 0, right: 0, bottom: 0, background: "rgba(0,0,0,0.85)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 1000 }}>
          <div onClick={e => e.stopPropagation()} style={{ background: "#0c0c18", border: "1px solid #1e1e30", borderRadius: 8, padding: "28px 32px", maxWidth: 450, width: "90%" }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 20 }}>
              <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 18, fontWeight: 700, color: "#fff", margin: 0 }}>Edit Entry/Exit Times</p>
              <button onClick={() => setEditTimeTrade(null)} style={{ background: "none", border: "none", color: "#aaa", cursor: "pointer", fontSize: 24 }}>×</button>
            </div>
            <div style={{ marginBottom: 20 }}>
              <p style={{ fontSize: 12, color: "#ffffff", marginBottom: 16 }}>
                Trade: <span style={{ color: "#fff", fontWeight: 600 }}>{editTimeTrade.ticker}</span> | {formatDateDisplay(editTimeTrade.date)}
                {editTimeTrade.source === "csv" && <span className="tv-badge" style={{ marginLeft: 8 }}>CSV</span>}
              </p>
              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14, marginBottom: 12 }}>
                <div>
                  <span className="lbl">Entry Time</span>
                  <input type="time" step="1" value={editEntryTime} onChange={e => setEditEntryTime(e.target.value)} style={{ width: "100%" }} />
                </div>
                <div>
                  <span className="lbl">Exit Time</span>
                  <input type="time" step="1" value={editExitTime} onChange={e => setEditExitTime(e.target.value)} style={{ width: "100%" }} />
                </div>
              </div>
              <p style={{ fontSize: 11, color: "#666", fontStyle: "italic" }}>Update the entry and exit times for this trade. Use 24-hour format (HH:MM:SS).</p>
            </div>
            <div style={{ display: "flex", gap: 10 }}>
              <button className="ghost" onClick={() => setEditTimeTrade(null)} style={{ flex: 1 }}>Cancel</button>
              <button className="gbtn" onClick={saveEditTime} style={{ flex: 1 }}>Save Changes</button>
            </div>
          </div>
        </div>
      )}

      {/* EDIT NOTES MODAL */}
      {editNotesTrade && (
        <div onClick={() => setEditNotesTrade(null)} style={{ position: "fixed", top: 0, left: 0, right: 0, bottom: 0, background: "rgba(0,0,0,0.85)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 1000 }}>
          <div onClick={e => e.stopPropagation()} style={{ background: "#0c0c18", border: "1px solid #1e1e30", borderRadius: 8, padding: "28px 32px", maxWidth: 800, width: "90%", maxHeight: "90vh", overflowY: "auto" }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 20 }}>
              <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 18, fontWeight: 700, color: "#fff", margin: 0 }}>Trade Notes</p>
              <button onClick={() => setEditNotesTrade(null)} style={{ background: "none", border: "none", color: "#aaa", cursor: "pointer", fontSize: 24 }}>×</button>
            </div>

            <div style={{ marginBottom: 20 }}>
              <p style={{ fontSize: 12, color: "#ffffff", marginBottom: 16 }}>
                Trade: <span style={{ color: "#fff", fontWeight: 600 }}>{editNotesTrade.ticker}</span> | {formatDateDisplay(editNotesTrade.date)} |
                <span className={editNotesTrade.pnl >= 0 ? "pos" : "neg"} style={{ marginLeft: 6 }}>
                  {editNotesTrade.pnl >= 0 ? "+" : ""}${editNotesTrade.pnl.toLocaleString()}
                </span>
                {editNotesTrade.source === "csv" && <span className="tv-badge" style={{ marginLeft: 8 }}>CSV</span>}
              </p>

              {/* Unified Notes Section with Drag & Drop */}
              <div
                onDragOver={handleDragOver}
                onDragLeave={handleDragLeave}
                onDrop={handleDrop}
                style={{
                  background: dragOver ? "rgba(127,255,178,0.05)" : "#09090f",
                  border: `2px dashed ${dragOver ? "#7fffb2" : "#222235"}`,
                  borderRadius: 8,
                  padding: 20,
                  transition: "all 0.2s",
                  minHeight: 400
                }}
              >
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 12 }}>
                  <p className="lbl" style={{ margin: 0 }}>Notes & Screenshots</p>
                  <div style={{ display: "flex", gap: 8 }}>
                    <button className="ghost" onClick={insertBulletPoint} style={{ padding: "4px 10px", fontSize: 10 }}>• Bullet</button>
                    <button className="ghost" onClick={() => imageInputRef.current?.click()} style={{ padding: "4px 10px", fontSize: 10 }}>
                      📷 Add Image
                    </button>
                  </div>
                  <input
                    ref={imageInputRef}
                    type="file"
                    accept="image/*"
                    multiple
                    style={{ display: "none" }}
                    onChange={handleImageUpload}
                  />
                </div>

                <p style={{ fontSize: 10, color: "#666", marginBottom: 12, fontStyle: "italic" }}>
                  💡 Tip: Drag & drop screenshots directly from your computer, or click "Add Image" to upload
                </p>

                {/* Text Area */}
                <textarea
                  id="notes-textarea"
                  rows={6}
                  placeholder="Type your notes here...&#10;&#10;• Entry reason&#10;• What went well&#10;• Areas to improve&#10;&#10;Add screenshots below by dragging images or clicking 'Add Image'"
                  value={notesText}
                  onChange={e => setNotesText(e.target.value)}
                  style={{
                    resize: "vertical",
                    minHeight: 120,
                    marginBottom: 16,
                    background: "#0a0a14",
                    border: "1px solid #181828"
                  }}
                />

                {/* Images Section - Integrated */}
                {notesImages.length > 0 && (
                  <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
                    {notesImages.map((img, index) => (
                      <div key={img.id} style={{ position: "relative" }}>
                        <div style={{ position: "relative", background: "#0a0a14", borderRadius: 6, padding: 12, border: "1px solid #181828" }}>
                          <img
                            src={img.dataUrl}
                            alt={img.name}
                            style={{
                              width: "100%",
                              maxHeight: 400,
                              objectFit: "contain",
                              borderRadius: 4,
                              marginBottom: 8,
                              cursor: "pointer"
                            }}
                            onClick={() => setPreviewImage(img)}
                          />
                          <p style={{ fontSize: 10, color: "#666", marginBottom: 0 }}>Screenshot {index + 1}: {img.name}</p>
                          <button
                            onClick={() => removeImage(img.id)}
                            style={{
                              position: "absolute",
                              top: 20,
                              right: 20,
                              background: "#ff4466",
                              border: "none",
                              color: "#fff",
                              width: 28,
                              height: 28,
                              borderRadius: "50%",
                              cursor: "pointer",
                              fontSize: 16,
                              display: "flex",
                              alignItems: "center",
                              justifyContent: "center",
                              padding: 0,
                              boxShadow: "0 2px 8px rgba(0,0,0,0.3)"
                            }}
                            title="Remove image"
                          >
                            ×
                          </button>
                        </div>
                      </div>
                    ))}
                  </div>
                )}

                {dragOver && (
                  <div style={{
                    position: "absolute",
                    top: "50%",
                    left: "50%",
                    transform: "translate(-50%, -50%)",
                    pointerEvents: "none",
                    textAlign: "center"
                  }}>
                    <p style={{ fontSize: 24, marginBottom: 8 }}>📷</p>
                    <p style={{ fontSize: 14, color: "#7fffb2", fontWeight: 600 }}>Drop screenshots here</p>
                  </div>
                )}
              </div>
            </div>

            <div style={{ display: "flex", gap: 10 }}>
              <button className="ghost" onClick={() => setEditNotesTrade(null)} style={{ flex: 1 }}>Cancel</button>
              <button className="gbtn" onClick={saveEditNotes} style={{ flex: 1 }}>Save Notes</button>
            </div>
          </div>
        </div>
      )}

      {/* ATTACH VIDEO MODAL */}
      {attachVideoTrade && (
        <div onClick={() => setAttachVideoTrade(null)} style={{ position: "fixed", top: 0, left: 0, right: 0, bottom: 0, background: "rgba(0,0,0,0.85)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 1000 }}>
          <div onClick={e => e.stopPropagation()} style={{ background: "#0c0c18", border: "1px solid #1e1e30", borderRadius: 12, padding: "24px", maxWidth: 600, width: "90%", maxHeight: "80vh", overflow: "auto" }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 20 }}>
              <div>
                <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 18, fontWeight: 700, color: "#fff", marginBottom: 4 }}>Attach Video to Trade</p>
                <p style={{ fontSize: 11, color: "#888" }}>Select a recording to attach to this trade</p>
              </div>
              <button onClick={() => setAttachVideoTrade(null)} style={{ background: "none", border: "none", color: "#aaa", cursor: "pointer", fontSize: 24 }}>×</button>
            </div>

            {recordings.filter(r => !r.attached || r.tradeId === attachVideoTrade.id).length === 0 ? (
              <div style={{ textAlign: "center", padding: "40px 20px" }}>
                <p style={{ fontSize: 32, marginBottom: 12 }}>🎥</p>
                <p style={{ color: "#666", fontSize: 12, fontStyle: "italic", marginBottom: 8 }}>No recordings available</p>
                <p style={{ color: "#555", fontSize: 10 }}>
                  Record a video using the blue ⏺ button, then come back here to attach it
                </p>
              </div>
            ) : (
              <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
                {recordings
                  .filter(r => !r.attached || r.tradeId === attachVideoTrade.id)
                  .map((recording) => {
                    const createdDate = new Date(recording.createdAt);
                    const dateStr = createdDate.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
                    const timeStr = createdDate.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" });
                    const durationStr = formatTime(recording.duration || 0);
                    const sizeStr = (recording.size / (1024 * 1024)).toFixed(1) + " MB";
                    const isAttached = recording.tradeId === attachVideoTrade.id;

                    return (
                      <div key={recording.id} style={{
                        padding: "14px",
                        background: isAttached ? "rgba(127,255,178,0.05)" : "rgba(255,255,255,0.02)",
                        borderRadius: 8,
                        border: isAttached ? "1px solid rgba(127,255,178,0.2)" : "1px solid rgba(255,255,255,0.05)",
                        cursor: "pointer",
                        transition: "all 0.2s"
                      }}
                      onClick={async () => {
                        try {
                          // Update recording in Firestore
                          await db.collection('recordings').doc(recording.id).update({
                            attached: true,
                            tradeId: attachVideoTrade.id
                          });

                          // Update local state
                          setRecordings(prev => prev.map(r =>
                            r.id === recording.id
                              ? { ...r, attached: true, tradeId: attachVideoTrade.id }
                              : r
                          ));

                          setAttachVideoTrade(null);
                        } catch (error) {
                          console.error('Failed to attach video:', error);
                          alert('Failed to attach video. Please try again.');
                        }
                      }}
                      onMouseEnter={(e) => {
                        if (!isAttached) {
                          e.currentTarget.style.background = "rgba(255,255,255,0.04)";
                          e.currentTarget.style.borderColor = "rgba(255,255,255,0.1)";
                        }
                      }}
                      onMouseLeave={(e) => {
                        if (!isAttached) {
                          e.currentTarget.style.background = "rgba(255,255,255,0.02)";
                          e.currentTarget.style.borderColor = "rgba(255,255,255,0.05)";
                        }
                      }}>
                        <div style={{ display: "flex", alignItems: "flex-start", gap: 12 }}>
                          <span style={{ fontSize: 20 }}>🎥</span>
                          <div style={{ flex: 1 }}>
                            <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 6 }}>
                              <p style={{ fontSize: 12, fontWeight: 600, color: "#fff", fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace" }}>
                                {recording.fileName}
                              </p>
                              {isAttached && (
                                <span style={{ fontSize: 8, color: "#7fffb2", fontWeight: 600, background: "rgba(127,255,178,0.1)", padding: "2px 6px", borderRadius: 4 }}>
                                  ATTACHED
                                </span>
                              )}
                            </div>
                            <div style={{ display: "flex", gap: 12, fontSize: 10, color: "#888" }}>
                              <span>📅 {dateStr} at {timeStr}</span>
                              <span>⏱ {durationStr}</span>
                              <span>💾 {sizeStr}</span>
                            </div>
                          </div>
                        </div>
                      </div>
                    );
                  })}
              </div>
            )}

            <div style={{ display: "flex", gap: 10, marginTop: 20 }}>
              <button className="ghost" onClick={() => setAttachVideoTrade(null)} style={{ flex: 1 }}>Cancel</button>
              {recordings.find(r => r.tradeId === attachVideoTrade.id) && (
                <button className="ghost" onClick={async () => {
                  const attachedRecording = recordings.find(r => r.tradeId === attachVideoTrade.id);
                  if (attachedRecording) {
                    try {
                      await db.collection('recordings').doc(attachedRecording.id).update({
                        attached: false,
                        tradeId: null
                      });

                      setRecordings(prev => prev.map(r =>
                        r.id === attachedRecording.id
                          ? { ...r, attached: false, tradeId: null }
                          : r
                      ));

                      setAttachVideoTrade(null);
                    } catch (error) {
                      console.error('Failed to detach video:', error);
                      alert('Failed to detach video. Please try again.');
                    }
                  }
                }} style={{ flex: 1, color: "#ff4466" }}>Detach Video</button>
              )}
            </div>
          </div>
        </div>
      )}

      {/* SHARE TRADE CARD MODAL */}
      {shareCardTrade && (
        <div onClick={() => setShareCardTrade(null)} style={{ position: "fixed", top: 0, left: 0, right: 0, bottom: 0, background: "rgba(0,0,0,0.9)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 1000, backdropFilter: "blur(10px)" }}>
          <div onClick={e => e.stopPropagation()} style={{ background: "#0c0c18", border: "1px solid #1e1e30", borderRadius: 12, padding: "32px", maxWidth: 600, width: "90%" }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 24 }}>
              <div>
                <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 20, fontWeight: 700, color: "#fff", marginBottom: 4 }}>Share Trade Card</p>
                <p style={{ fontSize: 12, color: "#888" }}>Create a shareable image for social media</p>
              </div>
              <button onClick={() => setShareCardTrade(null)} style={{ background: "none", border: "none", fontSize: 24, color: "#666", cursor: "pointer", padding: 0 }}>×</button>
            </div>

            {/* Card Preview */}
            <div id="trade-card-preview" style={{
              background: "linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%)",
              borderRadius: 16,
              padding: 40,
              marginBottom: 24,
              position: "relative",
              overflow: "hidden"
            }}>
              {/* Decorative background elements */}
              <div style={{ position: "absolute", top: -50, right: -50, width: 200, height: 200, background: "radial-gradient(circle, rgba(127,255,178,0.1), transparent)", borderRadius: "50%" }}></div>
              <div style={{ position: "absolute", bottom: -30, left: -30, width: 150, height: 150, background: "radial-gradient(circle, rgba(124,165,212,0.1), transparent)", borderRadius: "50%" }}></div>

              {/* Journal Name */}
              <div style={{ marginBottom: 32, position: "relative" }}>
                <p style={{
                  fontFamily: "'Courier New', Courier, monospace",
                  fontSize: 24,
                  fontWeight: 700,
                  letterSpacing: "1px",
                  margin: 0
                }}>
                  <span style={{ color: "#e45e54" }}>u</span>
                  <span style={{ color: "#f28b57" }}>l</span>
                  <span style={{ color: "#fabf53" }}>t</span>
                  <span style={{ color: "#8bc268" }}>r</span>
                  <span style={{ color: "#7ca5d4" }}>a</span>
                  <span style={{ color: "#a08ecc" }}>t</span>
                  <span style={{ color: "#c581b6" }}>r</span>
                  <span style={{ color: "#e45e54" }}>a</span>
                  <span style={{ color: "#f28b57" }}>c</span>
                  <span style={{ color: "#fabf53" }}>k</span>
                </p>
                <p style={{ fontSize: 10, color: "#888", marginTop: 4 }}>Trading Journal</p>
              </div>

              {/* Main Trade Info */}
              <div style={{ marginBottom: 24, position: "relative" }}>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 16 }}>
                  <div>
                    <p style={{ fontSize: 14, color: "#888", marginBottom: 4 }}>Symbol</p>
                    <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 48, fontWeight: 700, color: "#fff", margin: 0, lineHeight: 1 }}>{shareCardTrade.ticker}</p>
                  </div>
                  <div style={{ textAlign: "right" }}>
                    <p style={{ fontSize: 14, color: "#888", marginBottom: 4 }}>P&L</p>
                    <p style={{
                      fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace",
                      fontSize: 48,
                      fontWeight: 700,
                      color: shareCardTrade.pnl >= 0 ? "#7fffb2" : "#ff4466",
                      margin: 0,
                      lineHeight: 1
                    }}>{shareCardTrade.pnl >= 0 ? "+" : ""}${shareCardTrade.pnl.toLocaleString()}</p>
                  </div>
                </div>

                {/* Trade Details Row */}
                <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 16, marginTop: 24 }}>
                  <div style={{ background: "rgba(255,255,255,0.03)", padding: 16, borderRadius: 8, border: "1px solid rgba(255,255,255,0.05)" }}>
                    <p style={{ fontSize: 10, color: "#888", marginBottom: 6, textTransform: "uppercase", letterSpacing: 1 }}>Contracts</p>
                    <p style={{ fontSize: 20, fontWeight: 700, color: "#fff", margin: 0 }}>{shareCardTrade.size}</p>
                  </div>
                  <div style={{ background: "rgba(255,255,255,0.03)", padding: 16, borderRadius: 8, border: "1px solid rgba(255,255,255,0.05)" }}>
                    <p style={{ fontSize: 10, color: "#888", marginBottom: 6, textTransform: "uppercase", letterSpacing: 1 }}>Direction</p>
                    <p style={{ fontSize: 20, fontWeight: 700, color: shareCardTrade.direction === "Long" ? "#7fffb2" : "#ff4466", margin: 0 }}>{shareCardTrade.direction}</p>
                  </div>
                  <div style={{ background: "rgba(255,255,255,0.03)", padding: 16, borderRadius: 8, border: "1px solid rgba(255,255,255,0.05)" }}>
                    <p style={{ fontSize: 10, color: "#888", marginBottom: 6, textTransform: "uppercase", letterSpacing: 1 }}>Points</p>
                    <p style={{ fontSize: 20, fontWeight: 700, color: "#fff", margin: 0 }}>{Math.abs(shareCardTrade.exit - shareCardTrade.entry).toFixed(2)}</p>
                  </div>
                </div>
              </div>

              {/* Strategy & Date */}
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginTop: 24, position: "relative" }}>
                <div style={{ background: "rgba(127,255,178,0.1)", padding: "8px 14px", borderRadius: 6, border: "1px solid rgba(127,255,178,0.2)" }}>
                  <p style={{ fontSize: 11, color: "#7fffb2", fontWeight: 600, margin: 0 }}>{shareCardTrade.strategy}</p>
                </div>
                <p style={{ fontSize: 11, color: "#888", margin: 0 }}>{formatDateDisplay(shareCardTrade.date)}</p>
              </div>
            </div>

            {/* Action Buttons */}
            <div style={{ display: "flex", gap: 12 }}>
              <button
                className="gbtn"
                onClick={() => {
                  // Create canvas from the preview div
                  const card = document.getElementById('trade-card-preview');
                  html2canvas(card, {
                    backgroundColor: null,
                    scale: 2,
                    logging: false
                  }).then(canvas => {
                    canvas.toBlob(blob => {
                      const url = URL.createObjectURL(blob);
                      const a = document.createElement('a');
                      a.href = url;
                      a.download = `trade-${shareCardTrade.ticker}-${shareCardTrade.date}.png`;
                      a.click();
                      URL.revokeObjectURL(url);
                    });
                  });
                }}
                style={{ flex: 1 }}
              >
                💾 Download Image
              </button>
              <button
                className="gbtn"
                onClick={async () => {
                  const card = document.getElementById('trade-card-preview');
                  const canvas = await html2canvas(card, {
                    backgroundColor: null,
                    scale: 2,
                    logging: false
                  });
                  canvas.toBlob(async blob => {
                    try {
                      await navigator.clipboard.write([
                        new ClipboardItem({ 'image/png': blob })
                      ]);
                      alert('Trade card copied to clipboard! Ready to paste in social media.');
                    } catch (err) {
                      alert('Could not copy to clipboard. Please use Download instead.');
                    }
                  });
                }}
                style={{ flex: 1 }}
              >
                📋 Copy to Clipboard
              </button>
            </div>

            <p style={{ fontSize: 10, color: "#666", marginTop: 16, textAlign: "center", fontStyle: "italic" }}>
              Tip: Download or copy the image to share on Twitter, Instagram, or Discord
            </p>
          </div>
        </div>
      )}

      {/* SHARE P&L SUMMARY CARD MODAL */}
      {sharePnLCard && (() => {
        // Calculate stats based on timeframe
        const now = new Date();
        const today = getTodayLocalDate(); // Use the same local date function

        const getTimeframeTrades = () => {
          if (sharePnLCard === "daily") {
            return trades.filter(t => {
              const tradeDate = t.date.split('T')[0]; // Get YYYY-MM-DD part
              return tradeDate === today;
            });
          } else if (sharePnLCard === "weekly") {
            const weekStart = new Date(now);
            weekStart.setDate(now.getDate() - now.getDay() + 1); // Monday
            weekStart.setHours(0, 0, 0, 0); // Start of day
            return trades.filter(t => {
              const tradeDate = new Date(t.date + 'T00:00:00'); // Parse as local date
              return tradeDate >= weekStart;
            });
          } else if (sharePnLCard === "monthly") {
            const monthStart = new Date(now.getFullYear(), now.getMonth(), 1);
            monthStart.setHours(0, 0, 0, 0);
            return trades.filter(t => {
              const tradeDate = new Date(t.date + 'T00:00:00'); // Parse as local date
              return tradeDate >= monthStart;
            });
          }
          return [];
        };

        const tfTrades = getTimeframeTrades();
        const tfPnL = tfTrades.reduce((sum, t) => sum + t.pnl, 0);
        const tfWinners = tfTrades.filter(t => t.pnl > 0);
        const tfWinRate = tfTrades.length ? Math.round((tfWinners.length / tfTrades.length) * 100) : 0;
        const tfBestTrade = tfTrades.length ? Math.max(...tfTrades.map(t => t.pnl)) : 0;
        const tfWorstTrade = tfTrades.length ? Math.min(...tfTrades.map(t => t.pnl)) : 0;

        const timeframeLabels = {
          daily: "Today's Performance",
          weekly: "This Week's Performance",
          monthly: "This Month's Performance"
        };

        const dateRanges = {
          daily: now.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" }),
          weekly: (() => {
            const weekStart = new Date(now);
            weekStart.setDate(now.getDate() - now.getDay() + 1);
            const weekEnd = new Date(weekStart);
            weekEnd.setDate(weekStart.getDate() + 6);
            return `${weekStart.toLocaleDateString("en-US", { month: "short", day: "numeric" })} - ${weekEnd.toLocaleDateString("en-US", { month: "short", day: "numeric" })}`;
          })(),
          monthly: now.toLocaleDateString("en-US", { month: "long", year: "numeric" })
        };

        return (
          <div onClick={() => setSharePnLCard(null)} style={{ position: "fixed", top: 0, left: 0, right: 0, bottom: 0, background: "rgba(0,0,0,0.9)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 1000, backdropFilter: "blur(10px)" }}>
            <div onClick={e => e.stopPropagation()} style={{ background: "#0c0c18", border: "1px solid #1e1e30", borderRadius: 12, padding: "32px", maxWidth: 600, width: "90%" }}>
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 24 }}>
                <div>
                  <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 20, fontWeight: 700, color: "#fff", marginBottom: 4 }}>Share P&L Summary</p>
                  <p style={{ fontSize: 12, color: "#888" }}>{timeframeLabels[sharePnLCard]}</p>
                </div>
                <button onClick={() => setSharePnLCard(null)} style={{ background: "none", border: "none", fontSize: 24, color: "#666", cursor: "pointer", padding: 0 }}>×</button>
              </div>

              {/* Card Preview */}
              <div id="pnl-card-preview" style={{
                background: "linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%)",
                borderRadius: 16,
                padding: 40,
                marginBottom: 24,
                position: "relative",
                overflow: "hidden"
              }}>
                {/* Decorative background elements */}
                <div style={{ position: "absolute", top: -50, right: -50, width: 200, height: 200, background: "radial-gradient(circle, rgba(127,255,178,0.1), transparent)", borderRadius: "50%" }}></div>
                <div style={{ position: "absolute", bottom: -30, left: -30, width: 150, height: 150, background: "radial-gradient(circle, rgba(124,165,212,0.1), transparent)", borderRadius: "50%" }}></div>

                {/* Journal Name */}
                <div style={{ marginBottom: 32, position: "relative" }}>
                  <p style={{
                    fontFamily: "'Courier New', Courier, monospace",
                    fontSize: 24,
                    fontWeight: 700,
                    letterSpacing: "1px",
                    margin: 0
                  }}>
                    <span style={{ color: "#e45e54" }}>u</span>
                    <span style={{ color: "#f28b57" }}>l</span>
                    <span style={{ color: "#fabf53" }}>t</span>
                    <span style={{ color: "#8bc268" }}>r</span>
                    <span style={{ color: "#7ca5d4" }}>a</span>
                    <span style={{ color: "#a08ecc" }}>t</span>
                    <span style={{ color: "#c581b6" }}>r</span>
                    <span style={{ color: "#e45e54" }}>a</span>
                    <span style={{ color: "#f28b57" }}>c</span>
                    <span style={{ color: "#fabf53" }}>k</span>
                  </p>
                  <p style={{ fontSize: 10, color: "#888", marginTop: 4 }}>Trading Journal</p>
                </div>

                {/* Timeframe Header */}
                <div style={{ marginBottom: 24, position: "relative" }}>
                  <p style={{ fontSize: 12, color: "#888", marginBottom: 4, textTransform: "uppercase", letterSpacing: 1 }}>{sharePnLCard} Performance</p>
                  <p style={{ fontSize: 16, color: "#aaa", margin: 0 }}>{dateRanges[sharePnLCard]}</p>
                </div>

                {/* Main P&L */}
                <div style={{ marginBottom: 32, position: "relative", textAlign: "center" }}>
                  <p style={{ fontSize: 14, color: "#888", marginBottom: 8 }}>Net P&L</p>
                  <p style={{
                    fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace",
                    fontSize: 64,
                    fontWeight: 700,
                    color: tfPnL >= 0 ? "#7fffb2" : "#ff4466",
                    margin: 0,
                    lineHeight: 1
                  }}>{tfPnL >= 0 ? "+" : ""}${tfPnL.toLocaleString()}</p>
                </div>

                {/* Stats Grid */}
                <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16, marginBottom: 24 }}>
                  <div style={{ background: "rgba(255,255,255,0.03)", padding: 16, borderRadius: 8, border: "1px solid rgba(255,255,255,0.05)" }}>
                    <p style={{ fontSize: 10, color: "#888", marginBottom: 6, textTransform: "uppercase", letterSpacing: 1 }}>Trades</p>
                    <p style={{ fontSize: 24, fontWeight: 700, color: "#fff", margin: 0 }}>{tfTrades.length}</p>
                  </div>
                  <div style={{ background: "rgba(255,255,255,0.03)", padding: 16, borderRadius: 8, border: "1px solid rgba(255,255,255,0.05)" }}>
                    <p style={{ fontSize: 10, color: "#888", marginBottom: 6, textTransform: "uppercase", letterSpacing: 1 }}>Win Rate</p>
                    <p style={{ fontSize: 24, fontWeight: 700, color: tfWinRate >= 50 ? "#7fffb2" : "#ff4466", margin: 0 }}>{tfWinRate}%</p>
                  </div>
                  <div style={{ background: "rgba(255,255,255,0.03)", padding: 16, borderRadius: 8, border: "1px solid rgba(255,255,255,0.05)" }}>
                    <p style={{ fontSize: 10, color: "#888", marginBottom: 6, textTransform: "uppercase", letterSpacing: 1 }}>Best Trade</p>
                    <p style={{ fontSize: 20, fontWeight: 700, color: "#7fffb2", margin: 0 }}>+${tfBestTrade.toLocaleString()}</p>
                  </div>
                  <div style={{ background: "rgba(255,255,255,0.03)", padding: 16, borderRadius: 8, border: "1px solid rgba(255,255,255,0.05)" }}>
                    <p style={{ fontSize: 10, color: "#888", marginBottom: 6, textTransform: "uppercase", letterSpacing: 1 }}>Worst Trade</p>
                    <p style={{ fontSize: 20, fontWeight: 700, color: "#ff4466", margin: 0 }}>${tfWorstTrade.toLocaleString()}</p>
                  </div>
                </div>

                {/* Consistency Badge */}
                <div style={{ textAlign: "center", position: "relative", minHeight: 40 }}>
                  {tfWinRate >= 60 && tfPnL > 0 && (
                    <div style={{ display: "inline-block", background: "rgba(127,255,178,0.1)", padding: "8px 16px", borderRadius: 6, border: "1px solid rgba(127,255,178,0.3)" }}>
                      <p style={{ fontSize: 12, color: "#7fffb2", fontWeight: 600, margin: 0 }}>🔥 Consistent Performance</p>
                    </div>
                  )}
                </div>
              </div>

              {/* Action Buttons */}
              <div style={{ display: "flex", gap: 12 }}>
                <button
                  className="gbtn"
                  onClick={() => {
                    const card = document.getElementById('pnl-card-preview');
                    html2canvas(card, {
                      backgroundColor: null,
                      scale: 2,
                      logging: false,
                      useCORS: true,
                      allowTaint: true
                    }).then(canvas => {
                      canvas.toBlob(blob => {
                        const url = URL.createObjectURL(blob);
                        const a = document.createElement('a');
                        a.href = url;
                        a.download = `pnl-${sharePnLCard}-${now.toISOString().split('T')[0]}.png`;
                        a.click();
                        URL.revokeObjectURL(url);
                      });
                    });
                  }}
                  style={{ flex: 1 }}
                >
                  💾 Download Image
                </button>
                <button
                  className="gbtn"
                  onClick={async () => {
                    const card = document.getElementById('pnl-card-preview');
                    const canvas = await html2canvas(card, {
                      backgroundColor: null,
                      scale: 2,
                      logging: false,
                      useCORS: true,
                      allowTaint: true
                    });
                    canvas.toBlob(async blob => {
                      try {
                        await navigator.clipboard.write([
                          new ClipboardItem({ 'image/png': blob })
                        ]);
                        alert('P&L card copied to clipboard! Ready to paste in social media.');
                      } catch (err) {
                        alert('Could not copy to clipboard. Please use Download instead.');
                      }
                    });
                  }}
                  style={{ flex: 1 }}
                >
                  📋 Copy to Clipboard
                </button>
              </div>

              <p style={{ fontSize: 10, color: "#666", marginTop: 16, textAlign: "center", fontStyle: "italic" }}>
                Share your {sharePnLCard} performance on social media
              </p>
            </div>
          </div>
        );
      })()}

      {/* DELETE CONFIRMATION */}
      {deleteConfirm && (
        <div onClick={() => setDeleteConfirm(null)} style={{ position: "fixed", top: 0, left: 0, right: 0, bottom: 0, background: "rgba(0,0,0,0.85)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 1000 }}>
          <div onClick={e => e.stopPropagation()} style={{ background: "#0c0c18", border: "1px solid #1e1e30", borderRadius: 8, padding: "28px 32px", maxWidth: 420, width: "90%" }}>
            <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 18, fontWeight: 700, color: "#fff", marginBottom: 12 }}>Delete Trade?</p>
            <p style={{ fontSize: 12, color: "#ddd", marginBottom: 24, lineHeight: 1.6 }}>This action cannot be undone. The trade will be permanently removed from your journal.</p>
            <div style={{ display: "flex", gap: 10 }}>
              <button className="ghost" onClick={() => setDeleteConfirm(null)} style={{ flex: 1 }}>Cancel</button>
              <button onClick={() => deleteTrade(deleteConfirm)} style={{ flex: 1, background: "#ff4466", border: "none", color: "#fff", padding: "10px 20px", borderRadius: 6, cursor: "pointer", fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 11, letterSpacing: ".08em", fontWeight: 500 }}>Delete</button>
            </div>
          </div>
        </div>
      )}

      {/* CALENDAR DATE MODAL */}
      {selectedCalendarDate && (
        <div onClick={() => setSelectedCalendarDate(null)} style={{ position: "fixed", top: 0, left: 0, right: 0, bottom: 0, background: "rgba(0,0,0,0.85)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 1000 }}>
          <div onClick={e => e.stopPropagation()} style={{ background: "#0c0c18", border: "1px solid #1e1e30", borderRadius: 8, padding: "28px 32px", maxWidth: 900, width: "90%", maxHeight: "85vh", overflowY: "auto" }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 20 }}>
              <div>
                <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 20, fontWeight: 700, color: "#fff", margin: 0, marginBottom: 6 }}>
                  {formatDateDisplay(selectedCalendarDate.date)}
                </p>
                <p style={{ fontSize: 12, color: "#ffffff" }}>
                  {selectedCalendarDate.stats.count} trade{selectedCalendarDate.stats.count !== 1 ? 's' : ''} •
                  <span className={selectedCalendarDate.stats.pnl >= 0 ? "pos" : "neg"} style={{ marginLeft: 6 }}>
                    {selectedCalendarDate.stats.pnl >= 0 ? "+" : ""}${selectedCalendarDate.stats.pnl.toLocaleString()}
                  </span> •
                  <span style={{ marginLeft: 6, color: selectedCalendarDate.stats.winRate >= 50 ? "#7fffb2" : "#ff4466" }}>
                    {selectedCalendarDate.stats.winRate}% win rate
                  </span>
                </p>
              </div>
              <button onClick={() => setSelectedCalendarDate(null)} style={{ background: "none", border: "none", color: "#aaa", cursor: "pointer", fontSize: 24 }}>×</button>
            </div>

            {/* Trades List */}
            <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
              {selectedCalendarDate.trades.map(t => (
                <div key={t.id} style={{ background: "#09090f", border: "1px solid #181828", borderRadius: 6, padding: 16 }}>
                  <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 12 }}>
                    <div>
                      <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 8 }}>
                        <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 16, fontWeight: 700, color: "#fff", margin: 0 }}>
                          {t.ticker}
                          {t.source === "csv" && <span className="tv-badge">CSV</span>}
                        </p>
                        <span className="tag" style={{ background: t.direction === "Long" ? "rgba(127,255,178,.1)" : "rgba(255,68,102,.1)", color: t.direction === "Long" ? "#7fffb2" : "#ff4466" }}>
                          {t.direction}
                        </span>
                        <span className="tag" style={{ background: "#111120", color: "#ffffff" }}>{t.strategy}</span>
                        <span className="tag" style={{ color: emotionColors[t.emotion] || "#888", background: `${emotionColors[t.emotion] || "#888"}12` }}>
                          {t.emotion}
                        </span>
                      </div>
                      <div style={{ display: "flex", gap: 16, fontSize: 11, color: "#ffffff" }}>
                        <span>Entry: <span style={{ color: "#ddd" }}>{t.entry}</span></span>
                        <span>Exit: <span style={{ color: "#ddd" }}>{t.exit}</span></span>
                        <span>Size: <span style={{ color: "#ddd" }}>{t.size}</span></span>
                        <span>Session: <span style={{ color: "#ddd" }}>{t.session}</span></span>
                        {t.entryTime && <span>Entry Time: <span style={{ color: "#ddd" }}>{t.entryTime}</span></span>}
                        {t.exitTime && <span>Exit Time: <span style={{ color: "#ddd" }}>{t.exitTime}</span></span>}
                      </div>
                    </div>
                    <div style={{ textAlign: "right" }}>
                      <p style={{ fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace", fontSize: 20, fontWeight: 700, margin: 0, marginBottom: 4 }} className={t.pnl >= 0 ? "pos" : "neg"}>
                        {t.pnl >= 0 ? "+" : ""}${t.pnl.toLocaleString()}
                      </p>
                      <div style={{ display: "flex", gap: 8, justifyContent: "flex-end" }}>
                        <button className="ghost" onClick={() => { openEditNotes(t); setSelectedCalendarDate(null); }} style={{ padding: "4px 10px", fontSize: 9 }}>
                          📝 {t.notesData?.text || t.notesData?.images?.length ? "Edit" : "Add"} Notes
                        </button>
                        <button className="ghost" onClick={() => { openEditTime(t); setSelectedCalendarDate(null); }} style={{ padding: "4px 10px", fontSize: 9 }}>
                          🕐 Edit Time
                        </button>
                      </div>
                    </div>
                  </div>

                  {/* Show notes if they exist */}
                  {(t.notesData?.text || t.notesData?.images?.length > 0) && (
                    <div style={{ marginTop: 12, paddingTop: 12, borderTop: "1px solid #181828" }}>
                      {t.notesData?.text && (
                        <p style={{ fontSize: 11, color: "#ffffff", marginBottom: 8, whiteSpace: "pre-wrap", lineHeight: 1.6 }}>
                          {t.notesData.text}
                        </p>
                      )}
                      {t.notesData?.images?.length > 0 && (
                        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(100px, 1fr))", gap: 8 }}>
                          {t.notesData.images.map(img => (
                            <img key={img.id} src={img.dataUrl} alt={img.name} style={{ width: "100%", height: 80, objectFit: "cover", borderRadius: 4, border: "1px solid #222235", cursor: "pointer" }} onClick={() => setPreviewImage(img)} />
                          ))}
                        </div>
                      )}
                    </div>
                  )}
                </div>
              ))}
            </div>

            <div style={{ marginTop: 20 }}>
              <button className="ghost" onClick={() => setSelectedCalendarDate(null)} style={{ width: "100%" }}>Close</button>
            </div>
          </div>
        </div>
      )}

      {/* IMAGE PREVIEW MODAL */}
      {previewImage && (
        <div
          onClick={() => setPreviewImage(null)}
          style={{
            position: "fixed",
            top: 0,
            left: 0,
            right: 0,
            bottom: 0,
            background: "rgba(0, 0, 0, 0.95)",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            zIndex: 2000,
            padding: 40
          }}
        >
          <div
            onClick={(e) => e.stopPropagation()}
            style={{
              position: "relative",
              maxWidth: "90vw",
              maxHeight: "90vh",
              display: "flex",
              flexDirection: "column",
              alignItems: "center"
            }}
          >
            <button
              onClick={() => setPreviewImage(null)}
              style={{
                position: "absolute",
                top: -40,
                right: 0,
                background: "rgba(255, 255, 255, 0.1)",
                border: "1px solid rgba(255, 255, 255, 0.2)",
                color: "#fff",
                width: 36,
                height: 36,
                borderRadius: "50%",
                cursor: "pointer",
                fontSize: 20,
                display: "flex",
                alignItems: "center",
                justifyContent: "center",
                padding: 0,
                transition: "all 0.2s"
              }}
              onMouseEnter={(e) => {
                e.currentTarget.style.background = "rgba(255, 255, 255, 0.2)";
              }}
              onMouseLeave={(e) => {
                e.currentTarget.style.background = "rgba(255, 255, 255, 0.1)";
              }}
              title="Close preview"
            >
              ×
            </button>
            <img
              src={previewImage.dataUrl}
              alt={previewImage.name}
              style={{
                maxWidth: "100%",
                maxHeight: "90vh",
                objectFit: "contain",
                borderRadius: 8,
                boxShadow: "0 8px 32px rgba(0, 0, 0, 0.5)"
              }}
            />
            <p style={{
              marginTop: 16,
              color: "#ffffff",
              fontSize: 12,
              fontFamily: "-apple-system, BlinkMacSystemFont, 'SF Mono', 'Monaco', 'Menlo', 'Consolas', 'Roboto Mono', monospace"
            }}>
              {previewImage.name}
            </p>
          </div>
        </div>
      )}

      {/* Video Recorder - Always visible floating button (hidden when Lyra chat panel is open) */}
      {!chatPanelOpen && (
        <VideoRecorder
          user={user}
          onRecordingSaved={(recording) => {
            console.log('Recording saved:', recording);
            // Refresh recordings list
            setRecordings(prev => [recording, ...prev]);
          }}
        />
      )}
    </div>
  );
}
