import React, { useState, useEffect, useMemo } from 'react';
import {
  View, Text, StyleSheet, TouchableOpacity, ScrollView,
  Modal, ActivityIndicator, useWindowDimensions, Platform,
  useColorScheme,
} from 'react-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { useConnectionStore } from '../../src/stores/connectionStore';
import { useDeviceStore } from '../../src/stores/deviceStore';
import { useDataStore } from '../../src/stores/dataStore';
import { useDevice } from '../../src/hooks/useDevice';
import { useWaveform, type WaveformData } from '../../src/hooks/useWaveform';
import { WaveformChart } from '../../src/components/WaveformChart';
import { ParamForm } from '../../src/components/ParamForm';
import { NoProjectGate } from '../../src/components/NoProjectGate';
import { CHANNEL_COLORS } from '../../src/protocol/constants';
import { formatUV, formatUtc, formatCoord, sourceModeLabel, formatBattery, formatTemperature } from '../../src/utils/format';
import { useTheme } from '../../src/design/tokens';
import { Spacing, Radius } from '../../src/design/tokens';
import * as ScreenOrientation from 'expo-screen-orientation';
import type { MeasurementFrame } from '../../src/protocol/types';

// ── Param sheet ───────────────────────────────────────────────────────────────

function ParamSheet({
  visible,
  onClose,
  onSetup,
  busy,
  configDirty,
}: {
  visible:     boolean;
  onClose:     () => void;
  onSetup:     () => Promise<void>;
  busy:        boolean;
  configDirty: boolean;
}) {
  const theme = useTheme();
  const { deviceStatus } = useDeviceStore();
  const measuring = deviceStatus !== 'idle';

  return (
    <Modal
      visible={visible}
      transparent
      animationType="slide"
      onRequestClose={onClose}
      statusBarTranslucent
    >
      <TouchableOpacity style={PS.backdrop} activeOpacity={1} onPress={onClose} />
      <View style={[PS.sheet, {
        backgroundColor: theme.bg.surface,
        borderColor: theme.bg.border,
      }]}>
        <View style={[PS.handle, { backgroundColor: theme.bg.border }]} />

        <View style={PS.header}>
          <Text style={[PS.title, { color: theme.text.secondary }]}>采集参数</Text>
          {configDirty && (
            <View style={[PS.dirtyBadge, {
              backgroundColor: theme.amber.bg,
              borderColor: theme.amber.border,
            }]}>
              <Text style={[PS.dirtyTxt, { color: theme.amber.fg }]}>待下发</Text>
            </View>
          )}
        </View>

        <ScrollView style={PS.scroll} keyboardShouldPersistTaps="handled" showsVerticalScrollIndicator={false}>
          <ParamForm />
          <View style={{ height: Spacing.md }} />
        </ScrollView>

        <TouchableOpacity
          style={[
            PS.setupBtn,
            {
              backgroundColor: theme.bg.raised,
              borderColor: theme.bg.border,
            },
            configDirty && {
              backgroundColor: theme.blue.bg,
              borderColor: theme.blue.fg,
            },
            (busy || measuring) && PS.setupBtnDis,
          ]}
          onPress={onSetup}
          disabled={busy || measuring}
          activeOpacity={0.8}
        >
          {busy
            ? <ActivityIndicator color={theme.blue.fg} />
            : <Text style={[
                PS.setupBtnTxt,
                { color: theme.text.muted },
                configDirty && { color: theme.blue.fg },
              ]}>
                {measuring ? '采集中，不可下发' : '下  发  配  置'}
              </Text>}
        </TouchableOpacity>
      </View>
    </Modal>
  );
}

