// InfoScreen.tsx此页面为功率计信息页面
import React, { useEffect, useState, useRef } from "react";
import {
  View,
  Text as RNText,
  TextInput,
  ScrollView,
  StyleSheet,
  ActivityIndicator,
  Alert,
  Pressable,
} from "react-native";
import { useFocusEffect } from "@react-navigation/native";
import { NativeStackScreenProps } from "@react-navigation/native-stack";
import { RootStackParamList } from "../App";
import {
  Central,
  ScannedPeripheral,
  ConnectionStatus,
} from "@systemic-games/react-native-bluetooth-le";
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import { useTranslation } from 'react-i18next';
import MyStatusbar from "./component/MyStatusbar";
import MyHeader from "./component/MyHeader";
import { THEME } from "./theme";


type Props = NativeStackScreenProps<RootStackParamList, "Info">;

const powerServiceUuid = "fff1";
const powerWriteUuid = "fff2";
const powerNotifyUuid = "fff3";

const fullUUID = (uuid: string) =>
  uuid.length === 4
    ? `0000${uuid}-0000-1000-8000-00805f9b34fb`
    : uuid;

const Text = ({ children, style, ...props }: any) => {
  return (
    <RNText
      style={[{ color: '#000000', fontSize: 16 }, style]}
      {...props}
    >
      {children}
    </RNText>
  );
};

