import React, { useState, useEffect, useMemo } from 'react';
import {
  View, Text, StyleSheet, TouchableOpacity, ScrollView,
  Modal, ActivityIndicator, useWindowDimensions, Platform,
} from 'react-native';
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 } from '../../src/hooks/useWaveform';
import { WaveformChart } from '../../src/components/WaveformChart';
import { ParamForm } from '../../src/components/ParamForm';
import { CHANNEL_COLORS } from '../../src/protocol/constants';
import { formatUV, formatUtc, formatCoord } from '../../src/utils/format';
import { Colors, Spacing, Radius } from '../../src/design/tokens';
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 { 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}>
        <View style={PS.handle} />

        <View style={PS.header}>
          <Text style={PS.title}>采集参数</Text>
          {configDirty && (
            <View style={PS.dirtyBadge}>
              <Text style={PS.dirtyTxt}>待下发</Text>
            </View>
          )}
        </View>

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

        <TouchableOpacity
          style={[
            PS.setupBtn,
            configDirty && PS.setupBtnDirty,
            (busy || measuring) && PS.setupBtnDis,
          ]}
          onPress={onSetup}
          disabled={busy || measuring}
          activeOpacity={0.8}
        >
          {busy
            ? <ActivityIndicator color={Colors.blue.fg} />
            : <Text style={[PS.setupBtnTxt, configDirty && PS.setupBtnTxtDirty]}>
                {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%',
    backgroundColor:     Colors.bg.surface,
    borderTopLeftRadius:  Radius.xl,
    borderTopRightRadius: Radius.xl,
    borderTopWidth: 1,
    borderColor:    Colors.bg.border,
    paddingBottom:  Spacing.xxl,
  },
  handle: {
    width: 36, height: 4, borderRadius: 2,
    backgroundColor: Colors.bg.border,
    alignSelf: 'center',
    marginTop: Spacing.sm, marginBottom: Spacing.sm,
  },
  header:     { flexDirection: 'row', alignItems: 'center', paddingHorizontal: Spacing.lg, paddingBottom: Spacing.sm, gap: Spacing.sm },
  title:      { color: Colors.text.secondary, fontSize: 14, fontWeight: '700', flex: 1 },
  dirtyBadge: { backgroundColor: Colors.amber.bg, borderRadius: Radius.sm, paddingHorizontal: 7, paddingVertical: 2, borderWidth: 1, borderColor: Colors.amber.border },
  dirtyTxt:   { color: Colors.amber.fg, fontSize: 9, fontWeight: '700' },
  scroll:     { flex: 1 },
  setupBtn: {
    margin: Spacing.lg,
    backgroundColor: Colors.bg.raised,
    borderRadius: Radius.lg,
    paddingVertical: 14,
    alignItems: 'center',
    borderWidth: 1,
    borderColor: Colors.bg.border,
  },
  setupBtnDirty:    { backgroundColor: Colors.blue.bg, borderColor: Colors.blue.fg },
  setupBtnDis:      { opacity: 0.4 },
  setupBtnTxt:      { color: Colors.text.muted, fontWeight: '700', fontSize: 14, letterSpacing: 3 },
  setupBtnTxtDirty: { color: Colors.blue.fg },
});

// ── 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 idle    = deviceStatus === 'idle';
  const running = deviceStatus === 'running';
  const single  = deviceStatus === 'single';

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

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

      {/* Running indicator (running only) */}
      {running && frameId !== undefined && (
        <View style={CR.indicator}>
          <View style={CR.runDot} />
          <Text style={CR.indicatorTxt}>#{frameId}</Text>
        </View>
      )}

      {/* Settings button — always present */}
      <TouchableOpacity style={CR.settingsBtn} onPress={onSettings} activeOpacity={0.8}>
        <Text style={[CR.settingsTxt, configDirty && CR.settingsDirty]}>⚙</Text>
        {configDirty && <View style={CR.dirtyDot} />}
      </TouchableOpacity>
    </View>
  );
}

