import { useEffect, useMemo, useReducer, useRef, useState } from 'react';
import type { ChangeEvent, FormEvent } from 'react';
import { Pencil, RefreshCw, Trash2 } from 'lucide-react';
import { useSearchParams } from 'react-router-dom';
import { useAppContext } from '../context/AppContext';
import { fetchChartBars, fetchResearchProfile } from '../lib/marketApi';
import {
  createManualEntry,
  deleteManualEntry,
  fetchManualEntries,
  updateManualEntry,
  type ManualEntryPayload,
} from '../lib/manualEntriesApi';
import { fetchTradeProfiles, type TradeProfilePayload } from '../lib/profileApi';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../components/ui/card';
import { PageHeader } from '../components/ui/page-header';
import { Button, Input, Select } from '../components/ui/Primitives';
import {
  DEFAULT_TRADE_PLANS_UI_STATE,
  reduceTradePlansUiState,
  type MarketPriceSource,
  type SimpleSetupDraft,
  type SimpleSide,
  type TriggerMode,
} from './tradePlansState';
import { useTradePlansNavigationState } from './useTradePlansNavigationState';

type SimpleHolding = {
  symbol: string;
  size: number;
  entryPrice: number;
  profileId?: string;
  tradeId?: string;
};

type SimpleRuntimeSnapshot = {
  stage: 'armed' | 'entry_submitted' | 'filled' | 'exit_submitted' | 'closed' | 'unknown';
  label: string;
  tone: 'neutral' | 'info' | 'success';
  tradeId?: string;
  orderId?: string;
};

type SimpleOperationalEvent = NonNullable<ReturnType<typeof useAppContext>['botState']['operationalEvents']>[number];

const SIMPLE_AUTO_PROFILE_NAME = 'Simple Auto Profile';
const SIMPLE_AUTO_PROFILE_KEY = SIMPLE_AUTO_PROFILE_NAME.toLowerCase();
const SIMPLE_SYMBOL_DATALIST_ID = 'simple-supported-symbols';
const COMMON_SIMPLE_SYMBOLS = [
  'AAPL',
  'MSFT',
  'NVDA',
  'TSLA',
  'SPY',
  'QQQ',
  'AMZN',
  'META',
  'BTC/USD',
  'ETH/USD',
  'SOL/USD',
];

function parsePositiveNumber(value: string): number | null {
  const trimmed = value.trim();
  if (!trimmed) return null;
  const parsed = Number(trimmed);
  return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
}

function parseNonNegativeNumber(value: string): number | null {
  const trimmed = value.trim();
  if (!trimmed) return null;
  const parsed = Number(trimmed);
  return Number.isFinite(parsed) && parsed >= 0 ? parsed : null;
}

function roundPrice(value: number): number {
  return Number(value.toFixed(4));
}

function matchesSimpleAutoProfile(profile: Pick<TradeProfilePayload, 'name'> | null | undefined) {
  return String(profile?.name || '').trim().toLowerCase() === SIMPLE_AUTO_PROFILE_KEY;
}

function normalizeSetupSide(value: unknown): SimpleSide {
  return String(value || '').trim().toLowerCase() === 'sell' ? 'sell' : 'buy';
}

function normalizeMode(value: unknown, fallback: TriggerMode = 'percent'): TriggerMode {
  return String(value || '').trim().toLowerCase() === 'dollar' ? 'dollar' : fallback;
}

function normalizeHoldingMode(value: unknown): 'short_term' | 'long_term' {
  return String(value || '').trim().toLowerCase() === 'long_term' ? 'long_term' : 'short_term';
}

function normalizeAutomationState(value: unknown, entry: ManualEntryPayload): string {
  const explicit = String(value || '').trim().toLowerCase();
  if (explicit) return explicit;
  const status = String(entry.status || '').trim().toLowerCase();
  const holdingMode = normalizeHoldingMode(entry.holding_mode);
  if (holdingMode === 'long_term') {
    return status === 'sellcompleted' ? 'closed' : 'paused_long_term';
  }
  switch (status) {
    case 'simple_armed_buy':
    case 'simple_armed_sell':
      return 'armed';
    case 'simple_entry_submitted':
      return 'entry_submitted';
    case 'simple_bought':
      return 'holding_managed';
    case 'simple_exit_submitted':
      return 'exit_submitted';
    case 'sellcompleted':
      return 'closed';
    default:
      return 'unknown';
  }
}

function computeBuyTriggerPrice(draft: SimpleSetupDraft): number | null {
  const currentMarketPrice = parsePositiveNumber(draft.currentMarketPrice);
  const dropValue = parseNonNegativeNumber(draft.dropValue);
  if (!currentMarketPrice || dropValue === null) return null;

  if (draft.dropMode === 'dollar') {
    const trigger = currentMarketPrice - dropValue;
    return trigger > 0 ? roundPrice(trigger) : null;
  }

  const trigger = currentMarketPrice * (1 - dropValue / 100);
  return trigger > 0 ? roundPrice(trigger) : null;
}

function computeProfitTargetPrice(entryPrice: number | null, mode: TriggerMode, value: string): number | null {
  const numericEntryPrice = entryPrice && entryPrice > 0 ? entryPrice : null;
  const targetValue = parsePositiveNumber(value);
  if (!numericEntryPrice || !targetValue) return null;

  if (mode === 'dollar') {
    return roundPrice(numericEntryPrice + targetValue);
  }

  return roundPrice(numericEntryPrice * (1 + targetValue / 100));
}

export function buildSimpleSetupPayload(input: {
  draft: SimpleSetupDraft;
  existingId?: string;
  holding?: SimpleHolding | null;
  existingEntry?: ManualEntryPayload | null;
}): ManualEntryPayload {
  const symbol = input.draft.symbol.trim().toUpperCase();
  if (!symbol) {
    throw new Error('Symbol is required');
  }

  const currentMarketPrice = parsePositiveNumber(input.draft.currentMarketPrice);
  if (!currentMarketPrice) {
    throw new Error('No recent market price is available right now. The app uses live price when available, otherwise the latest close.');
  }

  const quantity = parsePositiveNumber(input.draft.quantity);
  const amountUsd = parsePositiveNumber(input.draft.amountUsd);

  const profitValue = parsePositiveNumber(input.draft.profitValue);
  if (!profitValue) {
    throw new Error('Profit target is required');
  }

  const side = input.draft.side;
  const holding = input.holding || null;
  const existingEntry = input.existingEntry || null;
  const holdingMode = normalizeHoldingMode(existingEntry?.holding_mode);
  const automationState = normalizeAutomationState(existingEntry?.automation_state, existingEntry || { status: side === 'buy' ? 'simple_armed_buy' : 'simple_armed_sell' } as ManualEntryPayload);

  if (side === 'sell' && !holding) {
    throw new Error('Sell setups require an existing holding for this symbol.');
  }

  if (side === 'buy' && parseNonNegativeNumber(input.draft.dropValue) === null) {
    throw new Error('Drop trigger is required for buy setups');
  }

  if (side === 'buy') {
    if (input.draft.sizingMode === 'amount') {
      if (!amountUsd) {
        throw new Error('USD amount is required');
      }
    } else if (!quantity) {
      throw new Error('Quantity is required');
    }
  }

  return {
    stock_instance_id: input.existingId,
    symbol,
    active: true,
    status: side === 'buy' ? 'simple_armed_buy' : 'simple_armed_sell',
    is_crypto: false,
    is_real_trade: false,
    label: 'Simple',
    quantity: side === 'sell' ? holding!.size : (input.draft.sizingMode === 'quantity' ? quantity : null),
    amount_usd: side === 'buy' && input.draft.sizingMode === 'amount' ? amountUsd : null,
    sizing_mode: side === 'buy' ? input.draft.sizingMode : 'quantity',
    filled_quantity: side === 'sell' ? holding!.size : null,
    notes: input.draft.notes.trim() || null,
    entry_price: side === 'sell' ? holding!.entryPrice : null,
    reference_price: currentMarketPrice,
    gain_threshold_for_sell: profitValue,
    drop_threshold_for_buy: side === 'buy' ? parseNonNegativeNumber(input.draft.dropValue) : null,
    workflow_type: 'simple',
    simple_side: side,
    drop_trigger_mode: side === 'buy' ? input.draft.dropMode : null,
    profit_target_mode: input.draft.profitMode,
    linked_trade_id: side === 'sell' ? holding!.tradeId || null : null,
    profile_id: side === 'sell' ? holding!.profileId || null : null,
    holding_mode: existingEntry ? holdingMode : 'short_term',
    automation_state: existingEntry ? automationState : 'armed',
    buy_price: null,
    sell_price: null,
    buy_time: null,
    sell_time: null,
  };
}