const PS = StyleSheet.create({
  backdrop: { ...StyleSheet.absoluteFill, backgroundColor: 'rgba(0,0,0,0.6)' },
  sheet: {
    position:    'absolute',
    bottom:      0,
    left:        0,
    right:       0,
    maxHeight:   '85%',
    borderTopLeftRadius:  Radius.xl,
    borderTopRightRadius: Radius.xl,
    borderTopWidth: 1,
    paddingBottom:  Spacing.xxl,
  },
  handle: {
    width: 36, height: 4, borderRadius: 2,
    alignSelf: 'center',
    marginTop: Spacing.sm, marginBottom: Spacing.sm,
  },
  header:     { flexDirection: 'row', alignItems: 'center', paddingHorizontal: Spacing.lg, paddingBottom: Spacing.sm, gap: Spacing.sm },
  title:      { fontSize: 14, fontWeight: '700', flex: 1 },
  dirtyBadge: { borderRadius: Radius.sm, paddingHorizontal: 7, paddingVertical: 2, borderWidth: 1 },
  dirtyTxt:   { fontSize: 9, fontWeight: '700' },
  scroll:     { flex: 1 },
  setupBtn: {
    margin: Spacing.lg,
    borderRadius: Radius.lg,
    paddingVertical: 14,
    alignItems: 'center',
    borderWidth: 1,
  },
  setupBtnDis:      { opacity: 0.4 },
  setupBtnTxt:      { fontWeight: '700', fontSize: 14, letterSpacing: 3 },
});

// ── Control row ───────────────────────────────────────────────────────────────

function ControlRow({
  deviceStatus,
  busy,
  frameId,
  onContinuous,
  onSingle,
  onStop,
  onSettings,
  configDirty,
}: {
  deviceStatus: 'idle' | 'running' | 'single';
  busy:         boolean;
  frameId:      number | undefined;
  onContinuous: () => void;
  onSingle:     () => void;
  onStop:       () => void;
  onSettings:   () => void;
  configDirty:  boolean;
}) {
  const theme = useTheme();
  const idle    = deviceStatus === 'idle';
  const running = deviceStatus === 'running';
  const single  = deviceStatus === 'single';

  return (
    <View style={[CR.row, {
      borderTopColor: theme.bg.border,
      backgroundColor: theme.bg.surface,
    }]}>
      {/* Primary action */}
      {idle && (
        <TouchableOpacity
          style={[CR.primary, {
            backgroundColor: theme.green.bg,
            borderColor: theme.green.border,
          }, !busy ? null : CR.dis]}
          onPress={onContinuous}
          disabled={busy}
          activeOpacity={0.85}
        >
          {busy
            ? <ActivityIndicator color={theme.green.fg} />
            : <>
                <Text style={[CR.primaryIcon, { color: theme.text.ghost }]}>▶</Text>
                <Text style={[CR.primaryTxt, { color: theme.green.fg }]}>连  续  采  集</Text>
              </>}
        </TouchableOpacity>
      )}
      {running && (
        <TouchableOpacity
          style={[CR.primary, {
            backgroundColor: theme.red.bg,
            borderColor: theme.red.border,
          }]}
          onPress={onStop}
          activeOpacity={0.85}
        >
          <Text style={[CR.primaryIcon, { color: theme.text.ghost }]}>■</Text>
          <Text style={[CR.primaryTxt, { color: theme.red.fg }]}>停    止</Text>
        </TouchableOpacity>
      )}
      {single && (
        <View style={[CR.primary, {
          backgroundColor: theme.teal.bg,
          borderColor: theme.teal.border,
        }, CR.dis]}>
          <ActivityIndicator color={theme.teal.fg} size="small" />
          <Text style={[CR.primaryTxt, { color: theme.teal.fg }]}>单次采集中…</Text>
        </View>
      )}

      {/* Secondary: single-shot button (idle only) */}
      {idle && (
        <TouchableOpacity
          style={[CR.secondary, {
            backgroundColor: theme.teal.bg,
            borderColor: theme.teal.border,
          }, !busy ? null : CR.dis]}
          onPress={onSingle}
          disabled={busy}
          activeOpacity={0.85}
        >
          <Text style={[CR.secondaryIcon, { color: theme.text.ghost }]}>◎</Text>
          <Text style={[CR.secondaryTxt, { color: theme.teal.fg }]}>单次</Text>
        </TouchableOpacity>
      )}

      {/* Running indicator (running only) */}
      {running && frameId !== undefined && (
        <View style={[CR.indicator, {
          backgroundColor: theme.green.bg,
          borderColor: theme.green.border,
        }]}>
          <View style={[CR.runDot, { backgroundColor: theme.green.fg }]} />
          <Text style={[CR.indicatorTxt, { color: theme.green.fg }]}>#{frameId}</Text>
        </View>
      )}

      {/* Settings button — always present */}
      <TouchableOpacity
        style={[CR.settingsBtn, {
          backgroundColor: theme.bg.raised,
          borderColor: theme.bg.border,
        }]}
        onPress={onSettings}
        activeOpacity={0.8}
      >
        <Text style={[CR.settingsTxt, { color: theme.text.muted }, configDirty && { color: theme.amber.fg }]}>⚙</Text>
        {configDirty && (
          <View style={[CR.dirtyDot, {
            backgroundColor: theme.amber.fg,
            borderColor: theme.bg.surface,
          }]} />
        )}
      </TouchableOpacity>
    </View>
  );
}

