const { useEffect, useMemo, useState } = React;

const EMPTY_METRICS = {
  totalExecutions: 0,
  totalCost: 0,
  totalDuration: 0,
  avgCost: 0,
  avgDuration: 0,
  statusCounts: {
    busy: 0,
    completed: 0,
    in_progress: 0,
    failed: 0
  }
};

function toTitle(value) {
  return String(value || '')
    .replace(/_/g, ' ')
    .replace(/\b\w/g, (c) => c.toUpperCase());
}

function formatCurrency(value) {
  const amount = Number(value) || 0;
  return new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD',
    minimumFractionDigits: 2,
    maximumFractionDigits: 2
  }).format(amount);
}

function formatDuration(value) {
  const seconds = Math.max(0, Math.round(Number(value) || 0));
  const hours = Math.floor(seconds / 3600);
  const minutes = Math.floor((seconds % 3600) / 60);
  const remainingSeconds = seconds % 60;

  if (hours > 0) {
    return `${hours}h ${minutes}m ${remainingSeconds}s`;
  }
  if (minutes > 0) {
    return `${minutes}m ${remainingSeconds}s`;
  }
  return `${remainingSeconds}s`;
}

function shortenUuid(value) {
  const str = String(value || '');
  if (str.length <= 16) return str || '-';
  return `${str.slice(0, 8)}...${str.slice(-6)}`;
}

function statusClass(status) {
  const normalized = String(status || '').toLowerCase();
  return `status-pill ${normalized || 'unknown'}`;
}

function DetailView({ detail, loading, error, onBack, onTranscribe, transcribing, transcribeError }) {
  const transcript = (detail && Array.isArray(detail.transcript)) ? detail.transcript : [];

  return (
    <div className="detail-wrap">
      <button className="ghost-button" onClick={onBack}>Back to dashboard</button>

      <div className="detail-header">
        <h2>Conversation data</h2>
        <p className="detail-subtitle">{detail && detail.callUuid ? detail.callUuid : '-'}</p>
      </div>

      {loading && <div className="state loading">Loading conversation detail...</div>}
      {error && <div className="state error">{error}</div>}

      {!loading && !error && detail && (
        <>
          <section className="metrics-grid detail-metrics">
            <article className="metric-card">
              <p className="metric-label">Status</p>
              <p className="metric-value">
                <span className={statusClass(detail.status)}>{toTitle(detail.status)}</span>
              </p>
            </article>
            <article className="metric-card">
              <p className="metric-label">Duration</p>
              <p className="metric-value">{formatDuration(detail.durationSeconds)}</p>
            </article>
            <article className="metric-card">
              <p className="metric-label">Total Cost</p>
              <p className="metric-value">{formatCurrency(detail.totalAmount)}</p>
            </article>
            <article className="metric-card">
              <p className="metric-label">Messages count</p>
              <p className="metric-value">{transcript.length}</p>
            </article>
          </section>

          <section className="panel">
            <div className="panel-head">
              <h3>Call Recording</h3>
              <div style={{ display: 'flex', gap: '8px', flexWrap: 'wrap' }}>
                {detail.recordingLink ? (
                  <button
                    className="ghost-button"
                    onClick={onTranscribe}
                    disabled={transcribing}
                  >
                    {transcribing ? 'Transcribing...' : (transcript.length ? 'Refresh transcript' : 'Transcribe recording')}
                  </button>
                ) : null}
                {detail.recordingLink ? (
                  <a
                    className="open-link"
                    href={detail.recordingLink}
                    target="_blank"
                    rel="noreferrer"
                  >
                    Open raw recording URL
                  </a>
                ) : null}
              </div>
            </div>

            {transcribeError ? <div className="state error" style={{ marginBottom: '10px' }}>{transcribeError}</div> : null}

            {detail.recordingLink ? (
              <audio className="audio-player" controls src={detail.recordingLink}>
                Your browser does not support the audio element.
              </audio>
            ) : (
              <p className="muted">No recording available for this conversation.</p>
            )}
          </section>

          <section className="panel">
            <h3>Transcription</h3>
            {transcript.length ? (
              <div className="chat-thread">
                {transcript.map((msg, index) => {
                  const role = String(msg.role || '').toLowerCase().includes('user') ? 'user' : 'assistant';
                  return (
                    <div key={`${role}-${index}`} className={`bubble-row ${role}`}>
                      <div className={`bubble ${role}`}>
                        <p className="bubble-role">{toTitle(role)}</p>
                        <p>{msg.text || '-'}</p>
                        {msg.at ? <span className="bubble-time">{msg.at}</span> : null}
                      </div>
                    </div>
                  );
                })}
              </div>
            ) : (
              <p className="muted">No transcript available for this call.</p>
            )}
          </section>
        </>
      )}
    </div>
  );
}