function buildPreviewText(draft: SimpleSetupDraft, holding: SimpleHolding | null): string | null {
  const symbol = draft.symbol.trim().toUpperCase();
  if (!symbol) return null;

  if (draft.side === 'buy') {
    const triggerPrice = computeBuyTriggerPrice(draft);
    const profitTargetPrice = computeProfitTargetPrice(triggerPrice, draft.profitMode, draft.profitValue);
    if (!triggerPrice) return `Buy ${symbol} after the configured drop trigger is hit.`;

    const dropMagnitude = parseNonNegativeNumber(draft.dropValue);
    const isImmediate = dropMagnitude === 0;
    const dropText = isImmediate
      ? 'at the current market reference'
      : draft.dropMode === 'dollar'
        ? `$${Number(draft.dropValue || 0).toFixed(2)} below current price`
        : `${draft.dropValue || '0'}% below current price`;
    const profitText = draft.profitMode === 'dollar'
      ? `$${Number(draft.profitValue || 0).toFixed(2)} above purchase`
      : `${draft.profitValue || '0'}% above purchase`;
    const sizeText = draft.sizingMode === 'amount'
      ? `Spend $${Number(draft.amountUsd || 0).toFixed(2)}`
      : `Buy ${draft.quantity || '0'} units`;

    return [
      `${sizeText} of ${symbol} when price reaches ${triggerPrice.toFixed(4)} (${dropText}).`,
      profitTargetPrice ? `Exit target stays armed at ${profitTargetPrice.toFixed(4)} (${profitText}).` : `Exit target uses ${profitText}.`,
    ].join(' ');
  }

  if (!holding) {
    return `Sell ${symbol} only works when an eligible existing holding is available.`;
  }

  const profitTargetPrice = computeProfitTargetPrice(holding.entryPrice, draft.profitMode, draft.profitValue);
  const profitText = draft.profitMode === 'dollar'
    ? `$${Number(draft.profitValue || 0).toFixed(2)} above purchase`
    : `${draft.profitValue || '0'}% above purchase`;
  if (!profitTargetPrice) {
    return `Exit ${symbol} when the configured profit target is hit (${profitText}).`;
  }

  return `Exit ${symbol} when price reaches ${profitTargetPrice.toFixed(4)} (${profitText}).`;
}

function deriveRuntimeSnapshot(
  entry: ManualEntryPayload,
  orders: Array<Record<string, any>>,
  holdings: SimpleHolding[],
): SimpleRuntimeSnapshot | null {
  const linkedTradeId = String(entry.linked_trade_id || '').trim();
  if (linkedTradeId) {
    const matchingOrder = orders.find((order) => String(order?.trade_id || order?.tradeId || '').trim() === linkedTradeId);
    if (matchingOrder) {
      const status = String(matchingOrder.status || '').trim().toLowerCase();
      const action = String(matchingOrder.action || '').trim().toUpperCase();
      const orderId = String(matchingOrder.orderId || matchingOrder.order_id || matchingOrder.id || '').trim() || undefined;
      if (action === 'EXIT') {
        if (status === 'filled') {
          return { stage: 'closed', label: 'Exit filled', tone: 'success', tradeId: linkedTradeId, orderId };
        }
        return { stage: 'exit_submitted', label: `Exit ${status || 'submitted'}`, tone: 'info', tradeId: linkedTradeId, orderId };
      }
      if (status === 'filled') {
        return { stage: 'filled', label: 'Entry filled', tone: 'success', tradeId: linkedTradeId, orderId };
      }
      return { stage: 'entry_submitted', label: `Entry ${status || 'submitted'}`, tone: 'info', tradeId: linkedTradeId, orderId };
    }
  }

  const symbol = String(entry.symbol || '').trim().toUpperCase();
  const side = normalizeSetupSide(entry.simple_side);
  const matchingHolding = holdings.find((holding) => holding.symbol === symbol && (!linkedTradeId || holding.tradeId === linkedTradeId || !holding.tradeId));
  if (side === 'buy' && matchingHolding) {
    return {
      stage: 'filled',
      label: 'Portfolio holding open',
      tone: 'success',
      tradeId: matchingHolding.tradeId || linkedTradeId || undefined,
    };
  }
  if (String(entry.status || '').trim().toLowerCase() === 'sellcompleted') {
    return { stage: 'closed', label: 'Position closed', tone: 'success', tradeId: linkedTradeId || undefined };
  }
  return null;
}

function buildDraftFromEntry(entry: ManualEntryPayload): SimpleSetupDraft {
  return {
    symbol: String(entry.symbol || '').trim().toUpperCase(),
    side: normalizeSetupSide(entry.simple_side),
    sizingMode: String(entry.sizing_mode || '').trim().toLowerCase() === 'amount' ? 'amount' : 'quantity',
    quantity: entry.quantity ? String(entry.quantity) : '',
    amountUsd: entry.amount_usd ? String(entry.amount_usd) : '',
    currentMarketPrice: entry.reference_price ? Number(entry.reference_price).toFixed(4) : '',
    dropMode: normalizeMode(entry.drop_trigger_mode, 'percent'),
    dropValue: entry.drop_threshold_for_buy !== null && entry.drop_threshold_for_buy !== undefined ? String(entry.drop_threshold_for_buy) : '',
    profitMode: normalizeMode(entry.profit_target_mode, 'percent'),
    profitValue: entry.gain_threshold_for_sell !== null && entry.gain_threshold_for_sell !== undefined ? String(entry.gain_threshold_for_sell) : '',
    notes: String(entry.notes || ''),
  };
}

function inferMarketPriceSourceFromEntry(entry: ManualEntryPayload): MarketPriceSource {
  return entry.reference_price ? 'reference_price' : null;
}

function formatSetupStatus(status?: string | null): string {
  const normalized = String(status || '').trim().toLowerCase();
  switch (normalized) {
    case 'simple_armed_buy':
      return 'Buy armed';
    case 'simple_entry_submitted':
      return 'Buy submitted';
    case 'simple_bought':
      return 'Holding';
    case 'simple_armed_sell':
      return 'Sell armed';
    case 'simple_exit_submitted':
      return 'Exit submitted';
    case 'sellcompleted':
      return 'Closed';
    default:
      return normalized || 'Unknown';
  }
}

function formatHoldingMode(mode?: string | null): string {
  return normalizeHoldingMode(mode) === 'long_term' ? 'Long-term' : 'Short-term';
}

function formatAutomationState(entry: ManualEntryPayload): string {
  const state = normalizeAutomationState(entry.automation_state, entry);
  switch (state) {
    case 'armed':
      return 'Automation armed';
    case 'entry_submitted':
      return 'Entry syncing';
    case 'holding_managed':
      return 'Exit managed';
    case 'paused_long_term':
      return 'Automation paused';
    case 'exit_submitted':
      return 'Exit syncing';
    case 'closed':
      return 'Closed';
    default:
      return 'State syncing';
  }
}

function statusToneClasses(tone: SimpleRuntimeSnapshot['tone']): string {
  switch (tone) {
    case 'success':
      return 'border-emerald-500/30 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300';
    case 'info':
      return 'border-sky-500/30 bg-sky-500/10 text-sky-700 dark:text-sky-300';
    default:
      return 'border-[var(--border)] text-[var(--muted-foreground)]';
  }
}

const SIMPLE_TIMELINE_STEPS: Array<SimpleRuntimeSnapshot['stage']> = [
  'armed',
  'entry_submitted',
  'filled',
  'exit_submitted',
  'closed',
];

function isTimelineStepComplete(
  current: SimpleRuntimeSnapshot['stage'] | undefined,
  step: SimpleRuntimeSnapshot['stage'],
): boolean {
  if (!current) return false;
  const currentIndex = SIMPLE_TIMELINE_STEPS.indexOf(current);
  const stepIndex = SIMPLE_TIMELINE_STEPS.indexOf(step);
  return currentIndex >= 0 && stepIndex >= 0 && stepIndex <= currentIndex;
}