const CR = StyleSheet.create({
  row: {
    flexDirection:  'row',
    alignItems:     'center',
    paddingHorizontal: Spacing.md,
    paddingVertical:   Spacing.sm,
    gap:            Spacing.sm,
    borderTopWidth: 1,
    borderTopColor: Colors.bg.border,
    backgroundColor: Colors.bg.surface,
  },
  primary: {
    flex: 2,
    flexDirection:   'row',
    alignItems:      'center',
    justifyContent:  'center',
    gap:             8,
    paddingVertical: 14,
    borderRadius:    Radius.lg,
    borderWidth:     1,
  },
  green:   { backgroundColor: Colors.green.bg, borderColor: Colors.green.border },
  red:     { backgroundColor: Colors.red.bg,   borderColor: Colors.red.border   },
  teal:    { backgroundColor: Colors.teal.bg,  borderColor: Colors.teal.border  },
  dis:     { opacity: 0.35 },
  primaryIcon: { fontSize: 11, color: '#ffffff88' },
  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,
  },
  tealBtn:      { backgroundColor: Colors.teal.bg, borderColor: Colors.teal.border },
  secondaryIcon:{ fontSize: 11, color: '#ffffff66' },
  secondaryTxt: { fontSize: 12, fontWeight: '700' },

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

  settingsBtn: {
    width: 44, height: 44,
    borderRadius: Radius.md,
    backgroundColor: Colors.bg.raised,
    borderWidth: 1, borderColor: Colors.bg.border,
    alignItems: 'center', justifyContent: 'center',
  },
  settingsTxt:   { fontSize: 18, color: Colors.text.muted },
  settingsDirty: { color: Colors.amber.fg },
  dirtyDot: {
    position: 'absolute', top: 6, right: 6,
    width: 7, height: 7, borderRadius: 4,
    backgroundColor: Colors.amber.fg,
    borderWidth: 1, borderColor: Colors.bg.surface,
  },
});

// ── Peak row ──────────────────────────────────────────────────────────────────

function PeakRow({ frame, visible, channelNum }: { frame: MeasurementFrame; visible: boolean[]; channelNum: number }) {
  return (
    <ScrollView horizontal showsHorizontalScrollIndicator={false} style={PK.scroll}>
      <View style={PK.row}>
        {frame.adcUV.map((ch, i) => {
          if (i >= channelNum || !visible[i]) return null;
          const pk = ch.reduce((m, v) => Math.max(m, Math.abs(v)), 0);
          return (
            <View key={i} style={PK.cell}>
              <View style={[PK.dot, { backgroundColor: CHANNEL_COLORS[i] }]} />
              <Text style={PK.label}>CH{i + 1}</Text>
              <Text style={[PK.value, { color: CHANNEL_COLORS[i] + 'cc' }]}>{formatUV(pk)}</Text>
            </View>
          );
        })}
      </View>
    </ScrollView>
  );
}

const PK = StyleSheet.create({
  scroll: { borderTopWidth: StyleSheet.hairlineWidth, borderTopColor: Colors.bg.divider },
  row:    { flexDirection: 'row', paddingHorizontal: Spacing.md, paddingVertical: 7, gap: 10 },
  cell:   { flexDirection: 'row', alignItems: 'center', gap: 4, backgroundColor: Colors.bg.surface, borderRadius: Radius.sm, paddingHorizontal: 8, paddingVertical: 4, borderWidth: 1, borderColor: Colors.bg.border },
  dot:    { width: 5, height: 5, borderRadius: 3 },
  label:  { color: Colors.text.ghost, fontSize: 9, fontWeight: '600' },
  value:  { fontSize: 11, fontWeight: '600', fontFamily: Platform.OS === 'ios' ? 'Courier' : 'monospace' },
});

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

function FrameSummaryBar({ frame }: { frame: MeasurementFrame }) {
  const m = frame.meta;
  return (
    <View style={FS.bar}>
      <Text style={FS.txt}>
        #{frame.frameId}
        {'  '}×{frame.accNum}叠
        {m ? `  ${formatUtc(m.utc)}` : ''}
        {m && m.latitude ? `  ${formatCoord(m.latitude, false)} ${formatCoord(m.longitude, true)}` : ''}
      </Text>
    </View>
  );
}

const FS = StyleSheet.create({
  bar: { paddingHorizontal: Spacing.md, paddingVertical: 5, backgroundColor: Colors.bg.void, borderTopWidth: StyleSheet.hairlineWidth, borderTopColor: Colors.bg.divider },
  txt: { color: Colors.text.ghost, fontSize: 9, fontFamily: Platform.OS === 'ios' ? 'Courier' : 'monospace' },
});

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

function NotConnected({ onConnect }: { onConnect: () => void }) {
  return (
    <View style={NC.root}>
      <Text style={NC.icon}>◈</Text>
      <Text style={NC.title}>未连接仪器</Text>
      <Text style={NC.sub}>请先连接 TEM 接收机</Text>
      <TouchableOpacity style={NC.btn} onPress={onConnect} activeOpacity={0.8}>
        <Text style={NC.btnTxt}>连  接  设  备</Text>
      </TouchableOpacity>
    </View>
  );
}

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

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