const CR = StyleSheet.create({
  row: {
    flexDirection:  'row',
    alignItems:     'center',
    paddingHorizontal: Spacing.md,
    paddingVertical:   Spacing.sm,
    gap:            Spacing.sm,
    borderTopWidth: 1,
  },
  primary: {
    flex: 2,
    flexDirection:   'row',
    alignItems:      'center',
    justifyContent:  'center',
    gap:             8,
    paddingVertical: 14,
    borderRadius:    Radius.lg,
    borderWidth:     1,
  },
  dis:     { opacity: 0.35 },
  primaryIcon: { fontSize: 11 },
  primaryTxt:  { fontSize: 13, fontWeight: '700', letterSpacing: 1.5 },

  secondary: {
    flex: 1,
    flexDirection:   'row',
    alignItems:      'center',
    justifyContent:  'center',
    gap:             5,
    paddingVertical: 14,
    borderRadius:    Radius.lg,
    borderWidth:     1,
  },
  secondaryIcon:{ fontSize: 11 },
  secondaryTxt: { fontSize: 12, fontWeight: '700' },

  indicator: {
    flex: 1,
    flexDirection:  'row',
    alignItems:     'center',
    justifyContent: 'center',
    gap:            6,
    paddingVertical: 14,
    borderRadius:   Radius.lg,
    borderWidth:    1,
  },
  runDot:       { width: 6, height: 6, borderRadius: 3 },
  indicatorTxt: { fontSize: 12, fontWeight: '700', fontFamily: Platform.OS === 'ios' ? 'Courier' : 'monospace' },

  settingsBtn: {
    width: 44, height: 44,
    borderRadius: Radius.md,
    borderWidth: 1,
    alignItems: 'center', justifyContent: 'center',
  },
  settingsTxt:   { fontSize: 18 },
  dirtyDot: {
    position: 'absolute', top: 6, right: 6,
    width: 7, height: 7, borderRadius: 4,
    borderWidth: 1,
  },
});

// ── Status panel ─────────────────────────────────────────────────────────────

const CURRENT_RATIO = 50;
const INT32_MAX = 0x7fffffff;

function formatCurrent(raw: number): string {
  const amps = (raw / INT32_MAX) * 5.0 * CURRENT_RATIO;
  return `${amps.toFixed(1)} A`;
}