function formatTimelineStepLabel(step: SimpleRuntimeSnapshot['stage']) {
  switch (step) {
    case 'armed':
      return 'Armed';
    case 'entry_submitted':
      return 'Entry sent';
    case 'filled':
      return 'Filled';
    case 'exit_submitted':
      return 'Exit sent';
    case 'closed':
      return 'Closed';
    default:
      return step;
  }
}

function describeNextAction(
  entry: ManualEntryPayload,
  runtimeSnapshot: SimpleRuntimeSnapshot | null,
): string {
  const side = normalizeSetupSide(entry.simple_side);
  const symbol = String(entry.symbol || '').trim().toUpperCase() || 'This symbol';

  if (!runtimeSnapshot) {
    if (normalizeHoldingMode(entry.holding_mode) === 'long_term') {
      return `${symbol} is being kept as a long-term hold. Automated exit monitoring is paused until you resume it.`;
    }
    return side === 'buy'
      ? `${symbol} is saved and waiting for the configured buy trigger.`
      : `${symbol} is saved and waiting for an eligible holding to manage.`;
  }

  if (normalizeHoldingMode(entry.holding_mode) === 'long_term' && runtimeSnapshot.stage === 'filled') {
    return `${symbol} is held as a long-term position. No automated profit exit is currently armed.`;
  }

  switch (runtimeSnapshot.stage) {
    case 'armed':
      return side === 'buy'
        ? `${symbol} is waiting for the configured drop trigger before sending an entry order.`
        : `${symbol} is waiting for the configured profit exit trigger.`;
    case 'entry_submitted':
      return `${symbol} entry order has been submitted and is waiting for exchange fill confirmation.`;
    case 'filled':
      return `${symbol} entry is filled. The setup is now monitoring for the configured profit exit.`;
    case 'exit_submitted':
      return `${symbol} exit order has been submitted and is waiting for exchange fill confirmation.`;
    case 'closed':
      return `${symbol} setup is complete. The linked position has been closed.`;
    default:
      return `${symbol} runtime state is syncing.`;
  }
}

function formatSetupUpdatedAt(entry: ManualEntryPayload): string | null {
  const raw = String(entry.sell_time || entry.buy_time || '').trim();
  if (!raw) return null;
  const parsed = new Date(raw);
  if (Number.isNaN(parsed.getTime())) return null;
  return parsed.toLocaleString();
}

function formatEventTimestamp(timestamp?: number): string | null {
  if (!timestamp || !Number.isFinite(timestamp)) return null;
  const parsed = new Date(timestamp);
  if (Number.isNaN(parsed.getTime())) return null;
  return parsed.toLocaleString();
}

function deriveSimpleEventHistory(
  entry: ManualEntryPayload,
  operationalEvents: SimpleOperationalEvent[],
): SimpleOperationalEvent[] {
  const setupId = String(entry.stock_instance_id || '').trim();
  const tradeId = String(entry.linked_trade_id || '').trim();
  const symbol = String(entry.symbol || '').trim().toUpperCase();

  return operationalEvents
    .filter((event): event is SimpleOperationalEvent => Boolean(event) && event.type === 'SIMPLE_SETUP_UPDATE')
    .filter((event) => {
      const eventSetupId = String(event.setupId || '').trim();
      const eventTradeId = String(event.tradeId || '').trim();
      const eventSymbol = String(event.symbol || '').trim().toUpperCase();
      if (setupId && eventSetupId === setupId) return true;
      if (tradeId && eventTradeId === tradeId) return true;
      return !setupId && !tradeId && !!symbol && eventSymbol === symbol;
    })
    .sort((left, right) => right.timestamp - left.timestamp)
    .slice(0, 5);
}

function eventSeverityClasses(severity?: string) {
  const normalized = String(severity || '').trim().toUpperCase();
  if (normalized === 'ERROR') {
    return 'border-red-500/30 bg-red-500/10 text-red-700 dark:text-red-300';
  }
  if (normalized === 'WARN') {
    return 'border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-300';
  }
  return 'border-sky-500/30 bg-sky-500/10 text-sky-700 dark:text-sky-300';
}

function normalizeSimpleEntries(entries: ManualEntryPayload[]): ManualEntryPayload[] {
  return entries
    .filter((entry) => String(entry.workflow_type || '').trim().toLowerCase() === 'simple')
    .sort((left, right) => {
      const leftTimestamp = new Date(String(left.sell_time || left.buy_time || '')).getTime() || 0;
      const rightTimestamp = new Date(String(right.sell_time || right.buy_time || '')).getTime() || 0;
      return rightTimestamp - leftTimestamp;
    });
}

function normalizeKnownSymbol(value: unknown): string | null {
  const normalized = String(value || '').trim().toUpperCase();
  return normalized ? normalized : null;
}

function normalizeRuntimeArray<T>(value: unknown): T[] {
  if (Array.isArray(value)) return value as T[];
  if (value && typeof value === 'object' && Symbol.iterator in (value as object)) {
    try {
      return Array.from(value as Iterable<T>);
    } catch {
      return [];
    }
  }
  return [];
}

function isLikelySymbolCandidate(symbol: string): boolean {
  return /^[A-Z0-9./-]{1,20}$/.test(symbol);
}

function extractReferencePriceFromResearchProfile(profile: any): number | null {
  const candidates = [
    profile?.price,
    profile?.lastPrice,
    profile?.currentPrice,
    profile?.previousClose,
    profile?.prevClose,
  ];

  for (const candidate of candidates) {
    const value = Number(candidate);
    if (Number.isFinite(value) && value > 0) return value;
  }

  return null;
}