export default function WaveScreen() {
  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 [visible,      setVisible]      = useState(() => Array(6).fill(true));
  const [logScale,     setLogScale]     = useState(true);
  const [sheetVisible, setSheetVisible] = useState(false);
  const [projectName,  setProjectName]  = useState<string | null>(null);

  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)),
    );
  }, [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}>
        <NotConnected onConnect={showModal} />
      </View>
    );
  }

  return (
    <View style={S.root}>

      {/* ── Context bar: project · session ── */}
      <View style={S.ctxBar}>
        {projectName
          ? <Text style={S.ctxTxt} numberOfLines={1}>{projectName}  ·  {sessionId}</Text>
          : <Text style={S.ctxTxt} numberOfLines={1}>{sessionId}</Text>}
      </View>

      {/* ── Channel selector + LOG/LIN ── */}
      <View style={S.toolbar}>
        <ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={S.chRow}>
          {Array.from({ length: channelNum }, (_, i) => (
            <TouchableOpacity
              key={i}
              style={[
                S.chBtn,
                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] : Colors.bg.border }]} />
              <Text style={[S.chTxt, visible[i] && { color: CHANNEL_COLORS[i] }]}>CH{i + 1}</Text>
            </TouchableOpacity>
          ))}
        </ScrollView>
        <TouchableOpacity
          style={[S.logBtn, !logScale && S.logBtnOn]}
          onPress={() => setLogScale((v) => !v)}
          activeOpacity={0.7}
        >
          <Text style={[S.logTxt, !logScale && S.logTxtOn]}>{logScale ? 'LOG' : 'LIN'}</Text>
        </TouchableOpacity>
      </View>

      {/* ── Waveform chart ── */}
      <View style={S.chartWrap}>
        {data ? (
          <WaveformChart
            data={data}
            visibleChannels={visible}
            width={sw}
            height={CHART_H}
            logScale={logScale}
          />
        ) : (
          <View style={[S.chartPlaceholder, { height: CHART_H }]}>
            <Text style={S.placeholderTxt}>等待采样数据…</Text>
          </View>
        )}
      </View>

      {/* ── Peak values ── */}
      {frame && <PeakRow frame={frame} visible={visible} channelNum={channelNum} />}

      {/* ── Frame summary ── */}
      {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}
      />
    </View>
  );
}

const S = StyleSheet.create({
  root:   { flex: 1, backgroundColor: Colors.bg.base },

  ctxBar: {
    paddingHorizontal: Spacing.md,
    paddingVertical:   4,
    backgroundColor:   Colors.bg.void,
    borderBottomWidth: 1,
    borderBottomColor: Colors.bg.divider,
  },
  ctxTxt: {
    color: Colors.text.ghost,
    fontSize: 9,
    fontFamily: Platform.OS === 'ios' ? 'Courier' : 'monospace',
  },

  toolbar: {
    flexDirection:  'row',
    alignItems:     'center',
    paddingRight:   Spacing.sm,
    borderBottomWidth: 1,
    borderBottomColor: Colors.bg.divider,
  },
  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,
    borderColor:     Colors.bg.border,
  },
  chDot:  { width: 6, height: 6, borderRadius: 3 },
  chTxt:  { color: Colors.text.ghost, fontSize: 10, fontWeight: '600' },
  logBtn: {
    paddingHorizontal: 9,
    paddingVertical:   5,
    borderRadius:      Radius.sm,
    borderWidth:       1,
    borderColor:       Colors.bg.border,
    backgroundColor:   Colors.bg.raised,
    marginLeft:        4,
  },
  logBtnOn:  { borderColor: Colors.blue.border, backgroundColor: Colors.blue.bg },
  logTxt:    { color: Colors.text.muted, fontSize: 10, fontWeight: '700', letterSpacing: 0.5 },
  logTxtOn:  { color: Colors.blue.fg },

  chartWrap: { borderBottomWidth: StyleSheet.hairlineWidth, borderBottomColor: Colors.bg.divider },
  chartPlaceholder: {
    backgroundColor: Colors.bg.surface,
    justifyContent:  'center',
    alignItems:      'center',
  },
  placeholderTxt: { color: Colors.text.ghost, fontSize: 13 },
});
