import React, { useState, useEffect, useMemo, useCallback } from 'react';
import {
  View, Text, FlatList, TouchableOpacity, Modal,
  StyleSheet, Alert, ActivityIndicator, Platform,
  useWindowDimensions, ScrollView,
} from 'react-native';
import { useDataStore } from '../../src/stores/dataStore';
import { useDeviceStore } from '../../src/stores/deviceStore';
import { exportCsv, shareFile } from '../../src/utils/export';
import { CHANNEL_COLORS } from '../../src/protocol/constants';
import { WaveformChart } from '../../src/components/WaveformChart';
import { computeWaveformData } from '../../src/hooks/useWaveform';
import { useTheme } from '../../src/design/tokens';
import { NoProjectGate } from '../../src/components/NoProjectGate';
import { SessionSelector } from '../../src/components/SessionSelector';
import * as StorageService from '../../src/services/StorageService';
import * as BinLoader from '../../src/services/BinLoader';
import type { PersistedFrame } from '../../src/services/StorageService';
import type { MeasurementFrame } from '../../src/protocol/types';

const MONO = { fontFamily: Platform.OS === 'ios' ? 'Courier' : 'monospace' } as const;

// ── Waveform modal ──────────────────────────────────────────────────────────

function FrameWaveformModal({ frame, onClose }: { frame: MeasurementFrame; onClose: () => void }) {
  const theme = useTheme();
  const { width } = useWindowDimensions();
  const sampleFreqCode = useDeviceStore((s) => s.config.sampleFreq);
  const [logScale, setLogScale] = useState(false);

  const visible = useMemo(() => Array(frame.meta?.channelNum ?? frame.adcUV.length).fill(true), [frame]);
  const data = useMemo(() => computeWaveformData(frame, visible, sampleFreqCode), [frame, visible, sampleFreqCode]);
  const CHART_H = Math.min(260, Math.round(width * 0.6));

  return (
    <Modal visible transparent animationType="slide" onRequestClose={onClose}>
      <View style={M.backdrop}>
        <View style={[M.sheet, { backgroundColor: theme.bg.surface }]}>
          <View style={M.header}>
            <Text style={[M.title, { color: theme.text.secondary }]}>帧 #{frame.frameId}</Text>
            <TouchableOpacity
              style={[M.scaleBtn, { borderColor: theme.bg.border, backgroundColor: theme.bg.raised }, !logScale && { borderColor: theme.blue.fg + '55', backgroundColor: theme.blue.bg }]}
              onPress={() => setLogScale((v) => !v)}
            >
              <Text style={[M.scaleTxt, { color: theme.text.muted }, !logScale && { color: theme.blue.fg }]}>{logScale ? 'LOG' : 'LIN'}</Text>
            </TouchableOpacity>
            <TouchableOpacity style={[M.closeBtn, { backgroundColor: theme.bg.border }]} onPress={onClose}>
              <Text style={[M.closeTxt, { color: theme.text.secondary }]}>✕</Text>
            </TouchableOpacity>
          </View>
          {data ? (
            <WaveformChart data={data} visibleChannels={visible} width={width - 32} height={CHART_H} logScale={logScale} />
          ) : (
            <View style={[{ height: CHART_H }, M.noData, { backgroundColor: theme.bg.raised }]}>
              <Text style={{ color: theme.text.muted }}>无波形数据</Text>
            </View>
          )}
        </View>
      </View>
    </Modal>
  );
}

// ── Table header ───────────────────────────────────────────────────────────

function TableHeader() {
  const theme = useTheme();
  const hdr = { color: theme.text.muted, fontSize: 9, fontWeight: '600' as const };
  return (
    <View style={[T.row, T.headerRow, { backgroundColor: theme.bg.raised, borderBottomColor: theme.bg.border }]}>
      <Text style={[hdr, T.colId]}>#</Text>
      <Text style={[hdr, T.colTime]}>时间</Text>
      <Text style={[hdr, T.colGps]}>GPS</Text>
      <Text style={[hdr, T.colCoord]}>经度</Text>
      <Text style={[hdr, T.colCoord]}>纬度</Text>
      <Text style={[hdr, T.colAcc]}>叠加</Text>
      <Text style={[hdr, T.colDel]} />
    </View>
  );
}

// ── Table row ──────────────────────────────────────────────────────────────