function StatusPanel({ frame }: { frame: MeasurementFrame }) {
  const theme = useTheme();
  const m = frame.meta;
  const mono = { fontFamily: Platform.OS === 'ios' ? 'Courier' : 'monospace' } as const;

  const row1 = [
    { label: '源模式', value: sourceModeLabel(m.sourceMode) },
    { label: '发射电流', value: formatCurrent(m.current) },
    { label: '电池', value: formatBattery(m.batteryVolt) },
    { label: '温度', value: formatTemperature(m.temperature) },
  ];
  const row2 = [
    { label: 'Roll', value: `${m.roll.toFixed(1)}°` },
    { label: 'Pitch', value: `${m.pitch.toFixed(1)}°` },
    { label: 'Yaw', value: `${m.yaw.toFixed(1)}°` },
    { label: 'GPS', value: ['未定位','非差分','差分','无效PPS','固定解','浮点解','估算中'][m.gpsStatus] ?? '未知', highlight: m.gpsStatus > 0 },
    { label: 'SD', value: ['正常','未插卡','异常'][m.sdStatus] ?? '未知', highlight: m.sdStatus === 0 },
  ];

  const renderCell = (it: { label: string; value: string; highlight?: boolean }) => (
    <View key={it.label} style={[SP.cell, { borderColor: theme.bg.border, backgroundColor: theme.bg.surface }]}>
      <Text style={[SP.label, { color: theme.text.muted }]}>{it.label}</Text>
      <Text style={[SP.value, mono, { color: it.highlight ? theme.green.fg : theme.text.secondary }]}>{it.value}</Text>
    </View>
  );

  return (
    <View style={[SP.container, { borderTopColor: theme.bg.divider, backgroundColor: theme.bg.void }]}>
      <View style={SP.row}>{row1.map(renderCell)}</View>
      <View style={SP.row}>{row2.map(renderCell)}</View>
    </View>
  );
}

const SP = StyleSheet.create({
  container: { paddingHorizontal: Spacing.md, paddingVertical: 4, gap: 4, borderTopWidth: StyleSheet.hairlineWidth },
  row:   { flexDirection: 'row', gap: 4 },
  cell:  { flex: 1, alignItems: 'center', paddingVertical: 3, borderRadius: Radius.sm, borderWidth: 1 },
  label: { fontSize: 8, fontWeight: '600' },
  value: { fontSize: 10, fontWeight: '700', marginTop: 1 },
});

// ── Frame summary bar ─────────────────────────────────────────────────────────

function FrameSummaryBar({ frame }: { frame: MeasurementFrame }) {
  const theme = useTheme();
  return (
    <View style={[FS.bar, {
      backgroundColor: theme.bg.void,
      borderTopColor: theme.bg.divider,
    }]}>
      <Text style={[FS.txt, { color: theme.text.ghost }]}>
        #{frame.frameId}
        {'  '}{frame.meta ? formatUtc(frame.meta.utc) : ''}
        {frame.meta?.latitude ? `  ${formatCoord(frame.meta.latitude, false)} ${formatCoord(frame.meta.longitude, true)}` : ''}
        {frame.meta ? `  R${frame.meta.roll.toFixed(1)} P${frame.meta.pitch.toFixed(1)} Y${frame.meta.yaw.toFixed(1)}` : ''}
      </Text>
    </View>
  );
}

const FS = StyleSheet.create({
  bar: { paddingHorizontal: Spacing.md, paddingVertical: 5, borderTopWidth: StyleSheet.hairlineWidth },
  txt: { fontSize: 9, fontFamily: Platform.OS === 'ios' ? 'Courier' : 'monospace' },
});

// ── Not connected placeholder ─────────────────────────────────────────────────

function NotConnected({ onConnect }: { onConnect: () => void }) {
  const theme = useTheme();
  return (
    <View style={NC.root}>
      <Text style={[NC.icon, { color: theme.bg.border }]}>◈</Text>
      <Text style={[NC.title, { color: theme.text.muted }]}>未连接仪器</Text>
      <Text style={[NC.sub, { color: theme.text.ghost }]}>请先连接 TEM 接收机</Text>
      <TouchableOpacity
        style={[NC.btn, {
          backgroundColor: theme.blue.bg,
          borderColor: theme.blue.fg,
        }]}
        onPress={onConnect}
        activeOpacity={0.8}
      >
        <Text style={[NC.btnTxt, { color: theme.blue.fg }]}>连  接  设  备</Text>
      </TouchableOpacity>
    </View>
  );
}