function App() {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');
  const [calls, setCalls] = useState([]);
  const [metrics, setMetrics] = useState(EMPTY_METRICS);

  const [searchText, setSearchText] = useState('');
  const [statusFilter, setStatusFilter] = useState('all');

  const [activeCallUuid, setActiveCallUuid] = useState('');
  const [detail, setDetail] = useState(null);
  const [detailLoading, setDetailLoading] = useState(false);
  const [detailError, setDetailError] = useState('');
  const [transcribing, setTranscribing] = useState(false);
  const [transcribeError, setTranscribeError] = useState('');

  async function loadCalls() {
    setLoading(true);
    setError('');
    try {
      const res = await fetch('/api/calls?limit=150');
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || 'Failed to fetch calls');
      setCalls(Array.isArray(data.items) ? data.items : []);
      setMetrics(data.metrics || EMPTY_METRICS);
    } catch (e) {
      setError(e.message || String(e));
      setCalls([]);
      setMetrics(EMPTY_METRICS);
    } finally {
      setLoading(false);
    }
  }

  async function loadCallDetail(callUuid) {
    setActiveCallUuid(callUuid);
    setDetail(null);
    setDetailError('');
    setTranscribeError('');
    setDetailLoading(true);
    try {
      const res = await fetch(`/api/calls/${encodeURIComponent(callUuid)}`);
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || 'Failed to fetch call detail');
      setDetail(data.item || null);
    } catch (e) {
      setDetailError(e.message || String(e));
      setDetail(null);
    } finally {
      setDetailLoading(false);
    }
  }

  async function transcribeActiveCall() {
    if (!activeCallUuid) return;

    setTranscribing(true);
    setTranscribeError('');
    try {
      const res = await fetch(`/api/calls/${encodeURIComponent(activeCallUuid)}/transcribe`, {
        method: 'POST'
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || 'Failed to transcribe call');
      setDetail(data.item || null);
    } catch (e) {
      setTranscribeError(e.message || String(e));
    } finally {
      setTranscribing(false);
    }
  }

  function closeDetail() {
    setActiveCallUuid('');
    setDetail(null);
    setDetailError('');
    setTranscribeError('');
    setDetailLoading(false);
    setTranscribing(false);
  }

  useEffect(() => {
    loadCalls();
  }, []);

  const filteredCalls = useMemo(() => {
    const needle = searchText.trim().toLowerCase();
    return calls.filter((call) => {
      const matchesStatus = statusFilter === 'all' || call.status === statusFilter;
      const matchesId = !needle || String(call.callUuid || '').toLowerCase().includes(needle);
      return matchesStatus && matchesId;
    });
  }, [calls, searchText, statusFilter]);

  if (activeCallUuid) {
    return (
      <div className="page">
        <DetailView
          detail={detail}
          loading={detailLoading}
          error={detailError}
          onBack={closeDetail}
          onTranscribe={transcribeActiveCall}
          transcribing={transcribing}
          transcribeError={transcribeError}
        />
      </div>
    );
  }

  return (
    <div className="page">
      <header className="hero">
        <h1>Agent conversations</h1>
        <p className="subtitle">Monitor execution outcomes, spend, and conversation artifacts.</p>
      </header>

      <section className="section-head">
        <h2>Performance Metrics</h2>
      </section>

      <section className="metrics-grid">
        <article className="metric-card">
          <p className="metric-label">Total executions</p>
          <p className="metric-value">{metrics.totalExecutions || 0}</p>
        </article>
        <article className="metric-card">
          <p className="metric-label">Total cost</p>
          <p className="metric-value">{formatCurrency(metrics.totalCost)}</p>
        </article>
        <article className="metric-card">
          <p className="metric-label">Total duration</p>
          <p className="metric-value">{formatDuration(metrics.totalDuration)}</p>
        </article>
        <article className="metric-card">
          <p className="metric-label">Completed</p>
          <p className="metric-value">{metrics.statusCounts.completed || 0}</p>
        </article>
        <article className="metric-card">
          <p className="metric-label">In Progress</p>
          <p className="metric-value">{metrics.statusCounts.in_progress || 0}</p>
        </article>
        <article className="metric-card">
          <p className="metric-label">Failed</p>
          <p className="metric-value">{metrics.statusCounts.failed || 0}</p>
        </article>
        <article className="metric-card">
          <p className="metric-label">Busy</p>
          <p className="metric-value">{metrics.statusCounts.busy || 0}</p>
        </article>
        <article className="metric-card">
          <p className="metric-label">Avg cost</p>
          <p className="metric-value">{formatCurrency(metrics.avgCost)}</p>
        </article>
        <article className="metric-card">
          <p className="metric-label">Avg duration</p>
          <p className="metric-value">{formatDuration(metrics.avgDuration)}</p>
        </article>
      </section>

      <section className="panel">
        <div className="toolbar">
          <label className="field">
            <span>Search by execution ID</span>
            <input
              type="text"
              placeholder="e.g. 93d4f0"
              value={searchText}
              onChange={(e) => setSearchText(e.target.value)}
            />
          </label>

          <label className="field">
            <span>Status</span>
            <select
              value={statusFilter}
              onChange={(e) => setStatusFilter(e.target.value)}
            >
              <option value="all">All</option>
              <option value="completed">Completed</option>
              <option value="in_progress">In Progress</option>
              <option value="failed">Failed</option>
              <option value="busy">Busy</option>
            </select>
          </label>

          <button className="primary-btn" onClick={loadCalls} disabled={loading}>
            {loading ? 'Refreshing...' : 'Refresh'}
          </button>
        </div>

        {error ? <div className="state error">{error}</div> : null}

        <div className="table-wrap">
          <table>
            <thead>
              <tr>
                <th>Execution ID</th>
                <th>User Number</th>
                <th>Conversation type</th>
                <th>Duration(s)</th>
                <th>Hangup by</th>
                <th>Batch</th>
                <th>Timestamp</th>
                <th>Cost</th>
                <th>Status</th>
                <th>Conversation data</th>
                <th>Actions</th>
              </tr>
            </thead>
            <tbody>
              {loading ? (
                <tr>
                  <td colSpan="11" className="state loading">Loading calls...</td>
                </tr>
              ) : null}

              {!loading && !filteredCalls.length ? (
                <tr>
                  <td colSpan="11" className="state empty">No calls found for the selected filters.</td>
                </tr>
              ) : null}

              {!loading && filteredCalls.map((call) => (
                <tr key={call.callUuid || Math.random()}>
                  <td title={call.callUuid || ''}>{shortenUuid(call.callUuid)}</td>
                  <td>{call.userNumber || call.phoneNumber || '-'}</td>
                  <td>{toTitle(call.callDirection || '-')}</td>
                  <td>{Math.round(Number(call.durationSeconds) || 0)}</td>
                  <td>{call.hangupSource || call.hangupCauseName || '-'}</td>
                  <td>{call.batch || call.aiAgentName || '-'}</td>
                  <td>{call.timestampDisplay || '-'}</td>
                  <td>{formatCurrency(call.totalAmount)}</td>
                  <td>
                    <span className={statusClass(call.status)}>{toTitle(call.status)}</span>
                  </td>
                  <td>
                    {call.recordingLink ? (
                      <a href={call.recordingLink} target="_blank" rel="noreferrer" className="table-link">
                        Recordings, transcripts, etc
                      </a>
                    ) : (
                      <span className="muted">Unavailable</span>
                    )}
                  </td>
                  <td>
                    <button className="ghost-button" onClick={() => loadCallDetail(call.callUuid)}>
                      View
                    </button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </section>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