function TableRow({
  item,
  onPress,
  onDelete,
}: {
  item: PersistedFrame;
  onPress: () => void;
  onDelete: () => void;
}) {
  const theme = useTheme();
  const m = item.meta;

  const timeStr = m
    ? `${String(Math.floor(m.utc / 3600) % 24).padStart(2, '0')}:${String(Math.floor(m.utc / 60) % 60).padStart(2, '0')}:${String(m.utc % 60).padStart(2, '0')}`
    : '--';

  return (
    <TouchableOpacity style={[T.row, { borderBottomColor: theme.bg.divider }]} onPress={onPress} activeOpacity={0.6}>
      <Text style={[T.cell, T.colId, MONO, { color: theme.blue.fg }]}>{item.frameId}</Text>
      <Text style={[T.cell, T.colTime, MONO, { color: theme.text.secondary }]}>{timeStr}</Text>
      <Text style={[T.cell, T.colGps, { color: m && m.gpsStatus > 0 ? theme.green.fg : theme.red.fg, fontWeight: '700' }]}>
        {m && m.gpsStatus > 0 ? '✓' : '✗'}
      </Text>
      <Text style={[T.cell, T.colCoord, MONO, { color: theme.text.secondary }]} numberOfLines={1}>
        {m ? m.longitude.toFixed(5) : '--'}
      </Text>
      <Text style={[T.cell, T.colCoord, MONO, { color: theme.text.secondary }]} numberOfLines={1}>
        {m ? m.latitude.toFixed(5) : '--'}
      </Text>
      <Text style={[T.cell, T.colAcc, MONO, { color: theme.text.muted }]}>×{item.accNum}</Text>
      <TouchableOpacity style={T.colDel} onPress={onDelete} hitSlop={8}>
        <Text style={{ color: theme.red.fg, fontSize: 14, fontWeight: '700' }}>×</Text>
      </TouchableOpacity>
    </TouchableOpacity>
  );
}

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

export default function RecordsScreen() {
  const theme = useTheme();
  const {
    sessionId, projectId, hasProject, clearHistory, deleteFrame, resumeSession,
  } = useDataStore();
  const frameId = useDataStore((s) => s.currentFrame?.frameId ?? -1);
  const [exporting, setExporting] = useState(false);
  const [dbFrames, setDbFrames] = useState<PersistedFrame[]>([]);
  const [loadingDb, setLoadingDb] = useState(false);
  const [selectedFrame, setSelectedFrame] = useState<MeasurementFrame | null>(null);

  // ── Load frames from DB when sessionId changes or new frame arrives ──
  useEffect(() => {
    if (!sessionId) return;
    const timer = setTimeout(() => {
      setLoadingDb(true);
      StorageService.loadSessionFrames(sessionId)
        .then(setDbFrames)
        .finally(() => setLoadingDb(false));
    }, 300);
    return () => clearTimeout(timer);
  }, [sessionId, frameId]);

  const reloadDbFrames = useCallback(() => {
    if (!sessionId) return;
    setLoadingDb(true);
    StorageService.loadSessionFrames(sessionId)
      .then(setDbFrames)
      .finally(() => setLoadingDb(false));
  }, [sessionId]);

  // ── NoProjectGate ──
  if (!hasProject) {
    return <NoProjectGate />;
  }

  const handleExportAll = async () => {
    if (dbFrames.length === 0) { Alert.alert('无数据', '当前会话没有采集记录'); return; }
    setExporting(true);
    try {
      // Export uses in-memory history; for DB frames we pass them through
      const path = await exportCsv(dbFrames as any, sessionId);
      await shareFile(path);
    } catch (e: any) {
      Alert.alert('导出失败', e.message);
    } finally {
      setExporting(false);
    }
  };

  const handleClear = () =>
    Alert.alert('清空显示', '清空屏幕上的记录列表？（已保存的数据不受影响）', [
      { text: '取消', style: 'cancel' },
      { text: '清空', style: 'destructive', onPress: clearHistory },
    ]);

  const handleDeleteFrame = (item: PersistedFrame) => {
    Alert.alert(`删除 #${item.frameId}`, '确定删除？', [
      { text: '取消', style: 'cancel' },
      {
        text: '删除', style: 'destructive', onPress: () => {
          deleteFrame(item.frameId);
          reloadDbFrames();
        },
      },
    ]);
  };

  const handleSessionChange = async (newSessionId: string) => {
    await resumeSession(newSessionId, projectId);
  };

  const handleFramePress = async (pf: PersistedFrame) => {
    if (!pf.binPath) return;
    const loaded = await BinLoader.loadBinFile(pf.binPath);
    if (!loaded) { Alert.alert('加载失败', '无法读取波形文件'); return; }
    const frame: MeasurementFrame = {
      meta: pf.meta as any,
      adcRaw: [],
      adcUV: loaded.adcUV,
      accNum: pf.accNum,
      gain: pf.gain,
      sampleFreqCode: loaded.sampleFreqCode,
      timestamp: pf.timestamp,
      frameId: pf.frameId,
    };
    setSelectedFrame(frame);
  };

  return (
    <View style={[S.container, { backgroundColor: theme.bg.base }]}>
      {/* Session Selector */}
      <View style={S.selectorRow}>
        <SessionSelector
          selectedSessionId={sessionId}
          projectId={projectId!}
          onSelect={handleSessionChange}
        />
      </View>

      {/* Toolbar */}
      <View style={[S.toolbar, { backgroundColor: theme.bg.surface, borderBottomColor: theme.bg.border }]}>
        <View style={S.toolbarLeft}>
          <Text style={[S.count, { color: theme.text.secondary }]}>{dbFrames.length} 测点</Text>
        </View>
        <TouchableOpacity
          style={[S.toolBtn, { borderColor: theme.green.border, backgroundColor: theme.green.bg }, exporting && S.btnDisabled]}
          onPress={handleExportAll} disabled={exporting} activeOpacity={0.8}
        >
          {exporting
            ? <ActivityIndicator color={theme.green.fg} size="small" />
            : <Text style={[S.btnTxt, { color: theme.green.fg }]}>导出 CSV</Text>}
        </TouchableOpacity>
        <TouchableOpacity style={[S.toolBtn, { borderColor: theme.red.border, backgroundColor: theme.red.bg }]} onPress={handleClear} activeOpacity={0.8}>
          <Text style={[S.btnTxt, { color: theme.red.fg }]}>清空</Text>
        </TouchableOpacity>
      </View>

      {loadingDb ? (
        <View style={S.empty}>
          <ActivityIndicator size="large" color={theme.blue.fg} />
          <Text style={{ color: theme.text.ghost, fontSize: 13, marginTop: 12 }}>加载中...</Text>
        </View>
      ) : dbFrames.length === 0 ? (
        <View style={S.empty}>
          <Text style={{ color: theme.bg.border, fontSize: 40 }}>◌</Text>
          <Text style={{ color: theme.text.ghost, fontSize: 15 }}>暂无采集记录</Text>
          <Text style={{ color: theme.bg.border, fontSize: 12 }}>在波形页开始采集后，数据将显示在这里</Text>
        </View>
      ) : (
        <ScrollView horizontal showsHorizontalScrollIndicator>
          <View style={{ minWidth: '100%' }}>
            <TableHeader />
            <FlatList
              data={dbFrames}
              keyExtractor={(item) => String(item.frameId)}
              renderItem={({ item }) => (
                <TableRow
                  item={item}
                  onPress={() => handleFramePress(item)}
                  onDelete={() => handleDeleteFrame(item)}
                />
              )}
              getItemLayout={(_, index) => ({ length: 40, offset: 40 * index, index })}
            />
          </View>
        </ScrollView>
      )}

      {selectedFrame && (
        <FrameWaveformModal frame={selectedFrame} onClose={() => setSelectedFrame(null)} />
      )}
    </View>
  );
}

