import { Fragment, useEffect, useState } from 'react';

import EmptyState from '../components/EmptyState.jsx';
import MetricCard from '../components/MetricCard.jsx';
import Pill from '../components/Pill.jsx';
import TableFrame from '../components/TableFrame.jsx';
import { formatEur, formatTimestamp, stringifyJson, truncateMiddle } from '../lib/format.js';

function buildInitialEstimateForm(balances, withdrawalDefaults) {
  const firstAssetId = balances?.[0]?.asset_id || '';
  return {
    asset_id: firstAssetId,
    amount: '',
    destination_address:
      withdrawalDefaults?.[firstAssetId]
      || Object.values(withdrawalDefaults || {})[0]
      || '',
    chain: '',
  };
}

function BalancesTable({ items }) {
  if (!items?.length) return <EmptyState>No inventory snapshot is available yet.</EmptyState>;

  return (
    <TableFrame>
      <table>
        <thead>
          <tr>
            <th>Asset</th>
            <th>Spendable</th>
            <th>Pending inbound</th>
            <th>Pending outbound</th>
            <th>EUR value</th>
          </tr>
        </thead>
        <tbody>
          {items.map((item) => (
            <tr key={item.asset_id}>
              <td>
                <strong>{item.symbol}</strong>
                <div className="muted mono">{item.asset_id}</div>
              </td>
              <td className="mono">{item.spendable}</td>
              <td className="mono">{item.pending_inbound}</td>
              <td className="mono">{item.pending_outbound}</td>
              <td className="mono">{formatEur(item.eur_value_eure)}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </TableFrame>
  );
}

function HandlesList({ handles }) {
  if (!handles?.length) return <EmptyState>No funding handles are available.</EmptyState>;

  return (
    <div className="service-grid">
      {handles.map((handle) => (
        <div className="service-card" key={`${handle.chain}:${handle.address || handle.asset_id}`}>
          <div className="service-head">
            <strong>{handle.symbol}</strong>
            <Pill label={handle.chain} stateLabel="healthy" />
          </div>
          <div className="service-detail">
            <div className="mono">{handle.address || 'Unavailable'}</div>
            {handle.memo ? <div className="mono">{`Memo ${handle.memo}`}</div> : null}
            <div>{`Refreshed ${formatTimestamp(handle.refreshed_at)}`}</div>
          </div>
        </div>
      ))}
    </div>
  );
}

function FundingTable({ items, creditedOnly = false }) {
  if (!items?.length) {
    return (
      <EmptyState>
        {creditedOnly ? 'No credited deposits have been recorded yet.' : 'No funding observations are available.'}
      </EmptyState>
    );
  }

  return (
    <TableFrame>
      <table>
        <thead>
          <tr>
            <th>Status</th>
            <th>Asset</th>
            <th>Amount</th>
            <th>Handle</th>
            <th>Observed</th>
          </tr>
        </thead>
        <tbody>
          {items.map((item) => (
            <tr key={item.funding_observation_id || `${item.tx_hash}:${item.status}`}>
              <td><Pill label={item.status} stateLabel={item.status} /></td>
              <td>{item.asset_symbol || item.asset_id}</td>
              <td className="mono">{item.amount_display || item.amount || 'Unavailable'}</td>
              <td className="mono truncate-cell" title={item.funding_handle || ''}>{truncateMiddle(item.funding_handle || '', 36)}</td>
              <td>{formatTimestamp(item.credited_at || item.last_seen_at || item.first_seen_at)}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </TableFrame>
  );
}

function PreCreditAssetTable({ items }) {
  if (!items?.length) return <EmptyState>No pre-credit funding is currently tracked.</EmptyState>;

  return (
    <TableFrame>
      <table>
        <thead>
          <tr>
            <th>Asset</th>
            <th>Pending amount</th>
            <th>Observation count</th>
            <th>Last seen</th>
          </tr>
        </thead>
        <tbody>
          {items.map((item) => (
            <tr key={item.asset_id}>
              <td>{item.asset_symbol || item.asset_id}</td>
              <td className="mono">{item.amount_display || item.amount || 'Unavailable'}</td>
              <td>{item.observation_count || 0}</td>
              <td>{formatTimestamp(item.last_seen_at)}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </TableFrame>
  );
}

function WithdrawalsTable({ items }) {
  if (!items?.length) return <EmptyState>No withdrawals are tracked yet.</EmptyState>;

  return (
    <TableFrame>
      <table>
        <thead>
          <tr>
            <th>Status</th>
            <th>Asset</th>
            <th>Amount</th>
            <th>Destination</th>
            <th>Observed</th>
          </tr>
        </thead>
        <tbody>
          {items.map((item) => (
            <tr key={item.withdrawal_id || `${item.asset_id}:${item.requested_at}`}>
              <td><Pill label={item.status} stateLabel={item.status} /></td>
              <td>{item.asset_symbol || item.asset_id}</td>
              <td className="mono">{item.amount_display || item.amount || 'Unavailable'}</td>
              <td className="mono truncate-cell" title={item.destination_address || ''}>{truncateMiddle(item.destination_address || '', 36)}</td>
              <td>{formatTimestamp(item.completed_at || item.requested_at)}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </TableFrame>
  );
}

function WithdrawalEstimateForm({ balances, withdrawalDefaults, onControl }) {
  const [form, setForm] = useState(() => buildInitialEstimateForm(balances, withdrawalDefaults));

  useEffect(() => {
    setForm(buildInitialEstimateForm(balances, withdrawalDefaults));
  }, [balances, withdrawalDefaults]);

  async function handleSubmit(event) {
    event.preventDefault();
    const body = { ...form };
    if (!body.chain) delete body.chain;
    await onControl('liquidity-manager', 'withdrawal-estimate', body, { reload: false });
  }

  return (
    <form onSubmit={handleSubmit}>
      <div className="form-grid">
        <div className="field">
          <label htmlFor="estimate-asset">Asset</label>
          <select
            id="estimate-asset"
            name="asset_id"
            onChange={(event) => {
              const assetId = event.target.value;
              setForm((current) => ({
                ...current,
                asset_id: assetId,
                destination_address:
                  withdrawalDefaults?.[assetId]
                  || current.destination_address
                  || '',
              }));
            }}
            value={form.asset_id}
          >
            {(balances || []).map((item) => (
              <option key={item.asset_id} value={item.asset_id}>
                {item.symbol}
              </option>
            ))}
          </select>
        </div>
        <div className="field">
          <label htmlFor="estimate-amount">Amount units</label>
          <input
            id="estimate-amount"
            name="amount"
            onChange={(event) => setForm((current) => ({ ...current, amount: event.target.value }))}
            placeholder="1000000"
            required
            value={form.amount}
          />
        </div>
        <div className="field">
          <label htmlFor="estimate-destination">Destination</label>
          <input
            id="estimate-destination"
            name="destination_address"
            onChange={(event) => setForm((current) => ({ ...current, destination_address: event.target.value }))}
            value={form.destination_address}
          />
        </div>
        <div className="field">
          <label htmlFor="estimate-chain">Chain override</label>
          <input
            id="estimate-chain"
            name="chain"
            onChange={(event) => setForm((current) => ({ ...current, chain: event.target.value }))}
            placeholder="Optional"
            value={form.chain}
          />
        </div>
      </div>
      <div className="button-row">
        <button className="button" type="submit">Estimate Withdrawal</button>
      </div>
    </form>
  );
}

async function copyIdentifier(value) {
  if (!value || typeof navigator === 'undefined' || !navigator.clipboard?.writeText) return;
  try {
    await navigator.clipboard.writeText(value);
  } catch {
    // Full ids remain visible when clipboard access is unavailable.
  }
}

function IdentifierLine({ label, value }) {
  if (!value) return <div className="status-subtle">{`${label}: unavailable`}</div>;
  return (
    <div className="trace-row">
      <span className="status-subtle">{`${label}:`}</span>
      <span className="mono trace-id">{value}</span>
      <button className="button secondary trace-copy-button" onClick={() => copyIdentifier(value)} type="button">
        Copy
      </button>
    </div>
  );
}

function IntentRequestForm({ summary, onControl }) {
  const defaults = summary?.defaults || {};
  const [form, setForm] = useState({
    amount_eure: defaults.amount_eure || '5',
    slippage_bps: String(defaults.slippage_bps ?? 200),
  });

  useEffect(() => {
    setForm({
      amount_eure: defaults.amount_eure || '5',
      slippage_bps: String(defaults.slippage_bps ?? 200),
    });
  }, [defaults.amount_eure, defaults.slippage_bps]);

  async function handlePreflight(event) {
    event.preventDefault();
    await onControl('trade-executor', 'intent-request-preflight', {
      amount_eure: form.amount_eure,
      slippage_bps: Number(form.slippage_bps),
    });
  }

  return (
    <form onSubmit={handlePreflight}>
      <div className="form-grid">
        <div className="field">
          <label htmlFor="intent-request-amount">Spend EURe</label>
          <input
            id="intent-request-amount"
            max={defaults.max_amount_eure || '5'}
            min="0.01"
            name="amount_eure"
            onChange={(event) => setForm((current) => ({ ...current, amount_eure: event.target.value }))}
            step="0.01"
            type="number"
            value={form.amount_eure}
          />
          <div className="status-subtle">{`Max ${defaults.max_amount_eure || '5'} EURe per live test request`}</div>
        </div>
        <div className="field">
          <label htmlFor="intent-request-slippage">Max slippage bps</label>
          <input
            id="intent-request-slippage"
            max={defaults.max_slippage_bps ?? 200}
            min="0"
            name="slippage_bps"
            onChange={(event) => setForm((current) => ({ ...current, slippage_bps: event.target.value }))}
            step="1"
            type="number"
            value={form.slippage_bps}
          />
          <div className="status-subtle">{`Max ${defaults.max_slippage_bps ?? 200} bps / 2%`}</div>
        </div>
      </div>
      <div className="button-row">
        <button className="button" type="submit">Preflight EURe to BTC</button>
        <button
          className="button secondary"
          onClick={() => onControl('trade-executor', 'intent-request-refresh-outcomes')}
          type="button"
        >
          Refresh Request Outcomes
        </button>
      </div>
      <div className="panel-subtitle">Preflight asks solvers for a quote. It does not submit live funds.</div>
    </form>
  );
}

function IntentRequestLifecycle({ item }) {
  return (
    <div className="lifecycle-detail-panel">
      <div className="lifecycle-stage-grid">
        <div className="lifecycle-stage-card">
          <div className="stage-title">1. Request preflight</div>
          <div className="stage-meta">{formatTimestamp(item.created_at)}</div>
          <div className="stage-status">{item.lifecycle?.preflight?.state || item.state}</div>
          <div className="stage-body">
            <div>{item.reason_text}</div>
            <div className="status-subtle mono">{item.reason_code}</div>
          </div>
        </div>
        <div className="lifecycle-stage-card">
          <div className="stage-title">2. Solver quote</div>
          <div className="stage-meta">{formatTimestamp(item.deadline_at)}</div>
          <div className="stage-status">{`${item.solver_quote_count || 0} quote(s)`}</div>
          <div className="stage-body">
            <IdentifierLine label="Quote hash" value={item.quote_hash} />
            <div className="status-subtle">{item.quoted_destination_amount ? `Quoted ${item.quoted_destination_amount} BTC` : 'No usable quote stored'}</div>
          </div>
        </div>
        <div className="lifecycle-stage-card">
          <div className="stage-title">3. Relay submission</div>
          <div className="stage-meta">{formatTimestamp(item.submitted_at)}</div>
          <div className="stage-status">{item.submission_status || 'Not submitted'}</div>
          <div className="stage-body">
            <IdentifierLine label="Submission" value={item.submission_id} />
            <IdentifierLine label="Intent hash" value={item.intent_hash} />
            <div className="status-subtle">Relay acceptance is not a completed trade.</div>
          </div>
        </div>
        <div className="lifecycle-stage-card">
          <div className="stage-title">4. Settlement truth</div>
          <div className="stage-meta">{formatTimestamp(item.resolved_at)}</div>
          <div className="stage-status">{item.outcome_status || item.state}</div>
          <div className="stage-body">
            <div>{item.settlement_summary?.text || 'No settled inventory delta is linked to this request.'}</div>
            {item.settlement_summary?.caveat ? <div className="status-subtle">{item.settlement_summary.caveat}</div> : null}
          </div>
        </div>
      </div>
      <div className="trace-block">
        <IdentifierLine label="Request" value={item.request_id} />
        <IdentifierLine label="Idempotency" value={item.idempotency_key} />
        <IdentifierLine label="Intent" value={item.intent_hash} />
        <IdentifierLine label="Quote hash" value={item.quote_hash} />
      </div>
      <details className="raw-details">
        <summary>Raw lifecycle evidence</summary>
        <pre>{stringifyJson(item.lifecycle)}</pre>
      </details>
    </div>
  );
}

function IntentRequestsTable({ items, executorArmed, onControl }) {
  const [expanded, setExpanded] = useState(() => new Set());
  if (!items?.length) return <EmptyState>No repo-created EURe-to-BTC requests are stored yet.</EmptyState>;

  function toggle(rowKey) {
    setExpanded((current) => {
      const next = new Set(current);
      if (next.has(rowKey)) next.delete(rowKey);
      else next.add(rowKey);
      return next;
    });
  }

  return (
    <TableFrame>
      <table className="intent-requests-table">
        <thead>
          <tr>
            <th>Time</th>
            <th>Request id</th>
            <th>Spend / min receive</th>
            <th>Quote / intent</th>
            <th>State</th>
            <th>Reason</th>
            <th>Settlement</th>
            <th>Action</th>
          </tr>
        </thead>
        <tbody>
          {items.map((item, index) => {
            const rowKey = item.request_id || item.idempotency_key || String(index);
            const isExpanded = expanded.has(rowKey);
            const canSubmit = item.live_submit_capable && executorArmed === true;
            return (
              <Fragment key={rowKey}>
                <tr>
                  <td>{formatTimestamp(item.resolved_at || item.submitted_at || item.created_at)}</td>
                  <td><IdentifierLine label="Request" value={item.request_id} /></td>
                  <td>
                    <div className="mono">{`${item.source_amount} ${item.source_symbol || 'EURe'}`}</div>
                    <div className="status-subtle">{`Min ${item.min_destination_amount} ${item.destination_symbol || 'BTC'}`}</div>
                    <div className="status-subtle">{`${item.slippage_bps ?? 'n/a'} bps slippage`}</div>
                  </td>
                  <td>
                    <IdentifierLine label="Quote" value={item.quote_hash} />
                    <IdentifierLine label="Intent" value={item.intent_hash} />
                  </td>
                  <td><Pill label={item.state_label || item.state} stateLabel={item.state} /></td>
                  <td>
                    <div>{item.reason_text}</div>
                    <div className="status-subtle mono">{item.reason_code}</div>
                  </td>
                  <td>
                    <div>{item.settlement_summary?.text || 'No settled inventory delta linked'}</div>
                    <div className="status-subtle">{item.has_settlement_evidence ? 'Settlement evidence present' : 'Not completed'}</div>
                  </td>
                  <td>
                    <div className="button-row compact">
                      <button className="button secondary" onClick={() => toggle(rowKey)} type="button">
                        {isExpanded ? 'Hide lifecycle' : 'Show lifecycle'}
                      </button>
                      {item.live_submit_capable ? (
                        <button
                          className="button"
                          disabled={!canSubmit}
                          onClick={() => onControl('trade-executor', 'intent-request-submit', { request_id: item.request_id })}
                          type="button"
                        >
                          Submit live
                        </button>
                      ) : null}
                    </div>
                    {item.live_submit_capable && executorArmed !== true ? (
                      <div className="status-subtle">Executor must be armed before live submit.</div>
                    ) : null}
                  </td>
                </tr>
                {isExpanded ? (
                  <tr className="lifecycle-expanded-row">
                    <td colSpan={8}><IntentRequestLifecycle item={item} /></td>
                  </tr>
                ) : null}
              </Fragment>
            );
          })}
        </tbody>
      </table>
    </TableFrame>
  );
}


function LastControlResult({ result }) {
  if (!result) return null;

  return (
    <TableFrame style={{ marginTop: 14 }}>
      <table>
        <tbody>
          <tr>
            <td><strong>Last control result</strong></td>
            <td className="mono"><pre>{stringifyJson(result)}</pre></td>
          </tr>
        </tbody>
      </table>
    </TableFrame>
  );
}

export default function FundsPage({
  funds,
  onControl,
  lastControlResult,
}) {
  const profitability = funds.profitability;
  const controlState = funds.funding.control_state || {};
  const externalFlowAdjusted = profitability.external_flow_adjusted;
  const externalFlowCount = profitability.external_flow_count || 0;
  const baselineLabel = externalFlowAdjusted ? 'PnL vs net funded capital' : 'PnL vs deposit baseline';
  const baselineMeta = externalFlowAdjusted
    ? `Adjusted for ${externalFlowCount} later deposit or withdrawal flows`
    : 'Baseline anchored before first live trade';
  const simpleHoldMeta = externalFlowAdjusted
    ? 'Simple hold includes later credited deposits and completed withdrawals'
    : 'Comparison against a no-trade simple-hold baseline';
  const marketMoveMeta = externalFlowAdjusted
    ? 'Simple-hold market move on baseline plus later external flows'
    : 'Baseline mark move only';
  const portfolioVsHoldMeta = externalFlowAdjusted
    ? 'Current minus cash-flow-adjusted simple hold; not realized trade PnL'
    : 'Current minus simple hold; not realized trade PnL';

  return (
    <>
      <section className="panel">
        <div className="panel-head">
          <div>
            <div className="eyebrow">Default view</div>
            <h2>Funds</h2>
            <div className="panel-subtitle">
              Profitability comes first. Spendable inventory remains verifier or bridge credit only,
              while pre-credit funding stays separate.
            </div>
          </div>
          <div className="pills">
            <Pill
              label={`Withdrawals ${controlState.withdrawals_frozen ? 'Frozen' : 'Unfrozen'}`}
              stateLabel={controlState.withdrawals_frozen ? 'frozen' : 'healthy'}
            />
            <Pill
              label={`Funding observer ${controlState.funding_observer_paused ? 'Paused' : 'Running'}`}
              stateLabel={controlState.funding_observer_paused ? 'paused' : 'healthy'}
            />
          </div>
        </div>
        <div className="stack-grid">
          <MetricCard
            hero
            label="Current EUR value"
            meta={
              profitability.computed_at
                ? `Latest durable snapshot ${formatTimestamp(profitability.computed_at)}`
                : 'Latest durable profitability snapshot'
            }
            value={formatEur(profitability.current_total_portfolio_value_eure)}
          />
          <MetricCard
            label={baselineLabel}
            meta={baselineMeta}
            signedValue={profitability.pnl_vs_deposit_baseline_eure}
            value={formatEur(profitability.pnl_vs_deposit_baseline_eure)}
          />
          <MetricCard
            label="PnL vs simple hold"
            meta={simpleHoldMeta}
            signedValue={profitability.pnl_vs_simple_hold_eure}
            value={formatEur(profitability.pnl_vs_simple_hold_eure)}
          />
          <MetricCard
            label="Market move"
            meta={marketMoveMeta}
            signedValue={profitability.market_move_contribution_eure}
            value={formatEur(profitability.market_move_contribution_eure)}
          />
          <MetricCard
            label="Portfolio vs simple hold"
            meta={portfolioVsHoldMeta}
            signedValue={profitability.portfolio_vs_simple_hold_eure}
            value={formatEur(profitability.portfolio_vs_simple_hold_eure)}
          />
        </div>
        <div className="panel-subtitle">
          {profitability.caveats.map((item) => (
            <div key={item}>{item}</div>
          ))}
        </div>
      </section>

      <section className="stack-grid">
        <div className="panel">
          <div className="panel-head">
            <div>
              <div className="eyebrow">Current balances</div>
              <h3>Spendable and pending</h3>
            </div>
            <div className="status-subtle">{`Inventory synced ${formatTimestamp(funds.balances.synced_at)}`}</div>
          </div>
          <BalancesTable items={funds.balances.items} />
        </div>
        <div className="panel">
          <div className="panel-head">
            <div>
              <div className="eyebrow">Operator controls</div>
              <h3>Safe actions</h3>
            </div>
          </div>
          <div className="button-row">
            <button className="button secondary" onClick={() => onControl('market-reference-ingest', 'refresh')} type="button">Refresh Price</button>
            <button className="button secondary" onClick={() => onControl('inventory-sync', 'refresh')} type="button">Refresh Inventory</button>
            <button className="button secondary" onClick={() => onControl('liquidity-manager', 'refresh')} type="button">Refresh Liquidity</button>
            <button
              className="button secondary"
              disabled={controlState.funding_observer_paused}
              onClick={() => onControl('liquidity-manager', 'pause-funding-observer')}
              type="button"
            >
              Pause Funding Observer
            </button>
            <button
              className="button secondary"
              disabled={!controlState.funding_observer_paused}
              onClick={() => onControl('liquidity-manager', 'resume-funding-observer')}
              type="button"
            >
              Resume Funding Observer
            </button>
            <button
              className="button secondary"
              disabled={controlState.withdrawals_frozen}
              onClick={() => onControl('liquidity-manager', 'freeze-withdrawals', { frozen: true })}
              type="button"
            >
              Freeze Withdrawals
            </button>
            <button
              className="button secondary"
              disabled={!controlState.withdrawals_frozen}
              onClick={() => onControl('liquidity-manager', 'freeze-withdrawals', { frozen: false })}
              type="button"
            >
              Unfreeze Withdrawals
            </button>
          </div>
          <div className="panel-subtitle">
            Risky treasury submit paths remain absent. Strategy and executor arm or disarm remain absent.
          </div>
          <WithdrawalEstimateForm
            balances={funds.balances.items}
            onControl={onControl}
            withdrawalDefaults={controlState.withdrawal_defaults || {}}
          />
          <LastControlResult result={lastControlResult} />
        </div>
      </section>

      <section className="panel full-width-evidence-panel">
        <div className="panel-head">
          <div>
            <div className="eyebrow">Own requests</div>
            <h3>EURe to BTC request creation</h3>
            <div className="panel-subtitle">Create a solver quote request first, then submit only a drafted request. Completed requires inventory movement, not relay acceptance.</div>
          </div>
          <div className="pills">
            <Pill label={`Executor ${funds.intent_requests?.executor_armed ? 'Armed' : 'Disarmed'}`} stateLabel={funds.intent_requests?.executor_armed ? 'healthy' : 'warning'} />
          </div>
        </div>
        <IntentRequestForm onControl={onControl} summary={funds.intent_requests} />
        <div className="panel-subtitle">{funds.intent_requests?.caveat}</div>
        <IntentRequestsTable
          executorArmed={funds.intent_requests?.executor_armed}
          items={funds.intent_requests?.items || []}
          onControl={onControl}
        />
      </section>

      <section className="stack-grid">
        <div className="panel">
          <div className="panel-head">
            <div>
              <div className="eyebrow">Funding handles</div>
              <h3>Credited and pre-credit funding</h3>
            </div>
          </div>
          <HandlesList handles={funds.funding.handles} />
          <h3 style={{ marginTop: 18 }}>Credited deposits</h3>
          <FundingTable creditedOnly items={funds.funding.credited_deposits} />
          <h3 style={{ marginTop: 18 }}>Pre-credit by asset</h3>
          <PreCreditAssetTable items={funds.funding.pre_credit_by_asset} />
        </div>

        <div className="panel">
          <div className="panel-head">
            <div>
              <div className="eyebrow">Transfer history</div>
              <h3>Withdrawals and observations</h3>
            </div>
          </div>
          <h3>Recent withdrawals</h3>
          <WithdrawalsTable items={funds.recent_withdrawals} />
          <h3 style={{ marginTop: 18 }}>Recent funding observations</h3>
          <FundingTable items={funds.funding.recent_observations} />
        </div>
      </section>
    </>
  );
}
