import { useEffect, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { listPlans, getPlanState, getPlanEvents, type PlanSummary, type PlanStateDetail, type PlanEvent } from '../services/orchestrator';
import StateMachineView from '../components/portal/StateMachineView';
import { endpoints } from '../config/endpoints';

type Source = 'live' | 'mocked' | 'degraded';

function SourceBadge({ source }: { source: Source }) {
  const label = source === 'live' ? 'LIVE' : source === 'degraded' ? 'DEGRADED' : 'DEMO';
  return <span className={`source-badge source-badge--${source}`}>{label}</span>;
}

export default function TransactionsPage() {
  const { planId } = useParams<{ planId?: string }>();
  return planId ? <TransactionDetail planId={planId} /> : <TransactionsList />;
}

function TransactionsList() {
  const navigate = useNavigate();
  const [plans, setPlans] = useState<PlanSummary[] | null>(null);
  const [source, setSource] = useState<Source>('mocked');
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    let cancelled = false;
    setPlans(null);
    setError(null);
    listPlans()
      .then((res) => {
        if (cancelled) return;
        setPlans(res.plans);
        setSource(res.source);
      })
      .catch((err) => {
        if (cancelled) return;
        setError(err instanceof Error ? err.message : String(err));
      });
    return () => {
      cancelled = true;
    };
  }, []);

  return (
    <div className="transactions-page">
      <div className="page-header">
        <h1>Transactions</h1>
        <p className="page-subtitle">
          Multi-layer atomic settlement plans. State machine per architecture note §8.
          {!endpoints.orchestrator.deployed && (
            <span className="muted">
              {' '}Orchestrator not deployed — showing demo plans.
            </span>
          )}
        </p>
      </div>

      <div className="dashboard-card">
        <div className="card-header">
          <h3>Recent plans</h3>
          <SourceBadge source={source} />
        </div>
        {error && <div className="error-banner">{error}</div>}
        {plans === null ? (
          <div className="loading-row">Loading…</div>
        ) : plans.length === 0 ? (
          <div className="empty-row">No plans yet.</div>
        ) : (
          <table className="portal-table" data-testid="transactions-table">
            <thead>
              <tr>
                <th>Plan ID</th>
                <th>State</th>
                <th>Instrument</th>
                <th>Owner</th>
                <th>Updated</th>
                <th aria-label="open" />
              </tr>
            </thead>
            <tbody>
              {plans.map((p) => (
                <tr
                  key={p.plan_id}
                  className="portal-table-row"
                  onClick={() => navigate(`/transactions/${encodeURIComponent(p.plan_id)}`)}
                  data-testid={`plan-row-${p.plan_id}`}
                >
                  <td className="mono">{p.plan_id}</td>
                  <td>
                    <span className={`state-chip state-chip--${p.status.toLowerCase()}`}>
                      {p.status.replace(/_/g, ' ')}
                    </span>
                  </td>
                  <td>{p.instrument_hint ?? '—'}</td>
                  <td>{p.actor_id ?? '—'}</td>
                  <td>{new Date(p.updated_at).toLocaleString()}</td>
                  <td className="row-chevron">›</td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>
    </div>
  );
}

function TransactionDetail({ planId }: { planId: string }) {
  const navigate = useNavigate();
  const [detail, setDetail] = useState<PlanStateDetail | null>(null);
  const [events, setEvents] = useState<PlanEvent[] | null>(null);
  const [source, setSource] = useState<Source>('mocked');
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    let cancelled = false;
    setDetail(null);
    setEvents(null);
    setError(null);
    Promise.all([getPlanState(planId), getPlanEvents(planId)])
      .then(([s, e]) => {
        if (cancelled) return;
        setDetail(s.detail);
        setEvents(e.events);
        setSource(s.source === 'live' && e.source === 'live' ? 'live' : s.source);
      })
      .catch((err) => {
        if (cancelled) return;
        setError(err instanceof Error ? err.message : String(err));
      });
    return () => {
      cancelled = true;
    };
  }, [planId]);

  return (
    <div className="transactions-page">
      <div className="page-header">
        <button className="back-button" onClick={() => navigate('/transactions')}>
          ← All transactions
        </button>
        <h1>
          Plan <span className="mono">{planId}</span>
        </h1>
        <p className="page-subtitle">
          {detail ? (
            <>Current state: <strong>{detail.current_state.replace(/_/g, ' ')}</strong></>
          ) : (
            'Loading plan state…'
          )}
        </p>
      </div>

      {error && <div className="error-banner">{error}</div>}

      <div className="dashboard-card">
        <div className="card-header">
          <h3>12-state machine</h3>
          <SourceBadge source={source} />
        </div>
        {detail ? (
          <StateMachineView current={detail.current_state} transitions={detail.transitions} />
        ) : (
          <div className="loading-row">Loading…</div>
        )}
      </div>

      <div className="dashboard-card">
        <div className="card-header">
          <h3>Audit trail</h3>
        </div>
        {detail === null ? (
          <div className="loading-row">Loading…</div>
        ) : detail.transitions.length === 0 ? (
          <div className="empty-row">No transitions recorded.</div>
        ) : (
          <table className="portal-table" data-testid="audit-trail">
            <thead>
              <tr>
                <th>#</th>
                <th>From → To</th>
                <th>Actor</th>
                <th>Role</th>
                <th>Reason</th>
                <th>At</th>
              </tr>
            </thead>
            <tbody>
              {detail.transitions.map((t, i) => (
                <tr key={i}>
                  <td>{i + 1}</td>
                  <td className="mono">
                    {t.from_state ?? '∅'} → {t.to_state}
                  </td>
                  <td>{t.actor_id}</td>
                  <td>
                    <span className={`role-chip role-chip--${t.actor_role}`}>{t.actor_role}</span>
                  </td>
                  <td>{t.reason ?? '—'}</td>
                  <td>{new Date(t.occurred_at).toLocaleString()}</td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>

      <div className="dashboard-card">
        <div className="card-header">
          <h3>Signed event stream</h3>
        </div>
        {events === null ? (
          <div className="loading-row">Loading…</div>
        ) : events.length === 0 ? (
          <div className="empty-row">No events.</div>
        ) : (
          <table className="portal-table" data-testid="event-stream">
            <thead>
              <tr>
                <th>#</th>
                <th>Type</th>
                <th>Signature</th>
                <th>Prev hash</th>
                <th>At</th>
              </tr>
            </thead>
            <tbody>
              {events.map((e) => (
                <tr key={e.id}>
                  <td>{e.id}</td>
                  <td className="mono">{e.type}</td>
                  <td className="mono truncate">{e.signature}</td>
                  <td className="mono truncate">{e.prev_hash ?? '∅'}</td>
                  <td>{new Date(e.created_at).toLocaleString()}</td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>
    </div>
  );
}