export default function InfoScreen({ route, navigation }: Props) {
  const { t } = useTranslation();
  const { peripheral } = route.params;
  const deviceKey = peripheral.address || peripheral.systemId;

  const [power, setPower] = useState<number>(0);
  const [cadence, setCadence] = useState<number>(0);
  const [leftbalance, setLeftBalance] = useState<number>(0);
  const [rightbalance, setRightBalance] = useState<number>(0);

  const [isConnected, setIsConnected] = useState(false);
  const [isDeviceReady, setIsDeviceReady] = useState(false);
  const [isLoading, setIsLoading] = useState(true);
  const [serial, setSerial] = useState(t('info.reading'));
  const [firmware, setFirmware] = useState(t('info.reading'));
  const [hardware, setHardware] = useState(t('info.reading'));
  const [battery, setBattery] = useState(t('info.reading'));
  const [powerTrim, setPowerTrim] = useState(t('info.reading'));
  const [inputTrim, setInputTrim] = useState("");

  const [readSuccessToast, setReadSuccessToast] = useState(false); // ✅ 读取成功提示
  const [powerTrimLoading, setPowerTrimLoading] = useState(false);  // 正在写入功率微调
  const [powerTrimSuccessToast, setPowerTrimSuccessToast] = useState(false); // 功率微调写入成功


  const notifySubscribedRef = useRef(false);
  const disconnectingRef = useRef(false);
  const skipDisconnectOnLeaveRef = useRef(false);
  const mountedRef = useRef(true);
  const deviceReadyRef = useRef(false);
  const readyResolverRef = useRef<(() => void) | null>(null);
  const readSuccessTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const powerDataSubscribedRef = useRef(false);
  const initialInfoLoadedRef = useRef(false);

  const prevConnectedRef = useRef(isConnected);
  const isActiveRef = useRef(true);

  //增加校准按钮相关状态
  const [calibrating, setCalibrating] = useState<boolean>(false);
  const [calibrationSuccess, setCalibrationSuccess] = useState<boolean>(false);
  const [calibrationValue, setCalibrationValue] = useState<string>("");
  const calibrationTimeoutRef = useRef<number | null>(null);
  const isCalibratingRef = useRef<boolean>(false);

  const sleep = (ms: number) =>
    new Promise<void>((resolve) => setTimeout(resolve, ms));

  const toUint8Array = (raw: unknown): Uint8Array | null => {
    if (!raw) return null;
    if (raw instanceof Uint8Array) return raw;
    if (raw instanceof ArrayBuffer) return new Uint8Array(raw);
    if (Array.isArray(raw)) return new Uint8Array(raw);

    if (
      typeof raw === "object" &&
      raw !== null &&
      "buffer" in raw &&
      (raw as { buffer?: unknown }).buffer instanceof ArrayBuffer
    ) {
      const view = raw as {
        buffer: ArrayBuffer;
        byteOffset?: number;
        byteLength?: number;
      };
      return new Uint8Array(
        view.buffer,
        view.byteOffset || 0,
        view.byteLength
      );
    }

    return null;
  };

  const decodeTextValue = (raw: unknown) => {
    const bytes = toUint8Array(raw);
    if (!bytes || bytes.length === 0) return null;

    const text = String.fromCharCode(...Array.from(bytes))
      .replace(/\0/g, "")
      .trim();

    return text || null;
  };

  const waitForDeviceReady = (timeoutMs = 6000) =>
    new Promise<void>((resolve, reject) => {
      if (deviceReadyRef.current) {
        resolve();
        return;
      }

      const timer = setTimeout(() => {
        if (readyResolverRef.current === onReady) {
          readyResolverRef.current = null;
        }
        reject(new Error("device ready timeout"));
      }, timeoutMs);

      const onReady = () => {
        clearTimeout(timer);
        if (readyResolverRef.current === onReady) {
          readyResolverRef.current = null;
        }
        resolve();
      };

      readyResolverRef.current = onReady;
    });

  const readCharacteristicWithRetry = async (
    serviceUuid: string,
    characteristicUuid: string,
    attempts = 3,
    delayMs = 180
  ) => {
    let lastError: unknown;

    for (let attempt = 0; attempt < attempts; attempt += 1) {
      try {
        const value = await Central.readCharacteristic(
          peripheral,
          fullUUID(serviceUuid),
          fullUUID(characteristicUuid)
        );
        const bytes = toUint8Array(value);

        if (bytes && bytes.length > 0) {
          return bytes;
        }

        lastError = new Error("empty characteristic value");
      } catch (err) {
        lastError = err;
      }

      if (attempt < attempts - 1) {
        await sleep(delayMs);
      }
    }

    throw lastError ?? new Error("read characteristic failed");
  };

  const readTextCharacteristic = async (serviceUuid: string, characteristicUuid: string) => {
    for (let attempt = 0; attempt < 3; attempt += 1) {
      try {
        const bytes = await readCharacteristicWithRetry(
          serviceUuid,
          characteristicUuid,
          1
        );
        const text = decodeTextValue(bytes);

        if (text) {
          return text;
        }
      } catch {
        // Continue retrying with a short gap below.
      }

      if (attempt < 2) {
        await sleep(180);
      }
    }

    return "未知";
  };

  const readBatteryCharacteristic = async () => {
    const validSamples: number[] = [];

    // Some devices briefly report a default battery value right after the first
    // connection. Read a few samples and prefer the later stable value.
    await sleep(250);

    for (let attempt = 0; attempt < 5; attempt += 1) {
      try {
        const bytes = await readCharacteristicWithRetry("180f", "2a19", 1);
        const batteryValue = bytes[0];

        if (
          Number.isInteger(batteryValue) &&
          batteryValue >= 0 &&
          batteryValue <= 100
        ) {
          validSamples.push(batteryValue);
          console.log(
            `🔋 battery sample ${attempt + 1}: ${batteryValue}%`
          );
        }
      } catch {
        // Continue retrying with a short gap below.
      }

      if (attempt < 4) {
        await sleep(260);
      }
    }

    if (validSamples.length === 0) {
      return "未知";
    }

    const lastSample = validSamples[validSamples.length - 1];
    const previousSample = validSamples[validSamples.length - 2];

    if (previousSample !== undefined && previousSample === lastSample) {
      return `${lastSample}%`;
    }

    const lastNonHundredSample = [...validSamples]
      .reverse()
      .find((value) => value !== 100);

    return `${lastNonHundredSample ?? lastSample}%`;
  };

  const subscribePowerDataIfNeeded = async () => {
    if (!deviceReadyRef.current || !initialInfoLoadedRef.current || powerDataSubscribedRef.current) {
      return;
    }

    console.log("✅ 订阅 2A63 特性通知...");

    await Central.unsubscribeCharacteristic(
      peripheral,
      fullUUID("1818"),
      fullUUID("2a63")
    ).catch(() => {});

    await Central.subscribeCharacteristic(
      peripheral,
      fullUUID("1818"),
      fullUUID("2a63"),
      (notifyEv) => {
        try {
          const byteArray = toUint8Array(notifyEv.value);
          if (!byteArray) return;
          parseData(byteArray);
        } catch (err) {
          console.warn("❌ 处理通知数据失败", err);
        }
      }
    );

    powerDataSubscribedRef.current = true;
    console.log("✅ 已订阅 2A63 特性通知");
  };

  const subscribeFff3IfNeeded = async () => {
    if (notifySubscribedRef.current) return;

    console.log("✅ device ready - subscribe notify FFF3");
    await Central.unsubscribeCharacteristic(
      peripheral,
      fullUUID(powerServiceUuid),
      fullUUID(powerNotifyUuid)
    ).catch(() => {});

    await Central.subscribeCharacteristic(
      peripheral,
      fullUUID(powerServiceUuid),
      fullUUID(powerNotifyUuid),
      (notifyEv) => {
        try {
          const raw = (notifyEv as any).value;
          const byteArray = toUint8Array(raw);
          if (!byteArray) return;
          if (byteArray[0] === 0x02 && byteArray.length >= 2) {
            const rawTrim =
              byteArray.length >= 3
                ? byteArray[1] | (byteArray[2] << 8)
                : byteArray[1];
            const displayTrim =
              byteArray.length >= 3
                ? (rawTrim / 100).toFixed(2).replace(/\.?0+$/, "")
                : rawTrim.toString();

            setPowerTrim(displayTrim);
          } else if (byteArray[0] === 0x05 && byteArray.length >= 3) {
            handleFFF3Response(byteArray);
          }
        } catch (err) {
          console.warn("notify parse error", err);
        }
      }
    );

    notifySubscribedRef.current = true;
    console.log("✅ notify 已订阅");
  };

  useFocusEffect(
    React.useCallback(() => {
      // 页面获得焦点
      isActiveRef.current = true;
      return () => {
        // 页面失去焦点
        isActiveRef.current = false;
      };
    }, [])
  );


  // ========== 监听连接状态变化，断开时提示重新连接 ==========
  useEffect(() => {
    if (prevConnectedRef.current && !isConnected && isActiveRef.current) {
      if (skipDisconnectOnLeaveRef.current) {
        prevConnectedRef.current = isConnected;
        return;
      }
      Alert.alert(t('info.disconnectTitle'), t('info.disconnectMessage'), [
        { text: t('info.confirm'), onPress: () => navigation.goBack() },
      ]);
    }
    prevConnectedRef.current = isConnected;
  }, [isConnected]);

  // ========== 页面即将返回时，强制断开蓝牙 ==========
  useEffect(() => {
    const unsubscribe = navigation.addListener("beforeRemove", async (e) => {
      if (skipDisconnectOnLeaveRef.current) return;
      if (disconnectingRef.current) return;
      disconnectingRef.current = true;

      const next = e.data.action?.type;
      const action = e.data.action as any;

      // ✅ 判断是否跳转到 Dfu 页面
      if (next === "NAVIGATE" && action?.payload?.name === "Dfu") {
        console.log("➡️ 跳转到 DFU，不断开蓝牙");
        disconnectingRef.current = false;
        return;
      }

      // 🔌 其他页面离开则断开蓝牙
      console.log("📴 页面关闭，断开蓝牙...");
      try {
        await Central.disconnectPeripheral(peripheral);
        console.log("✅ 已断开蓝牙");
      } catch (err) {
        console.warn("❌ 断开失败：", err);
      } finally {
        disconnectingRef.current = false;
      }
    });
    return unsubscribe;
  }, [navigation, peripheral]);

  // ========== BLE notify 订阅FFF3 ==========
  useEffect(() => {
    const connectionHandler = async (ev: {
      peripheral: ScannedPeripheral;
      connectionStatus: ConnectionStatus;
    }) => {
      const addr = ev.peripheral.address || ev.peripheral.systemId;
      if (addr !== deviceKey) return;

      console.log("🔌 connection event:", ev.connectionStatus);
      const connected =
        ev.connectionStatus === "connected" || ev.connectionStatus === "ready";
      const isReady = ev.connectionStatus === "ready";

      if (skipDisconnectOnLeaveRef.current && !connected) {
        console.log("⏭️ DFU flow disconnect ignored on InfoScreen");
        setIsConnected(false);
        setIsDeviceReady(false);
        deviceReadyRef.current = false;
        notifySubscribedRef.current = false;
        powerDataSubscribedRef.current = false;
        return;
      }

      setIsConnected(connected);
      setIsDeviceReady(isReady);
      deviceReadyRef.current = isReady;

      if (!isReady) {
        notifySubscribedRef.current = false;
        powerDataSubscribedRef.current = false;
      }

      if (isReady && readyResolverRef.current) {
        const resolveReady = readyResolverRef.current;
        readyResolverRef.current = null;
        resolveReady();
      }

      if (isReady && !notifySubscribedRef.current) {
        try {
          await subscribeFff3IfNeeded();
        } catch (err) {
          console.warn("❌ notify 订阅失败:", err);
        }
      }

      if (isReady && initialInfoLoadedRef.current && !powerDataSubscribedRef.current) {
        try {
          await subscribePowerDataIfNeeded();
        } catch (err) {
          console.warn("❌ 实时数据订阅失败:", err);
        }
      }
    };



    Central.addListener("peripheralConnectionStatus", connectionHandler);
    return () => {
      Central.removeListener("peripheralConnectionStatus", connectionHandler);
      notifySubscribedRef.current = false;
    };
  }, [deviceKey, peripheral]);

  // ========== 首次连接并读取信息 ==========
  useEffect(() => {
    let cancelled = false;

    (async () => {
      setIsLoading(true);
      let shouldShowReadSuccess = false;
      try {
        await Central.connectPeripheral(peripheral);
        await waitForDeviceReady(6000);
        await sleep(150);
        await subscribeFff3IfNeeded();
        await sleep(120);

        const serialValue = await readTextCharacteristic("180a", "2a25");
        const firmwareValue = await readTextCharacteristic("180a", "2a28");
        const hardwareValue = await readTextCharacteristic("180a", "2a27");
        const batteryValue = await readBatteryCharacteristic();

        if (!cancelled && mountedRef.current) {
          setSerial(serialValue);
          setFirmware(firmwareValue);
          setHardware(hardwareValue);
          setBattery(batteryValue);
          initialInfoLoadedRef.current = true;
        }

        await sleep(120);
        await subscribePowerDataIfNeeded();

        shouldShowReadSuccess =
          serialValue !== "未知" ||
          firmwareValue !== "未知" ||
          hardwareValue !== "未知" ||
          batteryValue !== "未知";

        console.log("✅ info 读取完成");

        try {
          await sleep(150);
          await Central.writeCharacteristic(
            peripheral,
            fullUUID(powerServiceUuid),
            fullUUID(powerWriteUuid),
            new Uint8Array([0x04]).buffer,
            { withoutResponse: false }
          );
          console.log("✅ 已发送 0x04，等待 notify 更新功率微调");

          // notify 回调里已经订阅了，所以这里不用再重复订阅
          // 可以稍等 300ms，确保 notify 回来后 UI 会更新
          await sleep(300);
        } catch (err) {
          console.warn("❌ 首次读取功率微调失败", err);
        }
      } catch (e) {
        console.warn("❌ 读取失败", e);
      } finally {
        if (!cancelled && mountedRef.current) {
          setIsLoading(false);
        }

        if (!cancelled && mountedRef.current && shouldShowReadSuccess) {
          setReadSuccessToast(true);
          if (readSuccessTimeoutRef.current) {
            clearTimeout(readSuccessTimeoutRef.current);
          }
          readSuccessTimeoutRef.current = setTimeout(() => {
            if (mountedRef.current) {
              setReadSuccessToast(false);
            }
          }, 2000);
        }
      }
    })();

    return () => {
      cancelled = true;
      initialInfoLoadedRef.current = false;
    };
  }, [peripheral]);




  // ========== 订阅 1818 服务的 2A63 特性 (通知) ==========
  useEffect(() => {
    if (peripheral && deviceReadyRef.current && initialInfoLoadedRef.current) {
      subscribePowerDataIfNeeded().catch((err) => {
        console.warn("❌ 订阅 2A63 特性失败", err);
      });
    }

    return () => {
      if (peripheral && powerDataSubscribedRef.current) {
        powerDataSubscribedRef.current = false;
        Central.unsubscribeCharacteristic(peripheral, fullUUID("1818"), fullUUID("2a63")).catch(() => { });
      }
    };
  }, [peripheral, isDeviceReady]);

  const cadenceStateRef = useRef({
    lastCadenceCount: 0,      // 上一次的踏频翻转次数，用于计算差值
    lastCadenceTimestamp: 0,  // 上一次的踏频时间戳（设备时间），用于计算差值
    lastCadenceChangedTime: 0, // 最后一次踏频变化的时间（本地时间），用于检测超时
  });

  const parseData = (byteArray: Uint8Array) => {
    // 当前时间（用于超时检测）
    const currentTime = Date.now();
    // ========== 1. 解析功率 ==========
    // 字节2-3：功率值（小端序）
    const powerValue = (byteArray[3] << 8) | byteArray[2];
    setPower(powerValue);

    // ========== 3. 解析踏频 ==========
    // 字节5-6：踏频翻转次数（小端序）
    const cadenceCount = (byteArray[6] << 8) | byteArray[5];

    // 字节7-8：踏频时间戳（小端序）
    const timestamp = (byteArray[8] << 8) | byteArray[7];

    // 获取上一次的状态
    const lastState = cadenceStateRef.current;

    // 检测踏频翻转次数是否有变化
    const hasCadenceChanged = cadenceCount !== lastState.lastCadenceCount;

    if (hasCadenceChanged) {
      // 踏频有变化，更新变化时间戳
      cadenceStateRef.current.lastCadenceChangedTime = currentTime;
    }

    // 检查是否超时（3秒无变化）
    if (lastState.lastCadenceChangedTime > 0 &&
      currentTime - lastState.lastCadenceChangedTime > 3000) {
      //setPower("0 W");
      setCadence(0);
      setLeftBalance(0);
      setRightBalance(0);
      cadenceStateRef.current = {
        lastCadenceCount: 0,
        lastCadenceTimestamp: 0,
        lastCadenceChangedTime: 0,
      };
      return; // 超时后直接返回，不再计算踏频
    }

    // 如果是第一次收到踏频数据，只记录不计算
    if (lastState.lastCadenceTimestamp === 0) {
      cadenceStateRef.current = {
        lastCadenceCount: cadenceCount,
        lastCadenceTimestamp: timestamp,
        lastCadenceChangedTime: hasCadenceChanged ? currentTime : 0,
      };
      setCadence(0);
      return;
    }

    // 计算踏频RPM（只在踏频有变化时计算）
    if (hasCadenceChanged) {
      // 计算翻转次数差（处理16位计数器翻转）
      let revDiff = cadenceCount - lastState.lastCadenceCount;
      if (revDiff < 0) {
        revDiff += 65536; // 16位计数器最大值65535
      }

      // 计算时间差（处理16位计数器翻转）
      let timeDiff = timestamp - lastState.lastCadenceTimestamp;
      if (timeDiff < 0) {
        timeDiff += 65536; // 16位计数器最大值65535
      }

      // 计算踏频
      if (timeDiff > 0 && revDiff > 0) {
        // 假设时间单位是1/1024秒（蓝牙设备常用）
        const timeInSeconds = timeDiff / 1024.0;

        // RPM = (圈数 / 时间(秒)) * 60
        const cadenceRPM = (revDiff / timeInSeconds) * 60;

        // 限制合理范围
        if (cadenceRPM > 10 && cadenceRPM < 250) {
          setCadence(Math.round(cadenceRPM));
        } else {
          setCadence(0);
        }
      } else {
        // 如果没有翻转，踏频为0
        setCadence(0);
      }

      // ==========  解析左平衡 ==========
      // 字节4：左平衡值，单位0.5%
      const leftBalanceValue = byteArray[4];
      const leftBalancePercent = Math.round(leftBalanceValue * 0.5 * 10) / 10;
      setLeftBalance(leftBalancePercent);
      // 计算右平衡：100% - 左平衡百分比
      const rightBalancePercent = Math.round((100 - leftBalancePercent) * 10) / 10;
      setRightBalance(rightBalancePercent);

      // 更新踏频计算状态
      cadenceStateRef.current = {
        ...cadenceStateRef.current,
        lastCadenceCount: cadenceCount,
        lastCadenceTimestamp: timestamp,
      };
    }
  };




  // ========== 写入功率微调 ==========
  const updatePowerTrim = async () => {
    const val = Number(inputTrim);
    if (isNaN(val) || val < 50 || val > 200) {
      Alert.alert(t('info.disconnectTitle'), t('info.trimRangeAlert'));
      return;
    }
    if (val === Number(powerTrim)) {
      console.log("⚙️ 相同数值，跳过发送");
      return;
    }
    if (!isConnected) {
      Alert.alert(t('info.disconnectTitle'), t('info.deviceNotConnected'));
      return;
    }

    try {
      setPowerTrimLoading(true);
      const scaledVal = Math.round(val * 100);
      const low = scaledVal & 0xff;
      const high = (scaledVal >> 8) & 0xff;

      console.log("🚀 写入功率微调", val, "=>", scaledVal);
      await Central.writeCharacteristic(
        peripheral,
        fullUUID(powerServiceUuid),
        fullUUID(powerWriteUuid),
        new Uint8Array([0x02, low, high]).buffer,
        { withoutResponse: false }
      );
      await new Promise<void>((resolve) => setTimeout(() => resolve(), 150));
      await Central.writeCharacteristic(
        peripheral,
        fullUUID(powerServiceUuid),
        fullUUID(powerWriteUuid),
        new Uint8Array([0x04]).buffer,
        { withoutResponse: false }
      );

      setPowerTrimLoading(false);
      setPowerTrimSuccessToast(true);
      setTimeout(() => setPowerTrimSuccessToast(false), 2000);

    } catch (err) {
      console.warn("❌ 写入失败", err);
      Alert.alert(t('info.writeFailed'));
    } finally {
      setPowerTrimLoading(false);
    }
  };

  // ========== 校准按钮逻辑 ==========
  const handleCalibration = async () => {
    if (!isConnected) {
      Alert.alert(t('info.disconnectTitle'), t('info.deviceNotConnected'));
      return;
    }

    if (calibrating) {
      return; // 正在校准中，不重复点击
    }

    try {
      setCalibrating(true);
      isCalibratingRef.current = true;
      setCalibrationSuccess(false);
      setCalibrationValue("");

      console.log("🔧 开始校准，向FFF2写入05");

      // 向FFF2写入05
      await Central.writeCharacteristic(
        peripheral,
        fullUUID("FFF1"), // 服务UUID
        fullUUID("FFF2"), // 写入特征UUID
        new Uint8Array([0x05]).buffer,
        { withoutResponse: false }
      );

      console.log("✅ 已发送校准命令，等待响应...");

      // 设置5秒超时
      calibrationTimeoutRef.current = setTimeout(() => {
        if (isCalibratingRef.current) {
          console.log("❌ 校准超时，未收到响应");
          Alert.alert(t('info.calibrationError'), t('info.calibrationTimeout'));
          setCalibrating(false);
          isCalibratingRef.current = false;
        }
      }, 5000);

    } catch (err) {
      console.warn("❌ 发送校准命令失败", err);
      Alert.alert(t('info.error'), t('info.calibrationSendError'));
      setCalibrating(false);
      isCalibratingRef.current = false;

      if (calibrationTimeoutRef.current) {
        clearTimeout(calibrationTimeoutRef.current);
      }
    }
  };

  const handleFFF3Response = (byteArray: Uint8Array) => {
    // 如果不是正在校准中，不处理
    if (!isCalibratingRef.current) return;

    // 清除超时定时器
    if (calibrationTimeoutRef.current) {
      clearTimeout(calibrationTimeoutRef.current);
      calibrationTimeoutRef.current = null;
    }

    // 检查响应数据格式：05XXXX (05开头，后面至少2个字节)
    // 假设响应是05 + 2字节的小端序数值
    if (byteArray[0] === 0x05 && byteArray.length >= 3) {
      // 解析XXXX（小端序）：低位在前，高位在后
      // byteArray[1] 是低位字节，byteArray[2] 是高位字节
      const value = Math.round(((byteArray[2] << 8) | byteArray[1]) / 10);   //除以10发送出来 不然数据容易乱跳 和码表端处理保持一致
      console.log(`✅ 收到校准响应，值: ${value}`);

      // 更新状态
      setCalibrationValue(value.toString());
      setCalibrationSuccess(true);

      // 显示成功弹框
      Alert.alert(
        t('info.calibrationSuccess'),
        `${t('info.calibrationValue') + ": "} ${value}`,
        [
          {
            text: t('info.confirm'),
            onPress: () => {
              setCalibrating(false);
              isCalibratingRef.current = false;
              setCalibrationSuccess(false);
            }
          }
        ]
      );
    } else {
      console.warn("❌ 校准响应格式错误", byteArray);
      Alert.alert(t('info.calibrationError'), t('info.calibrationFormatError'));
      setCalibrating(false);
      isCalibratingRef.current = false;
    }
  };

  useEffect(() => {
    mountedRef.current = true;
    return () => {
      mountedRef.current = false;
      deviceReadyRef.current = false;
      initialInfoLoadedRef.current = false;
      powerDataSubscribedRef.current = false;
      readyResolverRef.current = null;
      // 清理校准超时定时器
      if (calibrationTimeoutRef.current) {
        clearTimeout(calibrationTimeoutRef.current);
        calibrationTimeoutRef.current = null;
      }
      if (readSuccessTimeoutRef.current) {
        clearTimeout(readSuccessTimeoutRef.current);
        readSuccessTimeoutRef.current = null;
      }
    };
  }, []);


  // ========== UI ==========
  return (
    <View style={{flex:1, backgroundColor: '#FFFFFF'}}>
      <MyStatusbar backgroundColor={'#FFFFFF'} dark={true}></MyStatusbar>
      <MyHeader title={t("info.title")} textColor={'#000000'} backgroundColor={'#FFFFFF'} navigation={navigation}></MyHeader>
      <ScrollView contentContainerStyle={{ padding: 20, gap: 8 }}>

        <View style={styles.row}>
          <Text>{t('info.bluetoothName') + ": "} {peripheral.name}</Text>
        </View>

        <View style={styles.row}>
          <Text>{t('info.idNumber') + ": "} {serial}</Text>
        </View>

        <View style={styles.row}>
          <Text>{t('info.firmwareVersion') + ": "} {firmware}</Text>
        </View>

        <View style={styles.row}>
          <Text>{t('info.battery') + ": "} {battery}</Text>
        </View>

        <View style={styles.row}>
          <Text>{t('info.connectionStatus') + ": "} {isConnected ? t('info.connected') : t('info.disconnected')}</Text>
        </View>

        {/* ====== 实时数据三卡片 ====== */}
        <View style={styles.realtimeContainer}>
          {/* 功率 */}
          <View style={styles.realtimeCard}>
            <Icon name="flash" size={22} color={'#000000'} />
            <Text style={styles.realtimeLabel}>{t('info.power')}</Text>
            <Text style={styles.realtimeValue}>{power}</Text>
          </View>

          {/* 踏频 */}
          <View style={styles.realtimeCard}>
            <Icon name="sync" size={22} color={'#000000'} />
            <Text style={styles.realtimeLabel}>{t('info.cadence')}</Text>
            <Text style={styles.realtimeValue}>{cadence}</Text>
          </View>

          {/* 左右平衡 */}
          <View style={styles.realtimeCard}>
            <Text style={styles.balanceHeader}>L / R</Text>
            <Text style={styles.realtimeLabel}>{t('info.balance')}</Text>
            <Text style={styles.realtimeValue}>
              {leftbalance}/{rightbalance}
            </Text>
          </View>
        </View>



        {/* ========== 功率微调卡片部分 ========== */}
        <View style={styles.cardContainer}>
          <View style={styles.cardTitle}>
            <Text style={[styles.cardTitleText, { textAlign: 'center' }]}>{t('info.powerTrimTitle')}</Text>
          </View>

          <View style={{
            flexDirection: 'row',
            alignItems: 'center',
            justifyContent: 'space-between',
            marginBottom: 0,
            paddingHorizontal: 10
          }}>
            <Text style={{ marginTop: 10, flex: 1, marginRight: 10 }}>{t('info.currentTrim') + ": "} {powerTrim}%</Text>
            <TextInput
              style={[styles.input, { flex: 1, marginTop: 10 }]}
              value={inputTrim}
              onChangeText={setInputTrim}
              keyboardType="numeric"
              onEndEditing={updatePowerTrim}
              placeholder={t('info.trimPlaceholder')}
              placeholderTextColor={THEME.textMuted}
            />
          </View>

          <Pressable
            onPress={updatePowerTrim}
            style={styles.pressable}
            disabled={isLoading || powerTrimLoading}
          >
            <Text style={{ color: '#FFFFFF' }}>{t('info.updateValue')}
           </Text>
          </Pressable>
        </View>

        {/* ========== 新增校准按钮 ========== */}
        <View style={{ marginTop: 0 }}>
          <Pressable
            onPress={handleCalibration}
            style={[styles.pressable, calibrating && styles.disabledButton]}
            disabled={calibrating || !isConnected}
          >
            <Text style={{ color: '#FFFFFF' }}>
              {calibrating ? t('info.calibrating') : t('info.calibrateButton')}
            </Text>
          </Pressable>
        </View>



        <View style={{ marginTop: 0 }}>
          <Pressable
            onPress={() => {
              if (!isConnected) {
                Alert.alert(t('info.disconnectTitle'), t('info.reconnectMessage'), [
                  {
                    text: t('info.confirm'),
                    onPress: () => {
                      // 返回 ScanScreen
                      navigation.goBack();
                    },
                  },
                ]);
                return;
              }

              const dfuRouteParams = {
                deviceId: deviceKey,
                systemId: peripheral.systemId,
                address: peripheral.address,
                name: peripheral.name ?? "",
                firmware: firmware ?? "",
              };

              console.log("[DFU-TRACE] navigate to Dfu", {
                ...dfuRouteParams,
                isConnected,
                isDeviceReady,
              });

              skipDisconnectOnLeaveRef.current = true;
              navigation.navigate("Dfu", dfuRouteParams);
            }}
            style={styles.pressable}
            disabled={isLoading || powerTrimLoading} // ❌ 禁用点击
          >
            <Text style={{ color: '#FFFFFF' }}>{t('info.firmwareUpgrade')}</Text>
          </Pressable>
        </View>



        {isLoading && (
          <View style={{ marginVertical: 60, alignItems: "center" }}>
            <ActivityIndicator size={30} color={'#000000'} />
            <Text style={{ marginTop: 10, fontSize: 16 }}>{t('info.readingInfo')}</Text>
          </View>
        )}

        {/* ✅ 读取成功提示，固定在页面底部 */}
        {readSuccessToast && (
          <View style={{ marginVertical: 60, alignItems: "center" }}>
            <Icon name="check-circle" size={30} color={'#000000'} />
            <Text style={{ marginTop: 10, fontSize: 16 }}>{t('info.readSuccess')}</Text>
          </View>
        )}

        {/* 正在写入功率微调 */}
        {powerTrimLoading && (
          <View style={{ marginVertical: 60, alignItems: "center" }}>
            <ActivityIndicator size={30} color={'#000000'} />
            <Text style={{ marginTop: 10, fontSize: 16 }}>{t('info.writingTrim')}</Text>
          </View>
        )}

        {/* 功率微调写入成功 */}
        {powerTrimSuccessToast && (
          <View style={{ marginVertical: 60, alignItems: "center" }}>
            <Icon name="check-circle" size={30} color={'#000000'} />
            <Text style={{ marginTop: 10, fontSize: 16 }}>{t('info.trimUpdateSuccess')}</Text>
          </View>
        )}

      </ScrollView>
    </View>
  );
}