// ── Styles ──────────────────────────────────────────────────────────────────

const S = StyleSheet.create({
  container: { flex: 1 },
  selectorRow: {
    paddingHorizontal: 14, paddingTop: 10, paddingBottom: 4,
  },
  toolbar: {
    flexDirection: 'row', alignItems: 'center',
    paddingHorizontal: 14, paddingVertical: 10,
    borderBottomWidth: 1, gap: 8,
  },
  toolbarLeft: { flex: 1, gap: 2 },
  count:       { fontSize: 13, fontWeight: '700' },
  toolBtn:     { paddingHorizontal: 14, paddingVertical: 7, borderRadius: 8, borderWidth: 1 },
  btnTxt:      { fontSize: 12, fontWeight: '700' },
  btnDisabled: { opacity: 0.4 },
  empty:       { flex: 1, paddingVertical: 60, justifyContent: 'center', alignItems: 'center', gap: 10 },
});

const T = StyleSheet.create({
  row: {
    flexDirection: 'row',
    alignItems: 'center',
    height: 40,
    paddingHorizontal: 8,
    borderBottomWidth: StyleSheet.hairlineWidth,
  },
  headerRow: { height: 32, borderBottomWidth: 1 },
  cell:  { fontSize: 10, paddingHorizontal: 4 },
  colId:    { width: 36, textAlign: 'center' },
  colTime:  { width: 70 },
  colGps:   { width: 30, textAlign: 'center', fontSize: 12 },
  colCoord: { width: 80, textAlign: 'right' },
  colAcc:   { width: 40, textAlign: 'center' },
  colDel:   { width: 30, alignItems: 'center', justifyContent: 'center' },
});

const M = StyleSheet.create({
  backdrop: { flex: 1, backgroundColor: 'rgba(0,0,0,0.75)', justifyContent: 'flex-end' },
  sheet:    { borderTopLeftRadius: 20, borderTopRightRadius: 20, padding: 16, paddingBottom: 32 },
  header:   { flexDirection: 'row', alignItems: 'center', gap: 10, marginBottom: 12 },
  title:    { fontSize: 14, fontWeight: '700', flex: 1 },
  scaleBtn: { paddingHorizontal: 10, paddingVertical: 4, borderRadius: 6, borderWidth: 1 },
  scaleTxt: { fontSize: 11, fontWeight: '700' },
  closeBtn: { width: 28, height: 28, borderRadius: 14, alignItems: 'center', justifyContent: 'center' },
  closeTxt: { fontSize: 14 },
  noData:   { borderRadius: 8, alignItems: 'center', justifyContent: 'center' },
});