const NC = StyleSheet.create({
  root:   { flex: 1, justifyContent: 'center', alignItems: 'center', gap: 12 },
  icon:   { fontSize: 48 },
  title:  { fontSize: 17, fontWeight: '700' },
  sub:    { fontSize: 12 },
  btn: {
    marginTop: Spacing.sm,
    borderRadius: Radius.lg,
    paddingVertical: 13,
    paddingHorizontal: 32,
    borderWidth: 1,
  },
  btnTxt: { fontSize: 14, fontWeight: '700', letterSpacing: 2 },
});

// ── Main screen ───────────────────────────────────────────────────────────────

export default function WaveScreen() {
  const theme = useTheme();
  const { width: sw, height: sh } = useWindowDimensions();
  const { status, showModal }     = useConnectionStore();
  const { config, configDirty }   = useDeviceStore();
  const { deviceStatus }          = useDeviceStore();
  const { busy, setup, startContinuous, startSingle, stop } = useDevice();

  const frame      = useDataStore((s) => s.currentFrame);
  const sessionId  = useDataStore((s) => s.sessionId);
  const projectId  = useDataStore((s) => s.projectId);
  const hasProject = useDataStore((s) => s.hasProject);

  const [visible,      setVisible]      = useState(() => Array(6).fill(true));
  const [logScale,     setLogScale]     = useState(false);
  const [sheetVisible, setSheetVisible] = useState(false);
  const [fullscreen,   setFullscreen]   = useState(false);
  const [projectName,  setProjectName]  = useState<string | null>(null);

  useEffect(() => {
    if (fullscreen) {
      ScreenOrientation.unlockAsync();
    } else {
      ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.PORTRAIT_UP);
    }
    return () => {
      ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.PORTRAIT_UP);
    };
  }, [fullscreen]);

  const connected   = status === 'connected';
  const channelNum  = config.channelNum;
  const CHART_H     = Math.round(Math.min(280, sh * 0.36));

  const data = useWaveform(visible);

  useEffect(() => {
    if (!projectId) { setProjectName(null); return; }
    import('../../src/services/StorageService').then(({ listProjects }) =>
      listProjects().then((ps) => setProjectName(ps.find((p) => p.projectId === projectId)?.name ?? null)),
    ).catch(() => setProjectName(null));
  }, [projectId]);

  const toggleChannel = (idx: number) =>
    setVisible((prev) => prev.map((v, i) => (i === idx ? !v : v)));

  const handleSetup = async () => {
    await setup();
    setSheetVisible(false);
  };

  if (!connected) {
    return (
      <View style={[S.root, { backgroundColor: theme.bg.base }]}>
        <NotConnected onConnect={showModal} />
      </View>
    );
  }

  if (!hasProject) {
    return (
      <View style={[S.root, { backgroundColor: theme.bg.base }]}>
        <NoProjectGate />
      </View>
    );
  }

  return (
    <View style={[S.root, { backgroundColor: theme.bg.base }]}>

      {/* ── Context bar: project · session ── */}
      <View style={[S.ctxBar, {
        backgroundColor: theme.bg.void,
        borderBottomColor: theme.bg.divider,
      }]}>
        {projectName
          ? <Text style={[S.ctxTxt, { color: theme.text.ghost }]} numberOfLines={1}>{projectName}  ·  {sessionId}</Text>
          : <Text style={[S.ctxTxt, { color: theme.text.ghost }]} numberOfLines={1}>{sessionId}</Text>}
      </View>

      {/* ── Channel selector + LOG/LIN ── */}
      <View style={[S.toolbar, { borderBottomColor: theme.bg.divider }]}>
        <ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={S.chRow}>
          {Array.from({ length: channelNum }, (_, i) => (
            <TouchableOpacity
              key={i}
              style={[
                S.chBtn,
                { borderColor: theme.bg.border },
                visible[i] && { borderColor: CHANNEL_COLORS[i] + '99', backgroundColor: CHANNEL_COLORS[i] + '1a' },
              ]}
              onPress={() => toggleChannel(i)}
              activeOpacity={0.7}
            >
              <View style={[S.chDot, { backgroundColor: visible[i] ? CHANNEL_COLORS[i] : theme.bg.border }]} />
              <Text style={[S.chTxt, { color: theme.text.ghost }, visible[i] && { color: CHANNEL_COLORS[i] }]}>CH{i + 1}</Text>
            </TouchableOpacity>
          ))}
        </ScrollView>
        <TouchableOpacity
          style={[S.logBtn, {
            borderColor: theme.bg.border,
            backgroundColor: theme.bg.raised,
          }, !logScale && {
            borderColor: theme.blue.border,
            backgroundColor: theme.blue.bg,
          }]}
          onPress={() => setLogScale((v) => !v)}
          activeOpacity={0.7}
        >
          <Text style={[S.logTxt, { color: theme.text.muted }, !logScale && { color: theme.blue.fg }]}>
            {logScale ? 'LOG' : 'LIN'}
          </Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={[S.fullBtn, {
            borderColor: theme.bg.border,
            backgroundColor: theme.bg.raised,
          }]}
          onPress={() => setFullscreen(true)}
          activeOpacity={0.7}
        >
          <Text style={[S.fullTxt, { color: theme.text.muted }]}>⛶</Text>
        </TouchableOpacity>
      </View>

      {/* ── Waveform chart ── */}
      <View style={[S.chartWrap, { borderBottomColor: theme.bg.divider }]}>
        {data ? (
          <WaveformChart
            data={data}
            visibleChannels={visible}
            width={sw}
            height={CHART_H}
            logScale={logScale}
            interactive={false}
          />
        ) : (
          <View style={[S.chartPlaceholder, { height: CHART_H, backgroundColor: theme.bg.surface }]}>
            <Text style={[S.placeholderTxt, { color: theme.text.ghost }]}>等待采样数据…</Text>
          </View>
        )}
      </View>

      {/* ── Peak values ── */}

      {/* ── Frame summary ── */}
      {frame && <StatusPanel frame={frame} />}
      {frame && <FrameSummaryBar frame={frame} />}

      {/* ── Control row ── */}
      <ControlRow
        deviceStatus={deviceStatus}
        busy={busy}
        frameId={frame?.frameId}
        onContinuous={startContinuous}
        onSingle={startSingle}
        onStop={stop}
        onSettings={() => setSheetVisible(true)}
        configDirty={configDirty}
      />

      {/* ── Param sheet ── */}
      <ParamSheet
        visible={sheetVisible}
        onClose={() => setSheetVisible(false)}
        onSetup={handleSetup}
        busy={busy}
        configDirty={configDirty}
      />

      {/* ── Fullscreen waveform ── */}
      <Modal
        visible={fullscreen}
        animationType="fade"
        supportedOrientations={['portrait', 'landscape', 'landscape-left', 'landscape-right']}
        statusBarTranslucent
        onRequestClose={() => setFullscreen(false)}
      >
        <FullscreenContent
          data={data}
          visibleChannels={visible}
          logScale={logScale}
          onToggleLog={() => setLogScale((v) => !v)}
          onClose={() => setFullscreen(false)}
        />
      </Modal>
    </View>
  );
}

