/**
 * PSKReporter + WSJT-X Panel
 * Digital mode spots — toggle between internet (PSKReporter) and local (WSJT-X UDP)
 * 
 * Layout:
 *   Row 1: Segmented mode toggle  |  map + filter controls
 *   Row 2: Sub-tabs (Being Heard / Hearing  or  Decodes / QSOs)
 *   Content: Scrolling spot/decode list
 */
import React, { useState, useMemo } from 'react';
import { usePSKReporter } from '../hooks/usePSKReporter.js';
import { getBandColor } from '../utils/callsign.js';

const PSKReporterPanel = ({ 
  callsign, 
  onShowOnMap, 
  showOnMap, 
  onToggleMap,
  filters = {},
  onOpenFilters,
  // WSJT-X props
  wsjtxDecodes = [],
  wsjtxClients = {},
  wsjtxQsos = [],
  wsjtxStats = {},
  wsjtxLoading,
  wsjtxEnabled,
  wsjtxPort,
  wsjtxRelayEnabled,
  showWSJTXOnMap,
  onToggleWSJTXMap
}) => {
  const [panelMode, setPanelMode] = useState('psk');
  const [activeTab, setActiveTab] = useState('tx');
  const [wsjtxTab, setWsjtxTab] = useState('decodes');
  const [wsjtxFilter, setWsjtxFilter] = useState('all'); // 'all' | 'cq' | band name
  
  // PSKReporter hook
  const { 
    txReports, txCount, rxReports, rxCount, 
    loading, error, connected, source, refresh 
  } = usePSKReporter(callsign, { 
    minutes: 15,
    enabled: callsign && callsign !== 'N0CALL'
  });

  // ── PSK filtering ──
  const filterReports = (reports) => {
    return reports.filter(r => {
      if (filters?.bands?.length && !filters.bands.includes(r.band)) return false;
      if (filters?.grids?.length) {
        const grid = activeTab === 'tx' ? r.receiverGrid : r.senderGrid;
        if (!grid) return false;
        if (!filters.grids.includes(grid.substring(0, 2).toUpperCase())) return false;
      }
      if (filters?.modes?.length && !filters.modes.includes(r.mode)) return false;
      return true;
    });
  };

  const filteredTx = useMemo(() => filterReports(txReports), [txReports, filters, activeTab]);
  const filteredRx = useMemo(() => filterReports(rxReports), [rxReports, filters, activeTab]);
  const filteredReports = activeTab === 'tx' ? filteredTx : filteredRx;
  const pskFilterCount = [filters?.bands?.length, filters?.grids?.length, filters?.modes?.length].filter(Boolean).length;

  const getFreqColor = (freqMHz) => !freqMHz ? 'var(--text-muted)' : getBandColor(parseFloat(freqMHz));
  const formatAge = (m) => m < 1 ? 'now' : m < 60 ? `${m}m` : `${Math.floor(m/60)}h`;

  // ── WSJT-X helpers ──
  const activeClients = Object.entries(wsjtxClients);
  const primaryClient = activeClients[0]?.[1] || null;

  // Build unified filter options: All, CQ Only, then each available band
  const wsjtxFilterOptions = useMemo(() => {
    const bands = [...new Set(wsjtxDecodes.map(d => d.band).filter(Boolean))]
      .sort((a, b) => (parseInt(b) || 999) - (parseInt(a) || 999));
    return [
      { value: 'all', label: 'All decodes' },
      { value: 'cq', label: 'CQ only' },
      ...bands.map(b => ({ value: b, label: b }))
    ];
  }, [wsjtxDecodes]);

  const filteredDecodes = useMemo(() => {
    let filtered = [...wsjtxDecodes];
    if (wsjtxFilter === 'cq') {
      filtered = filtered.filter(d => d.type === 'CQ');
    } else if (wsjtxFilter !== 'all') {
      // Band filter
      filtered = filtered.filter(d => d.band === wsjtxFilter);
    }
    return filtered.reverse();
  }, [wsjtxDecodes, wsjtxFilter]);

  const getSnrColor = (snr) => {
    if (snr == null) return 'var(--text-muted)';
    if (snr >= 0) return '#4ade80';
    if (snr >= -10) return '#fbbf24';
    if (snr >= -18) return '#fb923c';
    return '#ef4444';
  };

  const getMsgColor = (d) => {
    if (d.type === 'CQ') return '#60a5fa';
    if (['RR73', '73', 'RRR'].includes(d.exchange)) return '#4ade80';
    if (d.exchange?.startsWith('R')) return '#fbbf24';
    return 'var(--text-primary)';
  };

  // Active map toggle for current mode
  const isMapOn = panelMode === 'psk' ? showOnMap : showWSJTXOnMap;
  const handleMapToggle = panelMode === 'psk' ? onToggleMap : onToggleWSJTXMap;

  // Compact status dot
  const statusDot = connected 
    ? { color: '#4ade80', char: '●' }
    : (source === 'connecting' || source === 'reconnecting')
      ? { color: '#fbbf24', char: '◐' }
      : error ? { color: '#ef4444', char: '●' } : null;

  // ── Shared styles ──
  const segBtn = (active, color) => ({
    padding: '3px 10px',
    background: active ? `${color}18` : 'transparent',
    color: active ? color : 'var(--text-muted)',
    border: 'none',
    borderBottom: active ? `2px solid ${color}` : '2px solid transparent',
    fontSize: '11px',
    fontWeight: active ? '700' : '400',
    cursor: 'pointer',
    letterSpacing: '0.02em',
  });

  const subTabBtn = (active, color) => ({
    flex: 1,
    padding: '3px 4px',
    background: active ? `${color}20` : 'transparent',
    border: `1px solid ${active ? color + '66' : 'var(--border-color)'}`,
    borderRadius: '3px',
    color: active ? color : 'var(--text-muted)',
    cursor: 'pointer',
    fontSize: '10px',
    fontWeight: active ? '600' : '400',
  });

  const iconBtn = (active, activeColor = '#4488ff') => ({
    background: active ? `${activeColor}30` : 'rgba(100,100,100,0.3)',
    border: `1px solid ${active ? activeColor : '#555'}`,
    color: active ? activeColor : '#777',
    padding: '2px 6px',
    borderRadius: '3px',
    fontSize: '10px',
    cursor: 'pointer',
    lineHeight: 1,
  });

  return (
    <div className="panel" style={{ 
      padding: '8px 10px', 
      display: 'flex', 
      flexDirection: 'column',
      height: '100%',
      overflow: 'hidden'
    }}>
      {/* ── Row 1: Mode toggle + controls ── */}
      <div style={{ 
        display: 'flex', 
        alignItems: 'center',
        justifyContent: 'space-between',
        marginBottom: '5px',
        flexShrink: 0,
      }}>
        {/* Mode toggle */}
        <div style={{ display: 'flex' }}>
          <button onClick={() => setPanelMode('psk')} style={segBtn(panelMode === 'psk', 'var(--accent-primary)')}>
            PSKReporter
          </button>
          <button onClick={() => setPanelMode('wsjtx')} style={segBtn(panelMode === 'wsjtx', '#a78bfa')}>
            WSJT-X
          </button>
        </div>

        {/* Right controls */}
        <div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>
          {/* PSK: status dot + filter + refresh */}
          {panelMode === 'psk' && (
            <>
              {statusDot && (
                <span style={{ color: statusDot.color, fontSize: '10px', lineHeight: 1 }}>{statusDot.char}</span>
              )}
              <button onClick={onOpenFilters} style={iconBtn(pskFilterCount > 0, '#ffaa00')}>
                {pskFilterCount > 0 ? `🔍${pskFilterCount}` : '🔍'}
              </button>
              <button onClick={refresh} disabled={loading} style={{
                ...iconBtn(false),
                opacity: loading ? 0.4 : 1,
                cursor: loading ? 'not-allowed' : 'pointer',
              }}>🔄</button>
            </>
          )}

          {/* WSJT-X: mode/band info + unified filter */}
          {panelMode === 'wsjtx' && (
            <>
              {primaryClient && (
                <span style={{ fontSize: '9px', color: 'var(--text-muted)' }}>
                  {primaryClient.mode} {primaryClient.band}
                  {primaryClient.transmitting && <span style={{ color: '#ef4444', marginLeft: '2px' }}>TX</span>}
                </span>
              )}
              <select
                value={wsjtxFilter}
                onChange={(e) => setWsjtxFilter(e.target.value)}
                style={{
                  background: 'var(--bg-tertiary)',
                  color: wsjtxFilter !== 'all' ? '#a78bfa' : 'var(--text-primary)',
                  border: `1px solid ${wsjtxFilter !== 'all' ? '#a78bfa55' : 'var(--border-color)'}`,
                  borderRadius: '3px',
                  fontSize: '10px',
                  padding: '1px 4px',
                  cursor: 'pointer',
                  maxWidth: '90px',
                }}
              >
                {wsjtxFilterOptions.map(o => (
                  <option key={o.value} value={o.value}>{o.label}</option>
                ))}
              </select>
            </>
          )}

          {/* Map toggle (always visible) */}
          {handleMapToggle && (
            <button onClick={handleMapToggle} style={iconBtn(isMapOn, panelMode === 'psk' ? '#4488ff' : '#a78bfa')}>
              🗺️
            </button>
          )}
        </div>
      </div>

      {/* ── Row 2: Sub-tabs ── */}
      <div style={{ display: 'flex', gap: '4px', marginBottom: '5px', flexShrink: 0 }}>
        {panelMode === 'psk' ? (
          <>
            <button onClick={() => setActiveTab('tx')} style={subTabBtn(activeTab === 'tx', '#4ade80')}>
              ▲ Heard ({pskFilterCount > 0 ? filteredTx.length : txCount})
            </button>
            <button onClick={() => setActiveTab('rx')} style={subTabBtn(activeTab === 'rx', '#60a5fa')}>
              ▼ Hearing ({pskFilterCount > 0 ? filteredRx.length : rxCount})
            </button>
          </>
        ) : (
          <>
            <button onClick={() => setWsjtxTab('decodes')} style={subTabBtn(wsjtxTab === 'decodes', '#a78bfa')}>
              Decodes ({filteredDecodes.length})
            </button>
            <button onClick={() => setWsjtxTab('qsos')} style={subTabBtn(wsjtxTab === 'qsos', '#a78bfa')}>
              QSOs ({wsjtxQsos.length})
            </button>
          </>
        )}
      </div>

      {/* ── Content area ── */}
      <div style={{ flex: 1, overflow: 'auto', fontSize: '11px', fontFamily: "'JetBrains Mono', monospace" }}>

        {/* === PSKReporter content === */}
        {panelMode === 'psk' && (
          <>
            {(!callsign || callsign === 'N0CALL') ? (
              <div style={{ color: 'var(--text-muted)', textAlign: 'center', padding: '16px', fontSize: '11px' }}>
                Set your callsign in Settings to see reports
              </div>
            ) : error && !connected ? (
              <div style={{ textAlign: 'center', padding: '12px', color: 'var(--text-muted)', fontSize: '11px' }}>
                Connection failed — tap 🔄
              </div>
            ) : loading && filteredReports.length === 0 && pskFilterCount === 0 ? (
              <div style={{ textAlign: 'center', padding: '16px', color: 'var(--text-muted)', fontSize: '11px' }}>
                <div className="loading-spinner" style={{ margin: '0 auto 8px' }} />
                Connecting...
              </div>
            ) : filteredReports.length === 0 ? (
              <div style={{ textAlign: 'center', padding: '12px', color: 'var(--text-muted)', fontSize: '11px' }}>
                {pskFilterCount > 0 
                  ? 'No spots match filters'
                  : activeTab === 'tx' 
                    ? 'Waiting for spots... (TX to see reports)' 
                    : 'No stations heard yet'}
              </div>
            ) : (
              filteredReports.slice(0, 25).map((report, i) => {
                const freqMHz = report.freqMHz || (report.freq ? (report.freq / 1000000).toFixed(3) : '?');
                const color = getFreqColor(freqMHz);
                const displayCall = activeTab === 'tx' ? report.receiver : report.sender;
                const grid = activeTab === 'tx' ? report.receiverGrid : report.senderGrid;
                
                return (
                  <div
                    key={`${displayCall}-${report.freq}-${i}`}
                    onClick={() => onShowOnMap?.(report)}
                    style={{
                      display: 'grid',
                      gridTemplateColumns: '52px 1fr auto',
                      gap: '5px',
                      padding: '3px 4px',
                      borderRadius: '2px',
                      background: i % 2 === 0 ? 'rgba(255,255,255,0.02)' : 'transparent',
                      cursor: report.lat && report.lon ? 'pointer' : 'default',
                    }}
                    onMouseEnter={(e) => e.currentTarget.style.background = 'rgba(68,136,255,0.12)'}
                    onMouseLeave={(e) => e.currentTarget.style.background = i % 2 === 0 ? 'rgba(255,255,255,0.02)' : 'transparent'}
                  >
                    <span style={{ color, fontWeight: '600', fontSize: '10px' }}>{freqMHz}</span>
                    <span style={{ 
                      color: 'var(--text-primary)', fontWeight: '600', fontSize: '11px',
                      overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap'
                    }}>
                      {displayCall}
                      {grid && <span style={{ color: 'var(--text-muted)', fontWeight: '400', marginLeft: '4px', fontSize: '9px' }}>{grid}</span>}
                    </span>
                    <span style={{ display: 'flex', alignItems: 'center', gap: '3px', fontSize: '9px' }}>
                      <span style={{ color: 'var(--text-muted)' }}>{report.mode}</span>
                      {report.snr != null && (
                        <span style={{ color: report.snr >= 0 ? '#4ade80' : report.snr >= -10 ? '#fbbf24' : '#f97316', fontWeight: '600' }}>
                          {report.snr > 0 ? '+' : ''}{report.snr}
                        </span>
                      )}
                      <span style={{ color: 'var(--text-muted)' }}>{formatAge(report.age)}</span>
                    </span>
                  </div>
                );
              })
            )}
          </>
        )}

        {/* === WSJT-X content === */}
        {panelMode === 'wsjtx' && (
          <>
            {/* No client connected */}
            {!wsjtxLoading && activeClients.length === 0 && wsjtxDecodes.length === 0 ? (
              <div style={{ 
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                flexDirection: 'column', gap: '8px', color: 'var(--text-muted)',
                fontSize: '11px', textAlign: 'center', padding: '16px 8px', height: '100%'
              }}>
                <div style={{ fontSize: '12px' }}>Waiting for WSJT-X...</div>
                {wsjtxRelayEnabled ? (
                  <div style={{ fontSize: '10px', opacity: 0.6, lineHeight: 1.5 }}>
                    <span style={{ color: '#a78bfa' }}>Relay mode</span> — run the relay agent locally:
                    <br />
                    <code style={{ background: 'rgba(167,139,250,0.15)', padding: '1px 4px', borderRadius: '2px', fontSize: '9px' }}>
                      node relay.js --url {'{this server}'} --key {'{key}'}
                    </code>
                    <br />
                    <span style={{ fontSize: '9px' }}>See wsjtx-relay/README.md</span>
                  </div>
                ) : (
                  <div style={{ fontSize: '10px', opacity: 0.6, lineHeight: 1.5 }}>
                    In WSJT-X: Settings → Reporting → UDP Server
                    <br />
                    Address: 127.0.0.1 &nbsp; Port: {wsjtxPort || 2237}
                  </div>
                )}
              </div>
            ) : wsjtxTab === 'decodes' ? (
              <>
                {filteredDecodes.length === 0 ? (
                  <div style={{ color: 'var(--text-muted)', textAlign: 'center', padding: '16px', fontSize: '11px' }}>
                    {wsjtxDecodes.length > 0 ? 'No decodes match filter' : 'Listening...'}
                  </div>
                ) : (
                  filteredDecodes.map((d, i) => (
                    <div 
                      key={d.id || i}
                      style={{
                        display: 'flex', gap: '5px', padding: '2px 2px',
                        borderBottom: '1px solid var(--border-color)',
                        alignItems: 'baseline',
                        opacity: d.lowConfidence ? 0.5 : 1,
                      }}
                    >
                      <span style={{ color: 'var(--text-muted)', minWidth: '44px', fontSize: '10px' }}>{d.time}</span>
                      <span style={{ color: getSnrColor(d.snr), minWidth: '26px', textAlign: 'right', fontSize: '10px' }}>
                        {d.snr != null ? (d.snr >= 0 ? `+${d.snr}` : d.snr) : ''}
                      </span>
                      <span style={{ color: 'var(--text-muted)', minWidth: '24px', textAlign: 'right', fontSize: '10px' }}>{d.dt}</span>
                      <span style={{ 
                        color: d.band ? getBandColor(d.dialFrequency / 1000000) : 'var(--text-muted)',
                        minWidth: '32px', textAlign: 'right', fontSize: '10px'
                      }}>{d.freq}</span>
                      <span style={{ 
                        color: getMsgColor(d), flex: 1, whiteSpace: 'nowrap',
                        overflow: 'hidden', textOverflow: 'ellipsis',
                      }}>{d.message}</span>
                    </div>
                  ))
                )}
              </>
            ) : (
              /* QSOs tab */
              <>
                {wsjtxQsos.length === 0 ? (
                  <div style={{ color: 'var(--text-muted)', textAlign: 'center', padding: '16px', fontSize: '11px' }}>
                    No QSOs logged yet
                  </div>
                ) : (
                  [...wsjtxQsos].reverse().map((q, i) => (
                    <div key={i} style={{
                      display: 'flex', gap: '5px', padding: '3px 2px',
                      borderBottom: '1px solid var(--border-color)', alignItems: 'baseline',
                    }}>
                      <span style={{ 
                        color: q.band ? getBandColor(q.frequency / 1000000) : 'var(--accent-green)', 
                        fontWeight: '600', minWidth: '65px' 
                      }}>{q.dxCall}</span>
                      <span style={{ color: 'var(--text-muted)', fontSize: '10px' }}>{q.band}</span>
                      <span style={{ color: 'var(--text-muted)', fontSize: '10px' }}>{q.mode}</span>
                      <span style={{ color: 'var(--text-muted)', fontSize: '10px' }}>{q.reportSent}/{q.reportRecv}</span>
                      {q.dxGrid && <span style={{ color: '#a78bfa', fontSize: '10px' }}>{q.dxGrid}</span>}
                    </div>
                  ))
                )}
              </>
            )}
          </>
        )}
      </div>

      {/* ── WSJT-X status footer ── */}
      {panelMode === 'wsjtx' && activeClients.length > 0 && (
        <div style={{ 
          fontSize: '9px', color: 'var(--text-muted)',
          borderTop: '1px solid var(--border-color)',
          paddingTop: '2px', marginTop: '2px',
          display: 'flex', justifyContent: 'space-between', flexShrink: 0
        }}>
          <span>{activeClients.map(([id, c]) => `${id}${c.version ? ` v${c.version}` : ''}`).join(', ')}</span>
          {primaryClient?.dialFrequency && (
            <span style={{ color: '#a78bfa' }}>{(primaryClient.dialFrequency / 1000000).toFixed(6)} MHz</span>
          )}
        </div>
      )}
    </div>
  );
};

export default PSKReporterPanel;
export { PSKReporterPanel };
