// ImportExport.jsx — CSV/XLSX import and CSV/JSON export

// ── EXPORT ────────────────────────────────────────────────────────────────────

const exportToCSV = (trades, filename = 'trades') => {
  const headers = ['id','date','symbol','type','direction','status','pnl','rMultiple',
    'entryPrice','quantity','stopLoss','strategy','optionType','strike','expiry','contracts','premium',
    'exits','signals','customSignal','labels','customLabel','notes'];

  const escape = (v) => {
    if (v == null) return '';
    const s = typeof v === 'object' ? JSON.stringify(v) : String(v);
    return s.includes(',') || s.includes('"') || s.includes('\n') ? `"${s.replace(/"/g,'""')}"` : s;
  };

  const rows = [headers.join(',')];
  trades.forEach(t => {
    rows.push(headers.map(h => {
      const v = t[h];
      if (h === 'exits' || h === 'signals' || h === 'labels') return escape(v || []);
      return escape(v);
    }).join(','));
  });

  const blob = new Blob([rows.join('\n')], { type: 'text/csv;charset=utf-8;' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url; a.download = `${filename}_${new Date().toISOString().slice(0,10)}.csv`;
  a.click(); URL.revokeObjectURL(url);
};

const exportToJSON = (trades, filename = 'trades') => {
  const blob = new Blob([JSON.stringify(trades, null, 2)], { type: 'application/json' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url; a.download = `${filename}_${new Date().toISOString().slice(0,10)}.json`;
  a.click(); URL.revokeObjectURL(url);
};

// ── BROKER DETECTION ──────────────────────────────────────────────────────────

const detectBroker = (headers) => {
  const h = headers.map(x => x.toLowerCase().trim());
  if (h.includes('exec time') || h.includes('pos effect')) return 'thinkorswim';
  if (h.includes('fees & comm') || h.includes('security type')) return 'schwab';
  if (h.includes('run-up') || h.includes('trade #')) return 'tradingview';
  if (h.includes('rmultiple') || h.includes('r multiple')) return 'native';
  return 'generic';
};

// ── BROKER PARSERS ────────────────────────────────────────────────────────────

const parseThinkorSwim = (rows, headers) => {
  // TOS Account Activity: Symbol, Qty, Price, Exec Time, Spread, Side, Pos Effect, Account
  const col = (h) => headers.findIndex(x => x.toLowerCase().includes(h.toLowerCase()));
  const idxSymbol = col('symbol'); const idxQty = col('qty'); const idxPrice = col('price');
  const idxTime = col('exec time'); const idxSide = col('side'); const idxPos = col('pos effect');

  const trades = [];
  rows.forEach((row, i) => {
    const symbol = row[idxSymbol]?.replace(/['"]/g,'').trim();
    const side   = row[idxSide]?.toLowerCase().trim();
    const pos    = row[idxPos]?.toLowerCase().trim();
    const price  = parseFloat(row[idxPrice]);
    const qty    = Math.abs(parseInt(row[idxQty]));
    const rawDate = row[idxTime]?.trim();
    if (!symbol || !side || isNaN(price)) return;
    const isEntry = pos === 'to open' || pos === 'open';
    const direction = side === 'buy' ? 'long' : 'short';
    const date = rawDate ? rawDate.slice(0,10).replace(/\//g,'-') : new Date().toISOString().slice(0,10);
    trades.push({
      id: genId(), date, symbol: symbol.toUpperCase(), type: 'stock', direction,
      quantity: qty, entryPrice: isEntry ? price : undefined,
      exits: isEntry ? [] : [{ id: genId(), price, quantity: qty, date }],
      signals: [], labels: [], customSignal: '', customLabel: '', notes: '',
      status: isEntry ? 'open' : 'closed', pnl: null, rMultiple: null, snapshot: null,
    });
  });
  return trades;
};

const parseSchwab = (rows, headers) => {
  const col = (h) => headers.findIndex(x => x.toLowerCase().includes(h.toLowerCase()));
  const idxDate = col('date'); const idxAction = col('action'); const idxSymbol = col('symbol');
  const idxQty = col('quantity'); const idxPrice = col('price'); const idxAmt = col('amount');

  return rows.filter(r => {
    const action = r[col('action')]?.toLowerCase() || '';
    return action.includes('buy') || action.includes('sell');
  }).map(row => {
    const action = row[idxAction]?.toLowerCase() || '';
    const symbol = row[idxSymbol]?.replace(/['"]/g,'').trim() || '';
    const price  = parseFloat(row[idxPrice]?.replace(/[$,]/g,''));
    const qty    = Math.abs(parseFloat(row[idxQty]?.replace(/,/g,'')));
    const rawDate = row[idxDate]?.trim() || '';
    const date = rawDate.slice(0,10).replace(/\//g,'-') || new Date().toISOString().slice(0,10);
    const direction = action.includes('buy') ? 'long' : 'short';
    const amt = parseFloat(row[idxAmt]?.replace(/[$,\-]/g,'') || '0');
    return {
      id: genId(), date, symbol: symbol.toUpperCase(), type: 'stock', direction,
      quantity: qty, entryPrice: price, stopLoss: null,
      exits: [], signals: [], labels: [], customSignal: '', customLabel: '',
      notes: '', status: 'open', pnl: null, rMultiple: null, snapshot: null,
    };
  });
};

const parseTradingView = (rows, headers) => {
  const col = (h) => headers.findIndex(x => x.toLowerCase().includes(h.toLowerCase()));
  const idxType = col('type'); const idxDate = col('date'); const idxPrice = col('price');
  const idxQty = col('contracts'); const idxProfit = col('profit');

  return rows.map(row => {
    const type  = row[idxType]?.toLowerCase() || '';
    const rawDate = row[idxDate]?.trim() || new Date().toISOString().slice(0,10);
    const date = rawDate.slice(0,10);
    const price = parseFloat(row[idxPrice]) || 0;
    const qty   = parseInt(row[idxQty]) || 1;
    const pnl   = parseFloat(row[idxProfit]?.replace(/,/g,'')) || null;
    const direction = type.includes('short') ? 'short' : 'long';
    return {
      id: genId(), date, symbol: 'UNKNOWN', type: 'stock', direction,
      quantity: qty, entryPrice: price, stopLoss: null,
      exits: pnl != null ? [{ id: genId(), price: price + (pnl / qty), quantity: qty, date }] : [],
      signals: [], labels: [], customSignal: '', customLabel: '',
      notes: `Imported from TradingView`, status: pnl != null ? 'closed' : 'open',
      pnl, rMultiple: null, snapshot: null,
    };
  });
};

const parseNative = (rows, headers) => {
  const col = (h) => headers.findIndex(x => x.toLowerCase().replace(/\s/g,'') === h.toLowerCase().replace(/\s/g,''));
  return rows.map(row => {
    const get = (h) => row[col(h)];
    const tryParse = (v) => { try { return JSON.parse(v); } catch { return []; } };
    return {
      id: get('id') || genId(),
      date: get('date') || '',
      symbol: (get('symbol') || '').toUpperCase(),
      type: get('type') || 'stock',
      direction: get('direction') || 'long',
      status: get('status') || 'closed',
      pnl: parseFloat(get('pnl')) || null,
      rMultiple: parseFloat(get('rMultiple') || get('r multiple')) || null,
      entryPrice: parseFloat(get('entryPrice') || get('entry price')) || undefined,
      quantity: parseInt(get('quantity')) || undefined,
      stopLoss: parseFloat(get('stopLoss') || get('stop loss')) || null,
      strategy: get('strategy') || 'single',
      optionType: get('optionType') || get('option type'),
      strike: parseFloat(get('strike')) || undefined,
      expiry: get('expiry') || '',
      contracts: parseInt(get('contracts')) || undefined,
      premium: parseFloat(get('premium')) || undefined,
      exits: tryParse(get('exits')),
      signals: tryParse(get('signals')),
      labels: tryParse(get('labels')),
      customSignal: get('customSignal') || '',
      customLabel: get('customLabel') || '',
      notes: get('notes') || '',
      snapshot: null,
    };
  });
};

const parseGenericCSV = (rows, headers, mapping) => {
  return rows.map(row => {
    const get = (field) => {
      const colIdx = mapping[field];
      if (colIdx == null || colIdx === -1) return undefined;
      return row[colIdx];
    };
    const pnl = parseFloat(get('pnl')) || null;
    return {
      id: genId(),
      date: get('date') || new Date().toISOString().slice(0,10),
      symbol: (get('symbol') || 'UNKNOWN').toUpperCase(),
      type: get('type') || 'stock',
      direction: get('direction') || 'long',
      quantity: parseInt(get('quantity')) || undefined,
      entryPrice: parseFloat(get('entryPrice')) || undefined,
      stopLoss: parseFloat(get('stopLoss')) || null,
      exits: [], signals: [], labels: [], customSignal: '', customLabel: '',
      notes: get('notes') || '',
      status: pnl != null ? 'closed' : 'open',
      pnl, rMultiple: parseFloat(get('rMultiple')) || null, snapshot: null,
    };
  });
};

// ── CSV PARSER ────────────────────────────────────────────────────────────────

const parseCSVText = (text) => {
  const lines = text.trim().split('\n');
  const parseRow = (line) => {
    const cells = []; let cur = ''; let inQuotes = false;
    for (let i = 0; i < line.length; i++) {
      const ch = line[i];
      if (ch === '"' && line[i+1] === '"') { cur += '"'; i++; }
      else if (ch === '"') { inQuotes = !inQuotes; }
      else if (ch === ',' && !inQuotes) { cells.push(cur.trim()); cur = ''; }
      else cur += ch;
    }
    cells.push(cur.trim());
    return cells;
  };
  const headers = parseRow(lines[0]);
  const rows = lines.slice(1).filter(l => l.trim()).map(parseRow);
  return { headers, rows };
};

// ── IMPORT MODAL ──────────────────────────────────────────────────────────────

const OUR_FIELDS = [
  { id: 'symbol', label: 'Symbol' },
  { id: 'date', label: 'Date' },
  { id: 'direction', label: 'Direction (long/short)' },
  { id: 'type', label: 'Type (stock/option)' },
  { id: 'entryPrice', label: 'Entry Price' },
  { id: 'quantity', label: 'Quantity / Shares' },
  { id: 'stopLoss', label: 'Stop Loss' },
  { id: 'pnl', label: 'P&L ($)' },
  { id: 'rMultiple', label: 'R Multiple' },
  { id: 'notes', label: 'Notes' },
];

const ImportModal = ({ onImport, onClose }) => {
  const { useState, useRef, useCallback } = React;
  const [step, setStep] = useState('drop'); // drop | mapping | preview
  const [csvData, setCsvData] = useState(null); // { headers, rows }
  const [broker, setBroker] = useState('generic');
  const [mapping, setMapping] = useState({});
  const [preview, setPreview] = useState([]);
  const [dragging, setDragging] = useState(false);
  const [error, setError] = useState('');
  const fileRef = useRef();

  const BROKER_LABELS = {
    thinkorswim: 'ThinkorSwim',
    schwab: 'Charles Schwab',
    tradingview: 'TradingView',
    native: 'TradeJournal Export',
    generic: 'Generic CSV'
  };

  const processFile = async (file) => {
    setError('');
    try {
      let text;
      if (file.name.match(/\.(xlsx|xls)$/i)) {
        // Load SheetJS dynamically
        if (!window.XLSX) {
          await new Promise((res, rej) => {
            const s = document.createElement('script');
            s.src = 'https://cdn.sheetjs.com/xlsx-0.20.3/package/dist/xlsx.full.min.js';
            s.onload = res; s.onerror = rej;
            document.head.appendChild(s);
          });
        }
        const ab = await file.arrayBuffer();
        const wb = window.XLSX.read(ab, { type: 'array' });
        const ws = wb.Sheets[wb.SheetNames[0]];
        text = window.XLSX.utils.sheet_to_csv(ws);
      } else {
        text = await file.text();
      }
      const { headers, rows } = parseCSVText(text);
      if (!headers.length) { setError('Could not parse file — check format'); return; }
      const detected = detectBroker(headers);
      setBroker(detected);
      setCsvData({ headers, rows });

      if (detected === 'generic') {
        // Init mapping: try to auto-match column names
        const autoMap = {};
        OUR_FIELDS.forEach(f => {
          const idx = headers.findIndex(h => h.toLowerCase().includes(f.id.toLowerCase()) || h.toLowerCase().includes(f.label.toLowerCase().split(' ')[0]));
          autoMap[f.id] = idx >= 0 ? idx : -1;
        });
        setMapping(autoMap);
        setStep('mapping');
      } else {
        // Auto-parse and go to preview
        const parsed = runParser(detected, rows, headers, {});
        setPreview(parsed);
        setStep('preview');
      }
    } catch (e) {
      setError('Failed to parse file: ' + e.message);
    }
  };

  const runParser = (b, rows, headers, map) => {
    if (b === 'thinkorswim') return parseThinkorSwim(rows, headers);
    if (b === 'schwab')      return parseSchwab(rows, headers);
    if (b === 'tradingview') return parseTradingView(rows, headers);
    if (b === 'native')      return parseNative(rows, headers);
    return parseGenericCSV(rows, headers, map);
  };

  const handleDrop = useCallback((e) => {
    e.preventDefault(); setDragging(false);
    const file = e.dataTransfer.files[0];
    if (file) processFile(file);
  }, []);

  const handleApplyMapping = () => {
    const parsed = runParser('generic', csvData.rows, csvData.headers, mapping);
    setPreview(parsed);
    setStep('preview');
  };

  const handleImport = () => {
    onImport(preview);
    onClose();
  };

  const overlay = { position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.75)', zIndex: 2000, display: 'flex', alignItems: 'center', justifyContent: 'center' };
  const modal = { background: '#0d1018', border: '1px solid #1e2440', borderRadius: '14px', width: '600px', maxWidth: '95vw', maxHeight: '85vh', display: 'flex', flexDirection: 'column', boxShadow: '0 24px 64px rgba(0,0,0,0.7)' };
  const labelS = { fontSize: '11px', color: '#55647d', fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.07em' };
  const selS = { background: '#0a0d14', border: '1px solid #1e2440', borderRadius: '6px', color: '#d8dde8', padding: '6px 10px', fontSize: '12px', fontFamily: 'Space Grotesk, sans-serif', width: '100%', outline: 'none' };

  return React.createElement('div', { style: overlay, onClick: onClose }, [
    React.createElement('div', { key: 'modal', style: modal, onClick: e => e.stopPropagation() }, [

      // Header
      React.createElement('div', { key: 'hdr', style: { padding: '20px 24px', borderBottom: '1px solid #1e2440', display: 'flex', justifyContent: 'space-between', alignItems: 'center' } }, [
        React.createElement('div', { key: 'l' }, [
          React.createElement('div', { key: 't', style: { fontSize: '16px', fontWeight: 700, color: '#d8dde8' } }, 'Import Trades'),
          React.createElement('div', { key: 's', style: { fontSize: '12px', color: '#55647d', marginTop: '2px' } }, 'CSV or Excel · ThinkorSwim · Charles Schwab · TradingView')
        ]),
        React.createElement('button', { key: 'x', onClick: onClose, style: { background: 'none', border: 'none', color: '#55647d', fontSize: '22px', cursor: 'pointer', lineHeight: 1 } }, '×')
      ]),

      // Step: Drop
      step === 'drop' && React.createElement('div', { key: 'drop', style: { padding: '32px', flex: 1, display: 'flex', flexDirection: 'column', gap: '16px', alignItems: 'center', justifyContent: 'center' } }, [
        React.createElement('div', {
          key: 'zone',
          onDrop: handleDrop, onDragOver: e => { e.preventDefault(); setDragging(true); }, onDragLeave: () => setDragging(false),
          onClick: () => fileRef.current?.click(),
          style: { border: `2px dashed ${dragging ? '#5588ff' : '#1e2440'}`, borderRadius: '12px', padding: '40px 24px', textAlign: 'center', cursor: 'pointer', transition: 'all 0.15s', background: dragging ? 'rgba(85,136,255,0.05)' : 'transparent', width: '100%' }
        }, [
          React.createElement('div', { key: 'icon', style: { fontSize: '36px', marginBottom: '12px', opacity: 0.5 } }, '📥'),
          React.createElement('div', { key: 'txt', style: { fontSize: '14px', color: '#8a9bb5', marginBottom: '6px' } }, 'Drop your file here or click to browse'),
          React.createElement('div', { key: 'sub', style: { fontSize: '12px', color: '#55647d' } }, '.csv · .xlsx · .xls')
        ]),
        React.createElement('input', { key: 'file', ref: fileRef, type: 'file', accept: '.csv,.xlsx,.xls', style: { display: 'none' }, onChange: e => e.target.files[0] && processFile(e.target.files[0]) }),
        error && React.createElement('div', { key: 'err', style: { color: '#f04060', fontSize: '13px' } }, error),

        // Supported formats
        React.createElement('div', { key: 'formats', style: { display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: '8px', width: '100%', marginTop: '8px' } },
          ['ThinkorSwim', 'Charles Schwab', 'TradingView', 'Generic CSV'].map(f =>
            React.createElement('div', { key: f, style: { background: '#0a0d14', border: '1px solid #1e2440', borderRadius: '8px', padding: '10px', textAlign: 'center' } }, [
              React.createElement('div', { key: 'n', style: { fontSize: '12px', fontWeight: 500, color: '#8a9bb5' } }, f)
            ])
          )
        )
      ]),

      // Step: Column Mapping (generic CSV)
      step === 'mapping' && React.createElement('div', { key: 'mapping', style: { padding: '24px', flex: 1, overflowY: 'auto', display: 'flex', flexDirection: 'column', gap: '12px' } }, [
        React.createElement('div', { key: 'info', style: { fontSize: '13px', color: '#55647d', marginBottom: '4px' } },
          `Detected ${csvData.rows.length} rows. Map your CSV columns to trade fields:`
        ),
        React.createElement('div', { key: 'grid', style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' } },
          OUR_FIELDS.map(f =>
            React.createElement('div', { key: f.id }, [
              React.createElement('label', { key: 'l', style: { ...labelS, display: 'block', marginBottom: '4px' } }, f.label),
              React.createElement('select', {
                key: 's', value: mapping[f.id] ?? -1,
                onChange: e => setMapping(m => ({ ...m, [f.id]: parseInt(e.target.value) })),
                style: selS
              }, [
                React.createElement('option', { key: 'none', value: -1 }, '— skip —'),
                ...csvData.headers.map((h, i) => React.createElement('option', { key: i, value: i }, h))
              ])
            ])
          )
        ),
        React.createElement('button', {
          key: 'next', onClick: handleApplyMapping,
          style: { padding: '10px', background: '#5588ff', border: 'none', borderRadius: '8px', color: '#fff', fontSize: '14px', fontWeight: 600, cursor: 'pointer', fontFamily: 'Space Grotesk, sans-serif', marginTop: '8px' }
        }, 'Preview →')
      ]),

      // Step: Preview
      step === 'preview' && React.createElement('div', { key: 'prev', style: { flex: 1, overflowY: 'auto', padding: '20px 24px' } }, [
        React.createElement('div', { key: 'info', style: { fontSize: '13px', color: '#55647d', marginBottom: '12px' } },
          `${preview.length} trades detected from ${BROKER_LABELS[broker] || broker}. Review before importing:`
        ),
        React.createElement('table', { key: 'tbl', style: { width: '100%', borderCollapse: 'collapse', fontSize: '12px' } }, [
          React.createElement('thead', { key: 'th' }, React.createElement('tr', {},
            ['Date','Symbol','Type','Dir','Entry','P&L','Status'].map(h =>
              React.createElement('th', { key: h, style: { padding: '8px 10px', textAlign: 'left', color: '#55647d', fontWeight: 600, borderBottom: '1px solid #1e2440', fontSize: '11px', textTransform: 'uppercase', letterSpacing: '0.06em' } }, h)
            )
          )),
          React.createElement('tbody', { key: 'tb' },
            preview.slice(0, 20).map((t, i) =>
              React.createElement('tr', { key: i, style: { borderBottom: '1px solid #0a0d14' } }, [
                React.createElement('td', { key: 'd', style: { padding: '7px 10px', color: '#8a9bb5', fontFamily: 'JetBrains Mono, monospace' } }, fmtDate(t.date)),
                React.createElement('td', { key: 's', style: { padding: '7px 10px', color: '#d8dde8', fontWeight: 600, fontFamily: 'JetBrains Mono, monospace' } }, t.symbol),
                React.createElement('td', { key: 'ty', style: { padding: '7px 10px', color: '#8a9bb5' } }, t.type),
                React.createElement('td', { key: 'dr', style: { padding: '7px 10px', color: t.direction === 'long' ? '#00d27a' : '#f04060' } }, t.direction),
                React.createElement('td', { key: 'e', style: { padding: '7px 10px', color: '#8a9bb5', fontFamily: 'JetBrains Mono, monospace' } }, fmtPrice(t.entryPrice)),
                React.createElement('td', { key: 'p', style: { padding: '7px 10px', color: t.pnl >= 0 ? '#00d27a' : '#f04060', fontFamily: 'JetBrains Mono, monospace' } }, fmtPnL(t.pnl)),
                React.createElement('td', { key: 'st', style: { padding: '7px 10px', color: t.status === 'open' ? '#ffb83f' : '#55647d' } }, t.status),
              ])
            )
          )
        ]),
        preview.length > 20 && React.createElement('div', { key: 'more', style: { fontSize: '12px', color: '#55647d', textAlign: 'center', padding: '10px' } }, `+ ${preview.length - 20} more trades`)
      ]),

      // Footer
      React.createElement('div', { key: 'footer', style: { padding: '16px 24px', borderTop: '1px solid #1e2440', display: 'flex', justifyContent: 'space-between', alignItems: 'center' } }, [
        step !== 'drop' && React.createElement('button', { key: 'back', onClick: () => setStep(step === 'preview' && broker === 'generic' ? 'mapping' : 'drop'), style: { background: 'none', border: '1px solid #1e2440', borderRadius: '7px', color: '#8a9bb5', padding: '8px 16px', cursor: 'pointer', fontFamily: 'Space Grotesk, sans-serif', fontSize: '13px' } }, '← Back'),
        step === 'drop' && React.createElement('div', { key: 'sp' }),
        React.createElement('div', { key: 'right', style: { display: 'flex', gap: '8px' } }, [
          React.createElement('button', { key: 'cancel', onClick: onClose, style: { background: '#111520', border: '1px solid #1e2440', borderRadius: '7px', color: '#8a9bb5', padding: '8px 16px', cursor: 'pointer', fontFamily: 'Space Grotesk, sans-serif', fontSize: '13px' } }, 'Cancel'),
          step === 'preview' && React.createElement('button', { key: 'imp', onClick: handleImport, style: { background: '#5588ff', border: 'none', borderRadius: '7px', color: '#fff', fontWeight: 600, padding: '8px 20px', cursor: 'pointer', fontFamily: 'Space Grotesk, sans-serif', fontSize: '13px' } }, `Import ${preview.length} Trades`)
        ])
      ])
    ])
  ]);
};

Object.assign(window, { ImportModal, exportToCSV, exportToJSON });