function FullscreenContent({
  data, visibleChannels, logScale, onToggleLog, onClose,
}: {
  data: WaveformData | null;
  visibleChannels: boolean[];
  logScale: boolean;
  onToggleLog: () => void;
  onClose: () => void;
}) {
  const theme = useTheme();
  const scheme = useColorScheme();
  const isDark = scheme !== 'light';
  const { width: fsW, height: fsH } = useWindowDimensions();
  return (
    <GestureHandlerRootView style={[S.fsRoot, { backgroundColor: theme.chart.bg }]}>
      {data ? (
        <WaveformChart
          data={data}
          visibleChannels={visibleChannels}
          width={fsW}
          height={fsH}
          logScale={logScale}
          interactive
        />
      ) : (
            <View style={[S.chartPlaceholder, { flex: 1, backgroundColor: theme.bg.surface }]}>
              <Text style={[S.placeholderTxt, { color: theme.text.ghost }]}>等待采样数据…</Text>
            </View>
          )}

          {/* Floating toolbar */}
          <View style={S.fsToolbar}>
            <TouchableOpacity
              style={[S.logBtn, {
                borderColor: theme.bg.border,
                backgroundColor: theme.bg.raised,
              }, !logScale && {
                borderColor: theme.blue.border,
                backgroundColor: theme.blue.bg,
              }]}
              onPress={onToggleLog}
              activeOpacity={0.7}
            >
              <Text style={[S.logTxt, { color: theme.text.muted }, !logScale && { color: theme.blue.fg }]}>
                {logScale ? 'LOG' : 'LIN'}
              </Text>
            </TouchableOpacity>
            <TouchableOpacity
              style={[S.fsCloseBtn, {
                backgroundColor: isDark ? 'rgba(255,255,255,0.15)' : 'rgba(0,0,0,0.15)',
              }]}
              onPress={onClose}
              activeOpacity={0.7}
            >
              <Text style={[S.fsCloseTxt, { color: isDark ? '#ffffff' : '#000000' }]}>✕</Text>
            </TouchableOpacity>
          </View>
        </GestureHandlerRootView>
  );
}