const styles = StyleSheet.create({
  row: {
    borderBottomWidth: 1,
    borderBottomColor: '#E0E0E0',
    paddingBottom: 3, // 横线和文字保持一定间距
    marginBottom: 8,  // 行间距
  },
  input: {
    borderWidth: 1,
    borderColor: '#E0E0E0',
    padding: 6,
    marginTop: 5,
    borderRadius: 4,
    color: '#000000',
    backgroundColor: '#F5F5F5',
  },
  pressable: {
    padding: 10,
    backgroundColor: '#000000',
    marginTop: 10,
    borderRadius: 6,
    alignItems: "center",
  },
  disabledButton: {
    backgroundColor: '#888888',
    opacity: 0.6,
  },

  cardContainer: {
    borderWidth: 1,
    borderColor: '#E0E0E0',
    borderRadius: 10,
    marginTop: 10,
    backgroundColor: '#FFFFFF',
    overflow: 'hidden', // 确保圆角效果完整
    shadowColor: "#000",
    shadowOffset: { width: 0, height: 1 },
    shadowOpacity: 0.1,
    shadowRadius: 2,
    elevation: 2, // Android阴影
  },
  cardTitle: {
    backgroundColor: '#F5F5F5',
    paddingVertical: 8,
    paddingHorizontal: 15,
    borderBottomWidth: 1,
    borderBottomColor: '#E0E0E0',
  },
  cardTitleText: {
    fontWeight: 'bold',
    color: '#000000',
  },

  realtimeContainer: {
    flexDirection: "row",
    justifyContent: "space-between",
    marginVertical: 10,
  },

  realtimeCard: {
    flex: 1,
    marginHorizontal: 4,
    paddingVertical: 12,
    borderRadius: 10,
    backgroundColor: '#FFFFFF',
    alignItems: "center",

    borderWidth: 1,
    borderColor: '#E0E0E0',

    shadowColor: "#000",
    shadowOffset: { width: 0, height: 1 },
    shadowOpacity: 0.1,
    shadowRadius: 2,
    elevation: 2, // Android阴影
  },

  realtimeLabel: {
    marginTop: 6,
    fontSize: 14,
    color: '#666666',
  },

  realtimeValue: {
    marginTop: 4,
    fontSize: 20,
    fontWeight: "bold",
    color: '#000000',
  },

  balanceHeader: {
    fontSize: 16,
    fontWeight: "bold",
    color: '#000000',
  },



});