function describeSavedSetup(entry: ManualEntryPayload): string {
  const side = normalizeSetupSide(entry.simple_side);
  const symbol = String(entry.symbol || '').trim().toUpperCase();
  const dropValue = Number(entry.drop_threshold_for_buy || 0);
  const profitValue = Number(entry.gain_threshold_for_sell || 0);
  const dropMode = normalizeMode(entry.drop_trigger_mode, 'percent');
  const profitMode = normalizeMode(entry.profit_target_mode, 'percent');
  const referencePrice = Number(entry.reference_price || 0);
  const entryPrice = Number(entry.entry_price || 0);
  const sizingMode = String(entry.sizing_mode || 'quantity').trim().toLowerCase();
  const sizeText = sizingMode === 'amount'
    ? `$${Number(entry.amount_usd || 0).toFixed(2)} budget`
    : `${Number(entry.quantity || 0).toFixed(6).replace(/\.?0+$/, '')} units`;

  if (side === 'buy') {
    const triggerPrice = computeBuyTriggerPrice(buildDraftFromEntry(entry));
    const dropText = dropValue === 0
      ? 'at current reference'
      : dropMode === 'dollar'
        ? `$${dropValue.toFixed(2)} below`
        : `${dropValue}% below`;
    const profitText = profitMode === 'dollar'
      ? `$${profitValue.toFixed(2)} above purchase`
      : `${profitValue}% above purchase`;
    return `Buy ${symbol} using ${sizeText} ${dropText} ${referencePrice > 0 ? `(${referencePrice.toFixed(4)} ref` : ''}${triggerPrice ? ` → ${triggerPrice.toFixed(4)}` : ''}). Exit at ${profitText}.`;
  }

  const profitTargetPrice = computeProfitTargetPrice(entryPrice || null, profitMode, String(profitValue || ''));
  const profitText = profitMode === 'dollar'
    ? `$${profitValue.toFixed(2)} above purchase`
    : `${profitValue}% above purchase`;
  return `Exit full ${symbol} holding at ${profitText}${profitTargetPrice ? ` (${profitTargetPrice.toFixed(4)})` : ''}.`;
}

export function SimpleView() {
  const { botState } = useAppContext();
  const [searchParams, setSearchParams] = useSearchParams();
  const [profiles, setProfiles] = useState<TradeProfilePayload[]>([]);
  const [savedSetups, setSavedSetups] = useState<ManualEntryPayload[]>([]);
  const [uiState, dispatch] = useReducer(reduceTradePlansUiState, DEFAULT_TRADE_PLANS_UI_STATE);
  const [submitting, setSubmitting] = useState(false);
  const [loadingPrice, setLoadingPrice] = useState(false);
  const marketPriceRequestSymbolRef = useRef<string>('');
  const setupCardRefs = useRef<Record<string, HTMLDivElement | null>>({});

  const {
    editingSetupId,
    draft,
    marketPriceSource,
    copiedKey,
    message,
    error,
    selectedHoldingTradeId,
    focusedSetupId,
  } = uiState;

  const normalizedSymbol = draft.symbol.trim().toUpperCase();
  const symbolState = botState?.symbols && typeof botState.symbols === 'object' ? botState.symbols : {};
  const livePrice = normalizedSymbol ? Number(symbolState?.[normalizedSymbol]?.price || 0) : 0;
  const simpleAutoProfile = useMemo(
    () => profiles.find((profile) => matchesSimpleAutoProfile(profile)) || null,
    [profiles],
  );

  const simpleHoldings = useMemo(() => {
    const positions = normalizeRuntimeArray<typeof botState.positions[number]>(botState?.positions);
    const simpleProfileId = simpleAutoProfile?.id;
    return positions
      .filter((position) => !simpleProfileId || position.profileId === simpleProfileId)
      .map((position) => ({
        symbol: String(position.symbol || '').trim().toUpperCase(),
        size: Number(position.size || 0),
        entryPrice: Number(position.entryPrice || 0),
        profileId: position.profileId,
        tradeId: position.tradeId,
      }))
      .filter((position) => position.symbol && position.size > 0 && position.entryPrice > 0);
  }, [botState?.positions, simpleAutoProfile?.id]);

  const availableSellHoldings = useMemo(() => {
    const positions = normalizeRuntimeArray<typeof botState.positions[number]>(botState?.positions);
    return positions
      .map((position) => ({
        symbol: String(position.symbol || '').trim().toUpperCase(),
        size: Number(position.size || 0),
        entryPrice: Number(position.entryPrice || 0),
        profileId: position.profileId,
        tradeId: position.tradeId,
      }))
      .filter((position) => position.symbol && position.size > 0 && position.entryPrice > 0 && position.profileId && position.tradeId)
      .sort((left, right) => {
        const bySymbol = left.symbol.localeCompare(right.symbol);
        if (bySymbol !== 0) return bySymbol;
        return String(left.tradeId || '').localeCompare(String(right.tradeId || ''));
      });
  }, [botState?.positions]);

  const runtimeOrders = useMemo(() => {
    const orders = normalizeRuntimeArray<Record<string, any>>(botState?.orders);
    return orders.filter((order) => {
      if (!simpleAutoProfile?.id) return true;
      return String(order.profileId || '').trim() === simpleAutoProfile.id;
    });
  }, [botState?.orders, simpleAutoProfile?.id]);
  const runtimeEvents = useMemo(
    () => normalizeRuntimeArray<SimpleOperationalEvent>(botState?.operationalEvents),
    [botState?.operationalEvents],
  );

  const selectedSellHolding = useMemo(() => {
    if (selectedHoldingTradeId) {
      return availableSellHoldings.find((holding) => holding.tradeId === selectedHoldingTradeId) || null;
    }
    return availableSellHoldings.find((holding) => holding.symbol === normalizedSymbol) || null;
  }, [availableSellHoldings, normalizedSymbol, selectedHoldingTradeId]);

  const supportedSymbols = useMemo(() => {
    const fromState = Object.keys(symbolState || {}).map(normalizeKnownSymbol).filter(Boolean) as string[];
    const fromSetups = savedSetups.map((entry) => normalizeKnownSymbol(entry.symbol)).filter(Boolean) as string[];
    const fromHoldings = availableSellHoldings.map((holding) => normalizeKnownSymbol(holding.symbol)).filter(Boolean) as string[];
    return Array.from(new Set([...fromState, ...fromSetups, ...fromHoldings, ...COMMON_SIMPLE_SYMBOLS])).sort((left, right) => left.localeCompare(right));
  }, [symbolState, savedSetups, availableSellHoldings]);

  const filteredSymbolSuggestions = useMemo(() => {
    if (!normalizedSymbol) {
      return supportedSymbols.slice(0, 8);
    }
    const startsWith = supportedSymbols.filter((symbol) => symbol.startsWith(normalizedSymbol));
    const includes = supportedSymbols.filter((symbol) => !symbol.startsWith(normalizedSymbol) && symbol.includes(normalizedSymbol));
    return [...startsWith, ...includes].slice(0, 8);
  }, [normalizedSymbol, supportedSymbols]);

  const isSuggestedSymbol = normalizedSymbol ? supportedSymbols.includes(normalizedSymbol) : false;

  useEffect(() => {
    let cancelled = false;

    async function loadData() {
      try {
        const [profileRows, entryRows] = await Promise.all([
          fetchTradeProfiles(),
          fetchManualEntries(),
        ]);
        if (cancelled) return;
        setProfiles(profileRows);
        setSavedSetups(normalizeSimpleEntries(entryRows));
      } catch (err: any) {
        if (cancelled) return;
        dispatch({ type: 'set-error', value: err?.message ?? 'Failed to load Trade Plans' });
      }
    }

    void loadData();
    return () => {
      cancelled = true;
    };
  }, []);

  useEffect(() => {
    if (!livePrice) return;
    dispatch({ type: 'set-market-price-source', value: 'live' });
    if (draft.currentMarketPrice !== livePrice.toFixed(4)) {
      dispatch({ type: 'set-draft-field', key: 'currentMarketPrice', value: livePrice.toFixed(4) });
    }
  }, [livePrice]);

  useEffect(() => {
    if (!normalizedSymbol || livePrice > 0 || draft.currentMarketPrice.trim() || loadingPrice) {
      return;
    }

    if (!isLikelySymbolCandidate(normalizedSymbol)) {
      return;
    }

    if (!supportedSymbols.includes(normalizedSymbol)) {
      return;
    }

    const timer = window.setTimeout(() => {
      void handleLoadMarketPrice({ silent: true });
    }, 250);

    return () => {
      window.clearTimeout(timer);
    };
  }, [normalizedSymbol, livePrice, draft.currentMarketPrice, loadingPrice, supportedSymbols]);

  const previewText = useMemo(
    () => buildPreviewText(draft, draft.side === 'sell' ? selectedSellHolding : null),
    [draft, selectedSellHolding],
  );

  function updateDraft<K extends keyof SimpleSetupDraft>(key: K, value: SimpleSetupDraft[K]) {
    if (key === 'side' && value === 'buy') {
      dispatch({ type: 'set-selected-holding-trade-id', value: null });
    }
    if (key === 'symbol' && draft.side === 'sell') {
      dispatch({ type: 'set-selected-holding-trade-id', value: null });
    }
    dispatch({ type: 'set-draft-field', key, value });
  }

  function applyHoldingToDraft(holding: SimpleHolding) {
    dispatch({
      type: 'apply-holding',
      tradeId: holding.tradeId || null,
      symbol: holding.symbol,
      quantity: String(holding.size),
    });
  }

  useEffect(() => {
    if (draft.side !== 'sell') return;
    if (selectedSellHolding) return;
    if (availableSellHoldings.length === 0) return;
    applyHoldingToDraft(availableSellHoldings[0]);
  }, [draft.side, selectedSellHolding, availableSellHoldings]);

  useTradePlansNavigationState({
    searchParams,
    setSearchParams,
    savedSetups,
    availableSellHoldings,
    applyHoldingToDraft,
    dispatch,
    setupCardRefs,
  });

  async function copyIdentifier(kind: 'trade' | 'order', value: string | null | undefined) {
    if (!value) return;
    try {
      await navigator.clipboard.writeText(value);
      const key = `${kind}:${value}`;
      dispatch({ type: 'set-copied-key', value: key });
      window.setTimeout(() => {
        dispatch({ type: 'set-copied-key', value: null });
      }, 1200);
    } catch {
      dispatch({ type: 'set-error', value: `Failed to copy ${kind} ID` });
    }
  }

  async function refreshSetupList() {
    const [profileRows, entryRows] = await Promise.all([
      fetchTradeProfiles(),
      fetchManualEntries(),
    ]);
    setProfiles(profileRows);
    setSavedSetups(normalizeSimpleEntries(entryRows));
  }

  async function updateSavedSetup(entryId: string, updater: (entry: ManualEntryPayload) => ManualEntryPayload) {
    const existing = savedSetups.find((entry) => String(entry.stock_instance_id || '') === entryId);
    if (!existing) return;
    const updated = await updateManualEntry(entryId, updater(existing));
    setSavedSetups((prev) => normalizeSimpleEntries(prev.map((entry) => (
      String(entry.stock_instance_id || '') === entryId ? updated : entry
    ))));
  }

  function setMarketPriceValue(value: string, source: MarketPriceSource) {
    dispatch({ type: 'set-market-price-source', value: source });
    updateDraft('currentMarketPrice', value);
  }

  async function handleLoadMarketPrice(options?: { silent?: boolean }) {
    if (!normalizedSymbol) return;
    const requestSymbol = normalizedSymbol;
    marketPriceRequestSymbolRef.current = requestSymbol;
    setLoadingPrice(true);
    if (!options?.silent) {
      dispatch({ type: 'clear-feedback' });
    }

    try {
      if (livePrice > 0) {
        if (marketPriceRequestSymbolRef.current === requestSymbol) {
          setMarketPriceValue(livePrice.toFixed(4), 'live');
        }
        return;
      }

      const bars = await fetchChartBars(requestSymbol, '1D');
      const lastClose = Number(bars?.[bars.length - 1]?.close || 0);
      if (Number.isFinite(lastClose) && lastClose > 0) {
        if (marketPriceRequestSymbolRef.current === requestSymbol) {
          setMarketPriceValue(lastClose.toFixed(4), 'latest_close');
        }
      } else {
        const researchProfile = await fetchResearchProfile(requestSymbol).catch(() => null);
        const fallbackReferencePrice = extractReferencePriceFromResearchProfile(researchProfile);
        if (fallbackReferencePrice && marketPriceRequestSymbolRef.current === requestSymbol) {
          setMarketPriceValue(fallbackReferencePrice.toFixed(4), 'reference_price');
          return;
        }
        throw new Error('No live price or latest close is available for this symbol right now.');
      }
    } catch (err: any) {
      if (!options?.silent && marketPriceRequestSymbolRef.current === requestSymbol) {
        dispatch({ type: 'set-error', value: err?.message ?? 'Failed to load market data' });
      }
    } finally {
      if (marketPriceRequestSymbolRef.current === requestSymbol) {
        setLoadingPrice(false);
      }
    }
  }

  async function handleSubmit(e: FormEvent) {
    e.preventDefault();
    setSubmitting(true);
    dispatch({ type: 'clear-feedback' });

    try {
      const existingEntry = editingSetupId
        ? (savedSetups.find((entry) => String(entry.stock_instance_id || '') === editingSetupId) || null)
        : null;
      const payload = buildSimpleSetupPayload({
        draft,
        existingId: editingSetupId || undefined,
        holding: draft.side === 'sell' ? selectedSellHolding : null,
        existingEntry,
      });

      if (editingSetupId) {
        await updateManualEntry(editingSetupId, payload);
        dispatch({ type: 'set-message', value: `Updated ${normalizedSymbol} trade plan.` });
      } else {
        await createManualEntry({
          ...payload,
          stock_instance_id: crypto.randomUUID(),
        });
        dispatch({ type: 'set-message', value: `Saved ${normalizedSymbol} trade plan.` });
      }

      await refreshSetupList();
      dispatch({
        type: 'reset-form',
        currentMarketPrice: draft.currentMarketPrice,
        marketPriceSource: draft.currentMarketPrice ? marketPriceSource : null,
      });
    } catch (err: any) {
      dispatch({ type: 'set-error', value: err?.message ?? 'Failed to save Trade Plan' });
    } finally {
      setSubmitting(false);
    }
  }

  function handleEdit(entry: ManualEntryPayload) {
    dispatch({ type: 'set-editing-setup-id', value: String(entry.stock_instance_id || '') });
    dispatch({ type: 'set-selected-holding-trade-id', value: String(entry.linked_trade_id || '').trim() || null });
    dispatch({ type: 'set-market-price-source', value: inferMarketPriceSourceFromEntry(entry) });
    dispatch({ type: 'replace-draft', draft: buildDraftFromEntry(entry) });
    dispatch({ type: 'clear-feedback' });
  }

  async function handleDelete(entryId: string) {
    if (!window.confirm('Delete this Trade Plan?')) return;
    try {
      await deleteManualEntry(entryId);
      if (editingSetupId === entryId) {
        dispatch({ type: 'reset-form', currentMarketPrice: '', marketPriceSource: null });
      }
      await refreshSetupList();
    } catch (err: any) {
      dispatch({ type: 'set-error', value: err?.message ?? 'Failed to delete Trade Plan' });
    }
  }

  async function handleConvertToLongTerm(entry: ManualEntryPayload) {
    const entryId = String(entry.stock_instance_id || '');
    if (!entryId) return;
    dispatch({ type: 'clear-feedback' });
    try {
      await updateSavedSetup(entryId, (current) => ({
        ...current,
        holding_mode: 'long_term',
        automation_state: 'paused_long_term',
        status: 'simple_bought',
        active: true,
      }));
      dispatch({ type: 'set-message', value: `${String(entry.symbol || '').trim().toUpperCase()} is now treated as a long-term hold. Automated exit monitoring is paused.` });
    } catch (err: any) {
      dispatch({ type: 'set-error', value: err?.message ?? 'Failed to convert setup to long-term mode' });
    }
  }

  async function handleResumeExitManagement(entry: ManualEntryPayload) {
    const entryId = String(entry.stock_instance_id || '');
    if (!entryId) return;
    dispatch({ type: 'clear-feedback' });
    try {
      await updateSavedSetup(entryId, (current) => ({
        ...current,
        holding_mode: 'short_term',
        automation_state: 'holding_managed',
        status: 'simple_bought',
        active: true,
      }));
      dispatch({ type: 'set-message', value: `${String(entry.symbol || '').trim().toUpperCase()} is back under short-term exit management.` });
    } catch (err: any) {
      dispatch({ type: 'set-error', value: err?.message ?? 'Failed to resume short-term exit management' });
    }
  }

  const saveButtonLabel = editingSetupId ? 'Update setup' : 'Save setup';
  const saveButtonDisabled = submitting || loadingPrice || (draft.side === 'sell' && !selectedSellHolding);

  return (
    <div className="trade-plans-page space-y-8">
      <PageHeader
        title="Trade Plans"
        description="Create and manage short-term trade plans, then convert filled positions into long-term holds when you want to stop automated exits."
      />

      <div className="grid gap-8 xl:grid-cols-[minmax(0,1.05fr)_minmax(380px,0.95fr)]">
        <Card className="overflow-hidden">
          <CardHeader className="border-b border-[var(--border)] bg-[var(--card-elevated)]/80 p-6">
            <div>
              <CardTitle>{editingSetupId ? 'Edit trade plan' : 'Create trade plan'}</CardTitle>
              <CardDescription className="mt-2 max-w-2xl leading-6">
                Build a guided plan with clear setup, instrument, price, sizing, trigger, and review steps before automation is armed.
              </CardDescription>
            </div>
            <Button
              type="button"
              onClick={() => {
                dispatch({
                  type: 'reset-form',
                  currentMarketPrice: draft.currentMarketPrice,
                  marketPriceSource: draft.currentMarketPrice ? marketPriceSource : null,
                });
              }}
              variant="outline"
              size="sm"
            >
              Reset
            </Button>
          </CardHeader>

          <CardContent className="p-6">
          <form className="space-y-5" onSubmit={handleSubmit}>
            <section className="rounded-[var(--bl-radius-card)] border border-[var(--border)] bg-[var(--card-elevated)] p-5">
              <div className="mb-4">
                <div className="text-sm font-bold text-[var(--foreground)]">1. Setup type</div>
                <p className="mt-1 text-sm leading-6 text-[var(--muted-foreground)]">
                  Choose whether this plan opens a new position or manages profit-taking for an existing holding.
                </p>
              </div>
              <div className="grid gap-3 md:grid-cols-2">
              <Button
                type="button"
                onClick={() => {
                  dispatch({ type: 'clear-feedback' });
                  dispatch({ type: 'set-selected-holding-trade-id', value: null });
                  updateDraft('side', 'buy');
                }}
                variant="ghost"
                className={`h-auto justify-start rounded-[1.25rem] border px-5 py-5 text-left transition ${
                  draft.side === 'buy'
                    ? 'border-[var(--primary)] bg-[var(--accent-soft)]'
                    : 'border-[var(--border)] bg-[var(--card-elevated)]'
                }`}
              >
                <div>
                  <div className="text-sm font-bold text-[var(--foreground)]">New short-term buy plan</div>
                  <div className="mt-2 text-sm font-normal leading-6 text-[var(--muted-foreground)]">Arm a dip-buy trigger and let the app manage the profit exit after fill.</div>
                </div>
                </Button>
                <Button
                type="button"
                onClick={() => {
                  dispatch({ type: 'clear-feedback' });
                  if (availableSellHoldings.length > 0) {
                    applyHoldingToDraft(availableSellHoldings[0]);
                  } else {
                    updateDraft('side', 'sell');
                  }
                }}
                variant="ghost"
                className={`h-auto justify-start rounded-[1.25rem] border px-5 py-5 text-left transition ${
                  draft.side === 'sell'
                    ? 'border-[var(--primary)] bg-[var(--accent-soft)]'
                    : 'border-[var(--border)] bg-[var(--card-elevated)]'
                }`}
              >
                <div>
                  <div className="text-sm font-bold text-[var(--foreground)]">Manage an existing holding</div>
                  <div className="mt-2 text-sm font-normal leading-6 text-[var(--muted-foreground)]">Choose a filled holding and place it back under managed profit-taking.</div>
                </div>
                </Button>
              </div>
            </section>

            {draft.side === 'sell' && (
              <label className="ux-field-stack rounded-[var(--bl-radius-card)] border border-[var(--border)] bg-[var(--card-elevated)] p-5">
                <span className="ux-field-label">Existing holding</span>
                <Select
                  value={selectedHoldingTradeId || ''}
                  onChange={(e: ChangeEvent<HTMLSelectElement>) => {
                    const selected = availableSellHoldings.find((holding) => (holding.tradeId || '') === e.target.value);
                    if (selected) applyHoldingToDraft(selected);
                  }}
                  disabled={availableSellHoldings.length === 0}
                  options={availableSellHoldings.length === 0
                    ? [{ value: '', label: 'No eligible holdings available' }]
                    : availableSellHoldings.map((holding) => ({
                        value: holding.tradeId || '',
                        label: `${holding.symbol} · ${holding.size} @ ${holding.entryPrice.toFixed(4)}`,
                      }))}
                />
                <span className="ux-helper-text">
                  Trade Plans can manage an existing filled holding by attaching a profit exit target to it.
                </span>
              </label>
            )}

            <section className="rounded-[var(--bl-radius-card)] border border-[var(--border)] bg-[var(--card-elevated)] p-5">
              <div className="mb-4">
                <div className="text-sm font-bold text-[var(--foreground)]">2. Instrument and market price</div>
                <p className="mt-1 text-sm leading-6 text-[var(--muted-foreground)]">
                  Select the symbol and confirm the reference price that automation will use for trigger calculations.
                </p>
              </div>
              <div className="grid gap-4 md:grid-cols-2">
              <label className="ux-field-stack">
                <span className="ux-field-label">Symbol</span>
                <Input
                  value={draft.symbol}
                  onChange={(e: ChangeEvent<HTMLInputElement>) => {
                    dispatch({ type: 'set-market-price-source', value: null });
                    if (draft.side === 'sell') {
                      dispatch({ type: 'set-selected-holding-trade-id', value: null });
                    }
                    dispatch({
                      type: 'replace-draft',
                      draft: {
                        ...draft,
                        symbol: e.target.value.toUpperCase(),
                        currentMarketPrice: '',
                      },
                    });
                  }}
                  list={SIMPLE_SYMBOL_DATALIST_ID}
                  placeholder="AAPL"
                />
                <datalist id={SIMPLE_SYMBOL_DATALIST_ID}>
                  {supportedSymbols.map((symbol) => (
                    <option key={symbol} value={symbol} />
                  ))}
                </datalist>
                <span className="ux-helper-text">
                  Start typing to pick a supported symbol. Suggestions come from live market symbols plus common supported assets.
                </span>
                {normalizedSymbol && !isSuggestedSymbol ? (
                  <span className="block text-sm text-[var(--bl-warning)]">
                    This symbol is not in the current supported suggestions. Double-check it before saving.
                  </span>
                ) : null}
                {filteredSymbolSuggestions.length > 0 ? (
                  <div className="flex flex-wrap gap-2 pt-1">
                    {filteredSymbolSuggestions.map((symbol) => (
                      <Button
                        key={symbol}
                        type="button"
                        onClick={() => {
                          dispatch({ type: 'set-market-price-source', value: null });
                          if (draft.side === 'sell') {
                            dispatch({ type: 'set-selected-holding-trade-id', value: null });
                          }
                          dispatch({
                            type: 'replace-draft',
                            draft: {
                              ...draft,
                              symbol,
                              currentMarketPrice: '',
                            },
                          });
                        }}
                        variant="ghost"
                        size="sm"
                        className={`rounded-full border px-3 py-1 text-[11px] font-semibold transition ${
                          symbol === normalizedSymbol
                            ? 'border-[var(--primary)] bg-[var(--accent-soft)] text-[var(--primary)]'
                            : 'border-[var(--border)] bg-[var(--card-elevated)] text-[var(--muted-foreground)] hover:border-[var(--primary)] hover:text-[var(--foreground)]'
                        }`}
                      >
                        {symbol}
                      </Button>
                    ))}
                  </div>
                ) : null}
              </label>

              <div className="grid gap-4 md:grid-cols-[minmax(0,1fr)_auto]">
              <label className="ux-field-stack">
                <span className="ux-field-label">Market price</span>
                <Input
                  value={draft.currentMarketPrice}
                  readOnly
                  className="bg-[var(--muted)] text-[var(--foreground)]"
                />
                <div className="space-y-1">
                  <span className="ux-helper-text">
                    Uses live market price when available. Outside market hours, it falls back to the latest close.
                  </span>
                  <span className="block text-sm text-[var(--muted-foreground)]">
                    Price source:{' '}
                    <span className="font-semibold text-[var(--foreground)]">
                      {marketPriceSource === 'live'
                        ? 'Live'
                        : marketPriceSource === 'latest_close'
                          ? 'Latest close'
                          : marketPriceSource === 'reference_price'
                            ? 'Reference price'
                            : 'Waiting for symbol data'}
                    </span>
                  </span>
                </div>
              </label>
              <Button
                type="button"
                onClick={() => void handleLoadMarketPrice()}
                className="self-start md:self-end"
                variant="outline"
                disabled={loadingPrice || !normalizedSymbol}
              >
                <span className="inline-flex items-center gap-2">
                  <RefreshCw size={14} className={loadingPrice ? 'animate-spin' : ''} />
                  Refresh
                </span>
              </Button>
              </div>
            </div>
            </section>

            <section className="rounded-[var(--bl-radius-card)] border border-[var(--border)] bg-[var(--card-elevated)] p-5">
              <div className="mb-4">
                <div className="text-sm font-bold text-[var(--foreground)]">3. Sizing and notes</div>
                <p className="mt-1 text-sm leading-6 text-[var(--muted-foreground)]">
                  Define the planned exposure and add context for why the plan should run.
                </p>
              </div>
              <div className="grid gap-4 md:grid-cols-2">
              {draft.side === 'buy' ? (
                <>
                  <label className="ux-field-stack">
                    <span className="ux-field-label">Sizing method</span>
                    <Select
                      value={draft.sizingMode}
                      onChange={(e: ChangeEvent<HTMLSelectElement>) => updateDraft('sizingMode', e.target.value as 'quantity' | 'amount')}
                      options={[
                        { value: 'quantity', label: 'Quantity / fractional shares' },
                        { value: 'amount', label: 'USD amount' },
                      ]}
                    />
                  </label>

                  <label className="ux-field-stack">
                    <span className="ux-field-label">
                      {draft.sizingMode === 'amount' ? 'Spend amount (USD)' : 'Planned quantity'}
                    </span>
                    <Input
                      value={draft.sizingMode === 'amount' ? draft.amountUsd : draft.quantity}
                      onChange={(e: ChangeEvent<HTMLInputElement>) => {
                        if (draft.sizingMode === 'amount') {
                          updateDraft('amountUsd', e.target.value);
                        } else {
                          updateDraft('quantity', e.target.value);
                        }
                      }}
                      placeholder={draft.sizingMode === 'amount' ? '250' : '10'}
                    />
                    <span className="ux-helper-text">
                      Quantity supports fractional shares/coins. Amount spends an approximate USD budget at trigger time.
                    </span>
                    <span className="ux-helper-text">
                      Use quantity when you know the units you want. Use amount to budget dollars and let the app derive fractional size at entry.
                    </span>
                  </label>
                </>
              ) : (
                <label className="ux-field-stack">
                  <span className="ux-field-label">
                    Holding size
                  </span>
                  <Input
                    value={draft.side === 'sell' && selectedSellHolding ? String(selectedSellHolding.size) : draft.quantity}
                    onChange={(e: ChangeEvent<HTMLInputElement>) => updateDraft('quantity', e.target.value)}
                    readOnly={draft.side === 'sell' && !!selectedSellHolding}
                    className="read-only:bg-[var(--muted)]"
                    placeholder="10"
                  />
                </label>
              )}

              <label className="ux-field-stack">
                <span className="ux-field-label">Notes</span>
                <Input
                  value={draft.notes}
                  onChange={(e: ChangeEvent<HTMLInputElement>) => updateDraft('notes', e.target.value)}
                  placeholder="Optional context"
                />
              </label>
            </div>
            </section>

            {draft.side === 'buy' && (
              <section className="grid gap-4 rounded-[var(--bl-radius-card)] border border-[var(--border)] bg-[var(--card-elevated)] p-5 md:grid-cols-[0.55fr_0.45fr]">
                <div className="ux-field-stack">
                  <p className="text-sm font-bold text-[var(--foreground)]">4. Drop trigger</p>
                  <p className="ux-helper-text">Set the dip condition that should arm the buy entry.</p>
                  <Select
                    value={draft.dropMode}
                    onChange={(e: ChangeEvent<HTMLSelectElement>) => updateDraft('dropMode', e.target.value as TriggerMode)}
                    options={[
                      { value: 'dollar', label: 'Dollar drop from current market' },
                      { value: 'percent', label: 'Percent drop from current market' },
                    ]}
                  />
                </div>
                <label className="ux-field-stack">
                  <span className="ux-field-label">
                    {draft.dropMode === 'dollar' ? 'Drop amount ($)' : 'Drop amount (%)'}
                  </span>
                  <Input
                    value={draft.dropValue}
                    onChange={(e: ChangeEvent<HTMLInputElement>) => updateDraft('dropValue', e.target.value)}
                    placeholder={draft.dropMode === 'dollar' ? '0.00' : '0'}
                  />
                </label>
              </section>
            )}

            <section className="grid gap-4 rounded-[var(--bl-radius-card)] border border-[var(--border)] bg-[var(--card-elevated)] p-5 md:grid-cols-[0.55fr_0.45fr]">
              <div className="ux-field-stack">
                <p className="text-sm font-bold text-[var(--foreground)]">{draft.side === 'buy' ? '5. Profit exit' : '4. Profit exit'}</p>
                <p className="ux-helper-text">Define when automation should take profit and close or reduce risk.</p>
                <Select
                  value={draft.profitMode}
                  onChange={(e: ChangeEvent<HTMLSelectElement>) => updateDraft('profitMode', e.target.value as TriggerMode)}
                  options={[
                    { value: 'dollar', label: 'Dollar gain from purchase' },
                    { value: 'percent', label: 'Percent gain from purchase' },
                  ]}
                />
              </div>
              <label className="ux-field-stack">
                <span className="ux-field-label">
                  {draft.profitMode === 'dollar' ? 'Profit target ($)' : 'Profit target (%)'}
                </span>
                <Input
                  value={draft.profitValue}
                  onChange={(e: ChangeEvent<HTMLInputElement>) => updateDraft('profitValue', e.target.value)}
                  placeholder={draft.profitMode === 'dollar' ? '7.50' : '10'}
                />
              </label>
            </section>

            {draft.side === 'sell' && (
              <div className={`rounded-[1.5rem] border px-4 py-4 text-sm ${
                selectedSellHolding
                  ? 'border-[var(--bl-success)]/20 bg-[var(--bl-success-muted)] text-[var(--bl-success)]'
                  : 'border-[var(--bl-danger)]/20 bg-[var(--bl-danger-muted)] text-[var(--bl-danger)]'
              }`}>
                {selectedSellHolding
                  ? `Holding ready: ${selectedSellHolding.symbol} · ${selectedSellHolding.size} units at ${selectedSellHolding.entryPrice.toFixed(4)}. Executed buys also appear in Portfolio as live positions.`
                  : 'No eligible live holding found for this symbol yet. Managed sell setups only arm against a current holding.'}
              </div>
            )}

            {previewText && (
              <section className="rounded-[var(--bl-radius-card)] border border-[var(--border)] bg-[var(--accent-soft)] p-5 text-sm leading-6 text-[var(--foreground)]">
                <div className="mb-1 font-bold">{draft.side === 'buy' ? '6. Review and create' : '5. Review and create'}</div>
                <div>{previewText}</div>
                <div className="mt-3 text-[var(--muted-foreground)]">
                  Review the symbol, price source, sizing, and exit target before creating the plan.
                </div>
              </section>
            )}

            {message && (
              <div className="rounded-2xl border border-[var(--bl-success)]/20 bg-[var(--bl-success-muted)] px-4 py-3 text-sm text-[var(--bl-success)]">
                {message}
              </div>
            )}

            {error && (
              <div className="rounded-2xl border border-[var(--bl-danger)]/20 bg-[var(--bl-danger-muted)] px-4 py-3 text-sm text-[var(--bl-danger)]">
                {error}
              </div>
            )}

            <div className="sticky bottom-4 z-[var(--bl-z-sticky)] rounded-[var(--bl-radius-card)] border border-[var(--border)] bg-[var(--card)]/95 p-4 shadow-[var(--bl-shadow-card)] backdrop-blur">
              <div className="flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
                <div className="text-sm leading-6 text-[var(--muted-foreground)]">
                  {saveButtonDisabled
                    ? 'Complete the required setup details before creating the plan.'
                    : 'Ready to save this plan and arm the next automation step.'}
                </div>
                <Button
                  type="submit"
                  disabled={saveButtonDisabled}
                  className="w-full md:w-auto"
                  size="lg"
                >
                  {submitting ? 'Saving...' : saveButtonLabel}
                </Button>
              </div>
            </div>
          </form>
          </CardContent>
        </Card>

        <Card className="saved-setups-panel">
          <CardHeader className="saved-setups-header">
            <div>
              <CardTitle>Saved setups</CardTitle>
              <CardDescription>Review armed setups, runtime order state, and portfolio handoff status.</CardDescription>
            </div>
            <span className="saved-setups-count">{savedSetups.length}</span>
          </CardHeader>

          <CardContent>
          <div className="saved-setups-list">
            {savedSetups.length === 0 && (
              <div className="rounded-[1.5rem] border border-dashed border-[var(--border)] bg-[var(--card-elevated)] px-5 py-8 text-sm text-[var(--muted-foreground)]">
                No Trade Plans saved yet.
              </div>
            )}

            {savedSetups.map((entry) => {
              const entryId = String(entry.stock_instance_id || '');
              const side = normalizeSetupSide(entry.simple_side);
              const isEditing = editingSetupId === entryId;
              const runtimeSnapshot = deriveRuntimeSnapshot(entry, runtimeOrders, simpleHoldings);
              const nextActionText = describeNextAction(entry, runtimeSnapshot);
              const updatedAt = formatSetupUpdatedAt(entry);
              const eventHistory = deriveSimpleEventHistory(entry, runtimeEvents);
              const holdingMode = normalizeHoldingMode(entry.holding_mode);
              const linkedHoldingTradeId = String(entry.linked_trade_id || '').trim();
              const linkedHolding = side === 'sell'
                ? availableSellHoldings.find((holding) => {
                    if (linkedHoldingTradeId) {
                      return holding.tradeId === linkedHoldingTradeId;
                    }
                    return (
                      holding.symbol === String(entry.symbol || '').trim().toUpperCase()
                      && String(holding.profileId || '').trim() === String(entry.profile_id || '').trim()
                    );
                  }) || null
                : null;
              const canConvertToLongTerm = side === 'buy' && holdingMode === 'short_term' && runtimeSnapshot?.stage === 'filled';
              const canResumeExitManagement = side === 'buy' && holdingMode === 'long_term' && runtimeSnapshot?.stage === 'filled';
              return (
                <div
                  key={entryId}
                  ref={(node) => {
                    setupCardRefs.current[entryId] = node;
                  }}
                  className={`saved-setup-card rounded-[1.5rem] border bg-[var(--card-elevated)] p-5 transition ${
                    focusedSetupId === entryId
                      ? 'border-[var(--primary)] ring-2 ring-[var(--primary)]/20'
                      : 'border-[var(--border)]'
                  }`}
                >
                  <div className="saved-setup-topline">
                    <div className="saved-setup-title-block">
                      <div className="saved-setup-asset-row">
                        <h3>{entry.symbol}</h3>
                        <span className={`saved-setup-side ${
                          side === 'buy' ? 'bg-emerald-500/10 text-emerald-700 dark:text-emerald-300' : 'bg-violet-500/10 text-violet-700 dark:text-violet-300'
                        }`}>
                          {side}
                        </span>
                      </div>
                      <p>{describeSavedSetup(entry)}</p>
                    </div>
                    <div className="saved-setup-actions">
                      {canConvertToLongTerm ? (
                        <Button
                          type="button"
                          onClick={() => void handleConvertToLongTerm(entry)}
                          variant="outline"
                          size="sm"
                          className="saved-setup-action"
                        >
                          Convert to long-term
                        </Button>
                      ) : null}
                      {canResumeExitManagement ? (
                        <Button
                          type="button"
                          onClick={() => void handleResumeExitManagement(entry)}
                          variant="outline"
                          size="sm"
                          className="saved-setup-action"
                        >
                          Resume exit management
                        </Button>
                      ) : null}
                      <Button
                        type="button"
                        onClick={() => handleEdit(entry)}
                        variant="outline"
                        size="sm"
                        className={isEditing ? 'saved-setup-action border-emerald-500/30 text-emerald-700 dark:text-emerald-300' : 'saved-setup-action'}
                      >
                        <span className="inline-flex items-center gap-2">
                          <Pencil size={14} />
                          Edit
                        </span>
                      </Button>
                      <Button
                        type="button"
                        onClick={() => void handleDelete(entryId)}
                        variant="destructive"
                        size="sm"
                        className="saved-setup-action"
                      >
                        <span className="inline-flex items-center gap-2">
                          <Trash2 size={14} />
                          Delete
                        </span>
                      </Button>
                    </div>
                  </div>

                  <div className="saved-setup-meta-grid">
                    <span>
                      {formatSetupStatus(entry.status)}
                    </span>
                    <span>
                      {formatHoldingMode(entry.holding_mode)}
                    </span>
                    <span>
                      {formatAutomationState(entry)}
                    </span>
                    {runtimeSnapshot ? (
                      <span className={statusToneClasses(runtimeSnapshot.tone)}>
                        {runtimeSnapshot.label}
                      </span>
                    ) : null}
                    <span>
                      {String(entry.sizing_mode || '').trim().toLowerCase() === 'amount'
                        ? `Budget $${Number(entry.amount_usd || 0).toFixed(2)}`
                        : `Qty ${entry.quantity || entry.filled_quantity || 0}`}
                    </span>
                    {entry.reference_price ? (
                      <span>
                        Ref {Number(entry.reference_price).toFixed(4)}
                      </span>
                    ) : null}
                    {entry.entry_price ? (
                      <span>
                        Entry {Number(entry.entry_price).toFixed(4)}
                      </span>
                    ) : null}
                    {(runtimeSnapshot?.tradeId || entry.linked_trade_id) ? (
                      <Button
                        type="button"
                        variant="subtle"
                        size="sm"
                        onClick={() => void copyIdentifier('trade', String(runtimeSnapshot?.tradeId || entry.linked_trade_id))}
                        className="saved-setup-id-chip"
                      >
                        {copiedKey === `trade:${String(runtimeSnapshot?.tradeId || entry.linked_trade_id)}`
                          ? 'Trade copied'
                          : `Trade ${String(runtimeSnapshot?.tradeId || entry.linked_trade_id).slice(0, 18)}…`}
                      </Button>
                    ) : null}
                    {runtimeSnapshot?.orderId ? (
                      <Button
                        type="button"
                        variant="subtle"
                        size="sm"
                        onClick={() => void copyIdentifier('order', runtimeSnapshot.orderId)}
                        className="saved-setup-id-chip"
                      >
                        {copiedKey === `order:${runtimeSnapshot.orderId}`
                          ? 'Order copied'
                          : `Order ${runtimeSnapshot.orderId.slice(0, 12)}…`}
                      </Button>
                    ) : null}
                    {updatedAt ? (
                      <span className="saved-setup-updated">
                        Updated {updatedAt}
                      </span>
                    ) : null}
                  </div>

                  {side === 'sell' ? (
                    <div className="mt-4 rounded-2xl border border-[var(--border)] bg-[var(--background)] px-4 py-3">
                      <div className="text-[11px] font-black uppercase tracking-[0.22em] text-[var(--muted-foreground)]">
                        Linked holding
                      </div>
                      <div className="mt-2 flex flex-wrap items-center gap-2 text-sm text-[var(--foreground)]">
                        <span className="rounded-full border border-[var(--border)] px-3 py-1">
                          {linkedHolding?.symbol || String(entry.symbol || '').trim().toUpperCase()}
                        </span>
                        {(linkedHolding?.tradeId || linkedHoldingTradeId) ? (
                          <span className="rounded-full border border-[var(--border)] px-3 py-1 font-mono text-xs">
                            Trade {linkedHolding?.tradeId || linkedHoldingTradeId}
                          </span>
                        ) : null}
                        {(linkedHolding?.profileId || entry.profile_id) ? (
                          <span className="rounded-full border border-[var(--border)] px-3 py-1 font-mono text-xs">
                            Profile {String(linkedHolding?.profileId || entry.profile_id)}
                          </span>
                        ) : null}
                        {linkedHolding?.entryPrice ? (
                          <span className="rounded-full border border-[var(--border)] px-3 py-1">
                            Entry {Number(linkedHolding.entryPrice).toFixed(4)}
                          </span>
                        ) : null}
                        {linkedHolding?.size ? (
                          <span className="rounded-full border border-[var(--border)] px-3 py-1">
                            Qty {linkedHolding.size}
                          </span>
                        ) : null}
                      </div>
                    </div>
                  ) : null}

                  <div className="saved-setup-timeline">
                    {SIMPLE_TIMELINE_STEPS.map((step) => {
                      const complete = isTimelineStepComplete(runtimeSnapshot?.stage, step);
                      const isCurrent = runtimeSnapshot?.stage === step;
                      return (
                        <div
                          key={step}
                          className={`saved-setup-step ${
                            isCurrent
                              ? 'border-[var(--primary)] bg-[var(--accent-soft)] text-[var(--primary)]'
                              : complete
                                ? 'border-emerald-500/30 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300'
                                : 'border-[var(--border)] bg-[var(--background)] text-[var(--muted-foreground)]'
                          }`}
                        >
                          {formatTimelineStepLabel(step)}
                        </div>
                      );
                    })}
                  </div>

                  <div className="saved-setup-next-action">
                    <span className="font-semibold text-[var(--foreground)]">Next action:</span>{' '}
                    {nextActionText}
                  </div>

                  {eventHistory.length > 0 && (
                    <div className="mt-4 rounded-2xl border border-[var(--border)] bg-[var(--background)] px-4 py-4">
                      <div className="mb-3 flex items-center justify-between gap-3">
                        <div className="text-sm font-semibold text-[var(--foreground)]">Recent activity</div>
                        <div className="text-[11px] uppercase tracking-[0.18em] text-[var(--muted-foreground)]">
                          setup-level runtime history
                        </div>
                      </div>
                      <div className="space-y-2">
                        {eventHistory.map((event) => (
                          <div key={event.id} className={`rounded-2xl border px-3 py-3 ${eventSeverityClasses(event.severity)}`}>
                            <div className="flex flex-wrap items-center justify-between gap-2">
                              <div className="text-[11px] font-black uppercase tracking-[0.18em]">
                                {String(event.severity || 'INFO').toUpperCase()}
                              </div>
                              <div className="text-[11px] opacity-80">
                                {formatEventTimestamp(event.timestamp) || 'Just now'}
                              </div>
                            </div>
                            <div className="mt-1 text-sm leading-6">{event.message}</div>
                            <div className="mt-2 flex flex-wrap gap-2 text-[11px] uppercase tracking-[0.14em] opacity-80">
                              {event.tradeId ? <span>Trade {event.tradeId.slice(0, 18)}…</span> : null}
                              {event.orderId ? <span>Order {event.orderId.slice(0, 12)}…</span> : null}
                            </div>
                          </div>
                        ))}
                      </div>
                    </div>
                  )}
                </div>
              );
            })}
          </div>
          </CardContent>
        </Card>
      </div>
    </div>
  );
}