const S = StyleSheet.create({
  root:   { flex: 1 },

  ctxBar: {
    paddingHorizontal: Spacing.md,
    paddingVertical:   4,
    borderBottomWidth: 1,
  },
  ctxTxt: {
    fontSize: 9,
    fontFamily: Platform.OS === 'ios' ? 'Courier' : 'monospace',
  },

  toolbar: {
    flexDirection:  'row',
    alignItems:     'center',
    paddingRight:   Spacing.sm,
    borderBottomWidth: 1,
  },
  chRow:  { flexDirection: 'row', paddingHorizontal: Spacing.sm, paddingVertical: 6, gap: 5 },
  chBtn: {
    flexDirection:   'row',
    alignItems:      'center',
    gap:             4,
    paddingHorizontal: 8,
    paddingVertical:   5,
    borderRadius:    Radius.md,
    borderWidth:     1,
  },
  chDot:  { width: 6, height: 6, borderRadius: 3 },
  chTxt:  { fontSize: 10, fontWeight: '600' },
  logBtn: {
    paddingHorizontal: 9,
    paddingVertical:   5,
    borderRadius:      Radius.sm,
    borderWidth:       1,
    marginLeft:        4,
  },
  logTxt:    { fontSize: 10, fontWeight: '700', letterSpacing: 0.5 },
  fullBtn: {
    paddingHorizontal: 8,
    paddingVertical:   5,
    borderRadius:      Radius.sm,
    borderWidth:       1,
    marginLeft:        4,
  },
  fullTxt: { fontSize: 12 },

  fsRoot: { flex: 1 },
  fsToolbar: {
    position: 'absolute',
    top:      40,
    right:    12,
    flexDirection: 'row',
    gap:      8,
  },
  fsCloseBtn: {
    width:  36,
    height: 36,
    borderRadius: 18,
    alignItems:     'center',
    justifyContent: 'center',
  },
  fsCloseTxt: { fontSize: 16, fontWeight: '700' },

  chartWrap: { borderBottomWidth: StyleSheet.hairlineWidth },
  chartPlaceholder: {
    justifyContent:  'center',
    alignItems:      'center',
  },
  placeholderTxt: { fontSize: 13 },
});
