import { useState, useCallback, useMemo, useEffect, useRef } from 'react';
import { View, Text } from '@tarojs/components';
import Taro, { useRouter } from '@tarojs/taro';
import { useThrottledDidShow } from '@/hooks/useThrottledDidShow';
import { BLEManager } from '@/services/ble/BLEManager';
import { XiaomiBandAdapter } from '@/services/ble/adapters/XiaomiBandAdapter';
import { BloodPressureAdapter } from '@/services/ble/adapters/BloodPressureAdapter';
import { GlucoseMeterAdapter } from '@/services/ble/adapters/GlucoseMeterAdapter';
import { CustomBandAdapter } from '@/services/ble/adapters/GenericBleAdapter';
import { DataSyncScheduler } from '@/services/ble/DataSyncScheduler';
import { uploadReadings } from '@/services/device-sync';
import { useAuthStore } from '@/stores/auth';
import type { BLEDevice, NormalizedReading } from '@/services/ble/types';
import { useElderClass } from '../../hooks/useElderClass';
import './index.scss';

/** liveReadings 最大保留条数，防止内存无限增长 */
const MAX_LIVE_READINGS = 200;

type PageState = 'idle' | 'scanning' | 'connecting' | 'connected' | 'syncing' | 'done' | 'error';

export default function DeviceSync() {
  const modeClass = useElderClass();
  const currentPatient = useAuthStore((s) => s.currentPatient);
  const router = useRouter();
  const returnTo = router.params.returnTo || '';
  const [pageState, setPageState] = useState<PageState>('idle');
  const [devices, setDevices] = useState<BLEDevice[]>([]);
  const [selectedDevice, setSelectedDevice] = useState<BLEDevice | null>(null);
  const [liveReadings, setLiveReadings] = useState<NormalizedReading[]>([]);
  const [syncCount, setSyncCount] = useState(0);
  const [errorMsg, setErrorMsg] = useState('');
  const [lastSyncAt, setLastSyncAt] = useState<number | null>(null);
  const [pendingCount, setPendingCount] = useState(0);

  const scheduler = useMemo(() => new DataSyncScheduler({
    intervalMs: 60 * 60 * 1000,
  }), []);

  const bleManagerRef = useRef<BLEManager | null>(null);
  const getBleManager = useCallback(() => {
    if (!bleManagerRef.current) {
      const mgr = new BLEManager({ scanTimeout: 10000, retryCount: 3 });
      mgr.registerAdapter(XiaomiBandAdapter);
      mgr.registerAdapter(BloodPressureAdapter);
      mgr.registerAdapter(GlucoseMeterAdapter);
      mgr.registerAdapter(CustomBandAdapter);
      bleManagerRef.current = mgr;
    }
    return bleManagerRef.current;
  }, []);

  useThrottledDidShow(() => {
    const bleManager = getBleManager();
    bleManager.setOnConnectionChange(() => {});
    bleManager.setOnReadings((readings) => {
      setLiveReadings((prev) => {
        const merged = [...prev, ...readings];
        return merged.length > MAX_LIVE_READINGS ? merged.slice(-MAX_LIVE_READINGS) : merged;
      });
    });

    // 显示上次同步时间
    setLastSyncAt(scheduler.getLastSyncAt());

    // 检查是否有未上传的缓冲数据
    const buffer = (bleManager as any).dataBuffer;
    if (buffer) {
      setPendingCount(buffer.size());
    }

    // 自动同步：超过间隔时尝试上传缓冲数据
    if (currentPatient && scheduler.needsSync()) {
      scheduler.tryAutoSync(async () => {
        const count = await bleManager.flushPendingReadings(async (readings) => {
          return uploadReadings(currentPatient.id, 'buffered', undefined, readings);
        });
        setLastSyncAt(Date.now());
        setPendingCount(0);
        return { success: count > 0, uploadedCount: count };
      });
    }
  }, 10000);

  useEffect(() => {
    return () => {
      scheduler.destroy();
      if (bleManagerRef.current) {
        bleManagerRef.current.destroy();
        bleManagerRef.current = null;
      }
    };
  }, [scheduler]);

  const handleScan = useCallback(async () => {
    setPageState('scanning');
    setDevices([]);
    setErrorMsg('');
    try {
      const found = await getBleManager().scanDevices();
      setDevices(found);
      if (found.length === 0) {
        setErrorMsg('未发现支持的设备，请确认设备已开启蓝牙并靠近手机');
      }
      setPageState('idle');
    } catch (e: any) {
      setErrorMsg(e.message || '扫描失败');
      setPageState('error');
    }
  }, []);

  const handleConnect = useCallback(async (device: BLEDevice) => {
    setSelectedDevice(device);
    setPageState('connecting');
    setErrorMsg('');
    try {
      await getBleManager().connect(device);
      setPageState('connected');
    } catch (e: any) {
      setErrorMsg(e.message || '连接失败');
      setPageState('error');
    }
  }, []);

  const handleSync = useCallback(async () => {
    if (!currentPatient || !selectedDevice) return;

    setPageState('syncing');
    setErrorMsg('');

    try {
      const result = await getBleManager().syncToServer(async (readings) => {
        return uploadReadings(
          currentPatient.id,
          selectedDevice.deviceId,
          selectedDevice.name,
          readings,
        );
      });

      if (result.success) {
        setSyncCount(result.uploadedCount);
        setLastSyncAt(Date.now());
        setPageState('done');

        // 如果从体征录入页跳转而来，将最新读数写入 storage 供回填
        if (returnTo === 'input' && liveReadings.length > 0) {
          const mapped: Record<string, number> = {};
          for (const r of liveReadings) {
            if (r.device_type === 'blood_pressure') {
              if (r.metric === 'systolic' && typeof r.values.value === 'number') mapped.systolic = r.values.value;
              if (r.metric === 'diastolic' && typeof r.values.value === 'number') mapped.diastolic = r.values.value;
              // 兼容 values 中直接包含 systolic/diastolic 的格式
              if (typeof r.values.systolic === 'number') mapped.systolic = r.values.systolic as number;
              if (typeof r.values.diastolic === 'number') mapped.diastolic = r.values.diastolic as number;
            } else if (r.device_type === 'blood_glucose' && typeof r.values.blood_glucose === 'number') {
              mapped.blood_sugar = r.values.blood_glucose as number;
            } else if (r.device_type === 'heart_rate' && typeof r.values.heart_rate === 'number') {
              mapped.heart_rate = r.values.heart_rate as number;
            }
          }
          if (Object.keys(mapped).length > 0) {
            Taro.setStorageSync('device_sync_result', JSON.stringify(mapped));
          }
        }
      } else {
        setErrorMsg(result.error || '同步失败');
        setPageState('error');
      }
    } catch (e: any) {
      setErrorMsg(e.message || '同步失败');
      setPageState('error');
    }
  }, [currentPatient, selectedDevice, liveReadings, returnTo]);

  const handleDisconnect = useCallback(async () => {
    await getBleManager().disconnect();
    setPageState('idle');
    setSelectedDevice(null);
    setLiveReadings([]);
    setSyncCount(0);
    setErrorMsg('');
  }, []);

  const renderIdle = () => (
    <View className="sync-section">
      <View className="sync-hero">
        <Text className="sync-hero-icon">D</Text>
        <Text className="sync-hero-title">设备同步</Text>
        <Text className="sync-hero-desc">连接智能手环、血压计、血糖仪，自动采集健康数据</Text>
      </View>

      {(lastSyncAt || pendingCount > 0) && (
        <View className="sync-status-info">
          {lastSyncAt && (
            <Text className="sync-status-time">
              上次同步: {new Date(lastSyncAt).toLocaleTimeString()}
            </Text>
          )}
          {pendingCount > 0 && (
            <Text className="sync-status-pending">
              {pendingCount} 条数据待上传
            </Text>
          )}
        </View>
      )}

      <View className="sync-action" onClick={handleScan}>
        <Text className="sync-action-text">扫描设备</Text>
      </View>

      {devices.length > 0 && (
        <View className="sync-device-list">
          <Text className="sync-section-title">发现的设备</Text>
          {devices.map((d) => (
            <View
              key={d.deviceId}
              className="sync-device-item"
              onClick={() => handleConnect(d)}
            >
              <View className="sync-device-info">
                <Text className="sync-device-name">{d.name}</Text>
                <Text className="sync-device-adapter">{d.adapter?.name}</Text>
              </View>
              <Text className="sync-device-rssi">信号 {d.RSSI > -60 ? '强' : d.RSSI > -80 ? '中' : '弱'}</Text>
            </View>
          ))}
        </View>
      )}
    </View>
  );

  const renderConnected = () => (
    <View className="sync-section">
      <View className="sync-status-card">
        <Text className="sync-status-dot sync-status-dot--connected" />
        <Text className="sync-status-text">已连接: {selectedDevice?.name}</Text>
      </View>

      {liveReadings.length > 0 && (
        <View className="sync-readings-panel">
          <Text className="sync-section-title">实时数据</Text>
          {liveReadings.slice(-5).reverse().map((r, i) => (
            <View key={i} className="sync-reading-item">
              <Text className="sync-reading-type">
                {r.device_type === 'heart_rate' ? '心率'
                  : r.device_type === 'blood_pressure' ? `血压(${r.metric === 'systolic' ? '收缩压' : r.metric === 'diastolic' ? '舒张压' : 'MAP'})`
                  : r.device_type === 'blood_glucose' ? '血糖'
                  : r.device_type}
              </Text>
              <Text className="sync-reading-value">
                {r.device_type === 'heart_rate'
                  ? `${r.values.heart_rate} bpm`
                  : r.metric
                    ? `${r.values.value} ${r.values.unit}`
                    : JSON.stringify(r.values)}
              </Text>
            </View>
          ))}
          <Text className="sync-readings-count">
            已采集 {liveReadings.length} 条数据
          </Text>
        </View>
      )}

      <View className="sync-actions-row">
        <View className="sync-action sync-action--primary" onClick={handleSync}>
          <Text className="sync-action-text">上传数据</Text>
        </View>
        <View className="sync-action sync-action--danger" onClick={handleDisconnect}>
          <Text className="sync-action-text">断开连接</Text>
        </View>
      </View>
    </View>
  );

  const renderDone = () => (
    <View className="sync-section">
      <View className="sync-result-card">
        <Text className="sync-result-icon">V</Text>
        <Text className="sync-result-title">同步完成</Text>
        <Text className="sync-result-count">成功上传 {syncCount} 条数据</Text>
      </View>
      <View className="sync-action" onClick={() => {
        handleDisconnect();
        if (returnTo === 'input') {
          Taro.navigateBack();
        }
      }}>
        <Text className="sync-action-text">{returnTo === 'input' ? '返回录入' : '完成'}</Text>
      </View>
    </View>
  );

  return (
    <View className={`device-sync-page ${modeClass}`}>
      <View className="sync-header">
        <Text className="sync-header-title">设备同步</Text>
      </View>

      {errorMsg && (
        <View className="sync-error">
          <Text className="sync-error-text">{errorMsg}</Text>
        </View>
      )}

      {(pageState === 'scanning' || pageState === 'connecting' || pageState === 'syncing') && (
        <View className="sync-loading">
          <Text className="sync-loading-text">
            {pageState === 'scanning' && '正在扫描设备...'}
            {pageState === 'connecting' && '正在连接设备...'}
            {pageState === 'syncing' && '正在上传数据...'}
          </Text>
        </View>
      )}

      {(pageState === 'idle' || pageState === 'error') && renderIdle()}
      {pageState === 'connected' && renderConnected()}
      {pageState === 'done' && renderDone()}
    </View>
  );
}
