import { useCallback, useEffect, useRef, useState } from 'react';
import type { ComponentType } from 'react';
import { Card, Col, Row, Tag, Button, Space, message, Spin, Empty, InputNumber, Modal, Alert, Result, Popconfirm } from 'antd';
import {
  ApiOutlined,
  BulbOutlined,
  SendOutlined,
  StopOutlined,
  DeleteOutlined,
  InfoCircleOutlined,
  PoweroffOutlined,
  ThunderboltOutlined,
  CloudOutlined,
  FireOutlined,
} from '@ant-design/icons';
import { get, post } from '../api/http';

interface Device {
  id: string;
  deviceKey?: string;
  name: string;
  onlineStatus?: string;
}

interface IRResult {
  hasResult: boolean;
  result?: {
    action: string;
    success: boolean;
    no: number;
    timestamp: string;
  };
  learnedCodes?: number[];
}

// 空调遥控按钮配置（顺序学习）
const AIRCON_BUTTONS = [
  { key: 'power-off', label: '关机', no: 1, icon: 'PoweroffOutlined' },
  { key: 'power-on', label: '开机', no: 2, icon: 'PoweroffOutlined' },
  { key: 'cooling', label: '制冷', no: 6, icon: 'CloudOutlined' },
  { key: 'heating', label: '制热', no: 7, icon: 'FireOutlined' },
  { key: 'dehumid', label: '除湿', no: 5, icon: 'ThunderboltOutlined' },
];

// 温度按钮配置（单独学习）
const TEMP_BUTTONS = [
  { key: 'temp-23', label: '23度', no: 3 },
  { key: 'temp-25', label: '25度', no: 4 },
  { key: 'temp-27', label: '27度', no: 8 },
  { key: 'temp-29', label: '29度', no: 9 },
];

// 图标名 -> 图标组件映射
const ICON_MAP: Record<string, ComponentType> = {
  PoweroffOutlined,
  ThunderboltOutlined,
  CloudOutlined,
  FireOutlined,
};

// 顺序学习的编号顺序（与 AIRCON_BUTTONS 的 no 字段一致）
const LEARN_SEQUENCE = [1, 2, 6, 7, 5];

// 所有可学习的按钮（用于查找按钮标签）
const ALL_BUTTONS = [...AIRCON_BUTTONS, ...TEMP_BUTTONS];

// 闪烁动画样式（正在学习的按钮高亮闪烁）
const blinkStyle = `
@keyframes ir-blink {
  0%, 100% { background-color: #faad14; }
  50% { background-color: #fffbe6; }
}
.ir-blinking {
  animation: ir-blink 0.8s infinite;
}
`;

const IRControl = () => {
  const [devices, setDevices] = useState<Device[]>([]);
  const [loading, setLoading] = useState(false);
  const [sending, setSending] = useState('');
  const [learnModal, setLearnModal] = useState<{ open: boolean; deviceId: string; no: number }>({ open: false, deviceId: '', no: 100 });
  const [emitNo, setEmitNo] = useState<Record<string, number>>({});
  const [irResults, setIrResults] = useState<Record<string, { action: string; success: boolean; no: number } | undefined>>({});
  const [deviceInfo, setDeviceInfo] = useState<Record<string, { signal?: number; lastSeen?: string; learnedCodes?: number[] } | undefined>>({});
  // 空调顺序学习状态：记录当前正在学习的设备与编号
  const [learningDevice, setLearningDevice] = useState<{ deviceId: string; currentNo: number } | null>(null);
  // 使用 ref 跟踪 learningDevice，避免轮询中的闭包陷阱
  const learningDeviceRef = useRef<{ deviceId: string; currentNo: number } | null>(null);
  // 空调按钮发射 loading（key = deviceId + button.key）
  const [airconSending, setAirconSending] = useState<string>('');

  // 同步更新 state 与 ref
  const updateLearningDevice = (val: { deviceId: string; currentNo: number } | null) => {
    learningDeviceRef.current = val;
    setLearningDevice(val);
  };

  const fetchDevices = useCallback(async () => {
    setLoading(true);
    try {
      const data = await get<Device[] | { items: Device[] }>('/devices');
      const all = Array.isArray(data) ? data : data.items ?? [];
      // 只显示红外控制器（名称包含"红外"）
      const items = all.filter((d) => d.name.includes('红外'));
      setDevices(items);
    } catch {
      message.error('加载设备列表失败');
    }
    setLoading(false);
  }, []);

  useEffect(() => {
    fetchDevices();
  }, [fetchDevices]);

  const actionLabel = (action: string) => {
    const labels: Record<string, string> = { learn: '学习', emit: '发射', learnCancel: '取消学习', erase: '擦除' };
    return labels[action] || action;
  };

  // 擦除结果轮询：erase 命令可能不返回响应，短时间轮询确认
  const pollEraseResult = async (deviceId: string) => {
    const startTime = Date.now();
    for (let i = 0; i < 5; i++) {
      await new Promise((r) => setTimeout(r, 2000));
      try {
        const data = await get<IRResult>(`/devices/${deviceId}/ir/status`, { silent: true });
        if (data.hasResult && data.result) {
          const resultTime = new Date(data.result.timestamp).getTime();
          if (resultTime >= startTime && data.result.action === 'erase') {
            if (data.result.success) {
              message.success('擦除成功');
            } else {
              message.warning('设备已进入擦除模式，本地列表已清空');
            }
            return;
          }
        }
      } catch {}
    }
    // 超时：设备可能不返回 erase 响应，本地列表已清空
    message.info('设备未响应擦除结果，本地红外码列表已清空');
  };

  // 轮询红外操作结果（原有功能：用于手动学习/发射/擦除）
  const pollIRResult = async (deviceId: string, action: string, no?: number) => {
    for (let i = 0; i < 15; i++) {
      await new Promise((r) => setTimeout(r, 2000));
      try {
        const data = await get<IRResult>(`/devices/${deviceId}/ir/status`, { silent: true });
        if (data.hasResult && data.result) {
          // 检查是否是本次操作的结果（action 匹配，且时间戳在最近 30 秒内）
          const resultTime = new Date(data.result.timestamp).getTime();
          if (Date.now() - resultTime < 30000) {
            if (data.result.action === action && (no === undefined || data.result.no === no || data.result.no === 0)) {
              // success=false 表示设备已进入操作模式（如进入学习/擦除模式），不是真正失败，继续轮询
              if (!data.result.success) {
                continue;
              }
              setIrResults((prev) => ({ ...prev, [deviceId]: data.result }));
              // 擦除成功后清空本地已学习红外码列表
              if (action === 'erase') {
                setDeviceInfo((prev) => {
                  const curInfo = prev?.[deviceId];
                  return { ...prev, [deviceId]: { ...curInfo, learnedCodes: [] } };
                });
              }
              message.success(`${actionLabel(data.result.action)}成功${data.result.no ? `（编号 ${data.result.no}）` : ''}`);
              return;
            }
          }
        }
      } catch {}
    }
    message.warning(`${actionLabel(action)}等待结果超时，请重试`);
  };

  // 轮询设备信息（info 响应后 signal 会被入库）
  const pollDeviceInfo = async (device: Device) => {
    const key = device.deviceKey || device.id;
    for (let i = 0; i < 10; i++) {
      await new Promise((r) => setTimeout(r, 2000));
      try {
        // 查询遥测数据（signal）
        const telemetry = await get<{ metric: string; value: number; timestamp: string }[]>(
          `/telemetry/${key}/latest`, { silent: true }
        );
        // 查询已学习的红外码
        const irStatus = await get<{ hasResult: boolean; learnedCodes?: number[] }>(
          `/devices/${device.id}/ir/status`, { silent: true }
        );
        const signalRec = Array.isArray(telemetry) ? telemetry.find((r) => r.metric === 'signal') : undefined;
        if (signalRec || irStatus.learnedCodes) {
          setDeviceInfo((prev) => ({
            ...prev,
            [device.id]: {
              signal: signalRec?.value,
              lastSeen: signalRec?.timestamp,
              learnedCodes: irStatus.learnedCodes || [],
            },
          }));
          if (signalRec) {
            const codes = irStatus.learnedCodes || [];
            message.success(`设备信息已更新：信号 ${signalRec.value}，已学习红外码 ${codes.length} 个`);
          }
          return;
        }
      } catch {}
    }
    message.warning('设备未响应，可能已离线');
  };

  // 原有通用指令发送（左侧按钮使用）
  const sendIR = async (device: Device, action: 'learn' | 'emit' | 'cancel' | 'erase' | 'info', no?: number) => {
    const key = device.id + action + (no ?? '');
    setSending(key);
    // 清除之前的结果
    setIrResults((prev) => ({ ...prev, [device.id]: undefined }));
    try {
      if (action === 'learn' && no !== undefined) {
        await post(`/devices/${device.id}/ir/learn`, { no });
        message.success(`学习指令已发送（编号 ${no}），请将遥控器对准设备按键`);
        setLearnModal({ open: true, deviceId: device.id, no });
        pollIRResult(device.id, 'learn', no);
      } else if (action === 'emit' && no !== undefined) {
        await post(`/devices/${device.id}/ir/emit`, { no });
        message.success(`发射指令已发送（编号 ${no}）`);
        pollIRResult(device.id, 'emit', no);
      } else if (action === 'cancel') {
        await post(`/devices/${device.id}/ir/cancel`);
        message.success('取消学习指令已发送');
        setLearnModal({ ...learnModal, open: false });
        // learnCancel 仅在学习模式下有响应，不轮询结果
      } else if (action === 'erase') {
        await post(`/devices/${device.id}/ir/erase`);
        // 立即清空本地已学习红外码列表
        setDeviceInfo((prev) => {
          const curInfo = prev?.[device.id];
          return { ...prev, [device.id]: { ...curInfo, learnedCodes: [] } };
        });
        message.success('擦除指令已发送，已清空本地红外码列表');
        // erase 可能像 learnCancel 一样不返回响应，短时间轮询确认
        pollEraseResult(device.id);
      } else if (action === 'info') {
        await post(`/devices/${device.id}/plug/info`);
        message.success('查询信息指令已发送，等待设备响应...');
        // 轮询遥测数据（info 响应中的 signal 会被入库）
        pollDeviceInfo(device);
      }
    } catch (err: any) {
      const errMsg = err?.response?.data?.error || '指令发送失败';
      message.error(errMsg);
    }
    setSending('');
  };

  // 空调按钮发射（右侧空调面板使用）
  const emitAircon = async (deviceId: string, button: typeof AIRCON_BUTTONS[number]) => {
    // 正在顺序学习中，不触发发射
    if (learningDeviceRef.current && learningDeviceRef.current.deviceId === deviceId) {
      return;
    }
    const key = deviceId + button.key;
    setAirconSending(key);
    try {
      await post(`/devices/${deviceId}/ir/emit`, { no: button.no });
      message.success(`【${button.label}】指令已发送`);
    } catch (err: any) {
      const errMsg = err?.response?.data?.error || `${button.label}指令发送失败`;
      message.error(errMsg);
    }
    setAirconSending('');
  };

  // 顺序学习轮询：循环查询学习结果，成功后自动进入下一个编号
  // startTime 用于过滤旧结果，只接受该时间之后产生的学习结果
  const pollSequentialLearn = async (deviceId: string, no: number, startTime: number) => {
    for (let i = 0; i < 15; i++) {
      await new Promise((r) => setTimeout(r, 2000));
      // 通过 ref 检查是否已被取消或已切换到下一个编号
      const cur = learningDeviceRef.current;
      if (!cur || cur.deviceId !== deviceId || cur.currentNo !== no) {
        return; // 已被取消或已切换
      }
      try {
        const data = await get<IRResult>(`/devices/${deviceId}/ir/status`, { silent: true });
        if (data.hasResult && data.result) {
          const resultTime = new Date(data.result.timestamp).getTime();
          // 只接受 startTime 之后的结果，避免读到上一个编号的旧结果
          // 设备学习成功时返回 no=0，失败时返回发送的编号，因此匹配条件需兼容 no=0
          if (resultTime >= startTime && data.result.action === 'learn' && (data.result.no === no || data.result.no === 0)) {
            const curButton = ALL_BUTTONS.find((b) => b.no === no);
            if (data.result.success) {
              // 学习成功，更新本地 learnedCodes
              setDeviceInfo((prev) => {
                const curInfo = prev?.[deviceId];
                const codes = curInfo?.learnedCodes ?? [];
                if (!codes.includes(no)) codes.push(no);
                return { ...prev, [deviceId]: { ...curInfo, learnedCodes: [...codes] } };
              });
              // 查找当前编号在学习序列中的位置，决定下一个学习的编号
              const seqIndex = LEARN_SEQUENCE.indexOf(no);
              const nextNo = seqIndex >= 0 && seqIndex + 1 < LEARN_SEQUENCE.length ? LEARN_SEQUENCE[seqIndex + 1] : null;
              if (nextNo !== null) {
                const nextStartTime = Date.now();
                await post(`/devices/${deviceId}/ir/learn`, { no: nextNo });
                updateLearningDevice({ deviceId, currentNo: nextNo });
                const nextLabel = ALL_BUTTONS.find((b) => b.no === nextNo)?.label;
                message.success(`【${curButton?.label}】学习成功，请按下遥控器的【${nextLabel}】键`);
                pollSequentialLearn(deviceId, nextNo, nextStartTime);
              } else {
                // 全部完成
                updateLearningDevice(null);
                message.success('全部学习完成');
              }
              return;
            }
            // success=false 表示设备已进入学习模式，等待用户按遥控器，继续轮询
          }
        }
      } catch {}
    }
    // 超时：仅当仍处于当前学习状态时才提示
    const cur = learningDeviceRef.current;
    if (cur && cur.deviceId === deviceId && cur.currentNo === no) {
      updateLearningDevice(null);
      message.warning('学习超时，请重试');
    }
  };

  // 开始顺序学习：从学习序列的第一个编号开始
  const startSequentialLearn = async (deviceId: string) => {
    try {
      const firstNo = LEARN_SEQUENCE[0];
      const startTime = Date.now();
      await post(`/devices/${deviceId}/ir/learn`, { no: firstNo });
      updateLearningDevice({ deviceId, currentNo: firstNo });
      const firstLabel = ALL_BUTTONS.find((b) => b.no === firstNo)?.label;
      message.success(`开始学习：请按下遥控器的【${firstLabel}】键`);
      pollSequentialLearn(deviceId, firstNo, startTime);
    } catch (err: any) {
      const errMsg = err?.response?.data?.error || '学习指令发送失败';
      message.error(errMsg);
    }
  };

  // 取消顺序学习
  const cancelSequentialLearn = async (deviceId: string) => {
    try {
      await post(`/devices/${deviceId}/ir/cancel`, {});
    } catch {}
    updateLearningDevice(null);
    message.success('已取消学习');
  };

  // 温度按钮单独学习
  const learnSingleTemp = async (deviceId: string, no: number, label: string) => {
    // 如果正在顺序学习，不允许单独学习
    if (learningDeviceRef.current !== null) {
      message.warning('正在顺序学习中，请先取消');
      return;
    }
    try {
      const startTime = Date.now();
      updateLearningDevice({ deviceId, currentNo: no });
      await post(`/devices/${deviceId}/ir/learn`, { no });
      message.success(`请按下遥控器的【${label}】键`);
      // 轮询单次学习结果
      for (let i = 0; i < 15; i++) {
        await new Promise((r) => setTimeout(r, 2000));
        const cur = learningDeviceRef.current as { deviceId: string; currentNo: number } | null;
        if (!cur || cur.deviceId !== deviceId || cur.currentNo !== no) {
          return; // 已被取消
        }
        try {
          const data = await get<IRResult>(`/devices/${deviceId}/ir/status`, { silent: true });
          if (data.hasResult && data.result) {
            const resultTime = new Date(data.result.timestamp).getTime();
            if (resultTime >= startTime && data.result.action === 'learn' && (data.result.no === no || data.result.no === 0)) {
              if (!data.result.success) {
                continue; // 进入学习模式，继续等
              }
              // 学习成功
              setDeviceInfo((prev) => {
                const curInfo = prev?.[deviceId];
                const codes = curInfo?.learnedCodes ?? [];
                if (!codes.includes(no)) codes.push(no);
                return { ...prev, [deviceId]: { ...curInfo, learnedCodes: [...codes] } };
              });
              updateLearningDevice(null);
              message.success(`【${label}】学习成功`);
              return;
            }
          }
        } catch {}
      }
      // 超时
      const cur = learningDeviceRef.current as { deviceId: string; currentNo: number } | null;
      if (cur && cur.deviceId === deviceId && cur.currentNo === no) {
        updateLearningDevice(null);
        message.warning(`【${label}】学习超时，请重试`);
      }
    } catch (err: any) {
      updateLearningDevice(null);
      const errMsg = err?.response?.data?.error || '学习指令发送失败';
      message.error(errMsg);
    }
  };

  const isOnline = (d: Device) => d.onlineStatus === 'online';

  if (!loading && devices.length === 0) {
    return <Empty description="暂无设备" />;
  }

  return (
    <Spin spinning={loading}>
      <style>{blinkStyle}</style>
      <Row gutter={[16, 16]}>
        {devices.map((d) => {
          const online = isOnline(d);
          const currentNo = emitNo[d.id] ?? 100;
          const irResult = irResults[d.id];
          const info = deviceInfo[d.id];
          const learnedCodes = info?.learnedCodes ?? [];
          // 当前设备是否处于顺序学习
          const isLearning = learningDevice?.deviceId === d.id;
          const learningNo = isLearning ? learningDevice!.currentNo : null;

          return (
            <Col key={d.id} span={24}>
              <Card
                title={<Space><ApiOutlined />{d.name}</Space>}
                extra={<Tag color={online ? 'green' : 'default'}>{online ? '在线' : '离线'}</Tag>}
              >
                <Row gutter={[24, 0]}>
                  {/* 左侧：原有通用功能 */}
                  <Col span={12}>
                    {/* 操作结果反馈 */}
                    {irResult && (
                      <div style={{ marginBottom: 16 }}>
                        <Result
                          status={irResult.success ? 'success' : 'error'}
                          title={`${actionLabel(irResult.action)}${irResult.success ? '成功' : '失败'}`}
                          subTitle={irResult.no ? `红外码编号: ${irResult.no}` : undefined}
                          style={{ padding: '12px 0' }}
                        />
                      </div>
                    )}

                    {/* 设备信息 */}
                    {info && (
                      <div style={{ marginBottom: 16, padding: 12, background: '#f5f5f5', borderRadius: 8 }}>
                        <div style={{ fontSize: 13, color: '#666' }}>设备信息</div>
                        <div style={{ marginTop: 4 }}>
                          4G 信号：<Tag color={(info.signal ?? 0) >= 20 ? 'green' : (info.signal ?? 0) >= 10 ? 'orange' : 'red'}>{info.signal ?? '--'}/31</Tag>
                        </div>
                        <div style={{ fontSize: 12, color: '#999', marginTop: 4 }}>
                          最后上报：{info.lastSeen ? new Date(info.lastSeen).toLocaleTimeString() : '--'}
                        </div>
                        <div style={{ marginTop: 8, fontSize: 13, color: '#666' }}>
                          已学习红外码：
                          {info.learnedCodes && info.learnedCodes.length > 0 ? (
                            <Space size={4} wrap style={{ marginTop: 4 }}>
                              {info.learnedCodes.slice().sort((a, b) => a - b).map((no) => (
                                <Tag key={no} color="blue" style={{ cursor: 'pointer' }} onClick={() => setEmitNo({ ...emitNo, [d.id]: no })}>
                                  {no}
                                </Tag>
                              ))}
                            </Space>
                          ) : (
                            <span style={{ color: '#999' }}>暂无</span>
                          )}
                        </div>
                      </div>
                    )}

                    {/* 发射红外码 */}
                    <div style={{ marginBottom: 16 }}>
                      <div style={{ marginBottom: 8, fontWeight: 500 }}>发射红外码</div>
                      <Space>
                        <InputNumber
                          min={1}
                          max={248}
                          value={currentNo}
                          onChange={(v) => setEmitNo({ ...emitNo, [d.id]: v ?? 100 })}
                          style={{ width: 80 }}
                          disabled={isLearning}
                        />
                        <Button
                          type="primary"
                          icon={<SendOutlined />}
                          loading={sending === d.id + 'emit' + currentNo}
                          onClick={() => sendIR(d, 'emit', currentNo)}
                          disabled={isLearning}
                        >
                          发射
                        </Button>
                      </Space>
                    </div>

                    {/* 学习红外码 */}
                    <div style={{ marginBottom: 16 }}>
                      <div style={{ marginBottom: 8, fontWeight: 500 }}>学习红外码</div>
                      <Space>
                        <InputNumber
                          min={1}
                          max={248}
                          value={learnModal.no}
                          onChange={(v) => setLearnModal({ ...learnModal, no: v ?? 100 })}
                          style={{ width: 80 }}
                          disabled={isLearning}
                        />
                        <Button
                          icon={<BulbOutlined />}
                          loading={sending === d.id + 'learn' + learnModal.no}
                          onClick={() => sendIR(d, 'learn', learnModal.no)}
                          disabled={isLearning}
                        >
                          开始学习
                        </Button>
                      </Space>
                    </div>

                    {/* 其他操作 */}
                    <Space style={{ width: '100%', justifyContent: 'center' }}>
                      <Button
                        size="small"
                        icon={<StopOutlined />}
                        loading={sending === d.id + 'cancel'}
                        onClick={() => sendIR(d, 'cancel')}
                      >
                        取消学习
                      </Button>
                      <Button
                        size="small"
                        icon={<InfoCircleOutlined />}
                        loading={sending === d.id + 'info'}
                        onClick={() => sendIR(d, 'info')}
                      >
                        查询信息
                      </Button>
                      <Popconfirm
                        title="确认擦除全部红外码？"
                        okText="确认"
                        cancelText="取消"
                        okButtonProps={{ danger: true }}
                        onConfirm={() => sendIR(d, 'erase')}
                      >
                        <Button
                          size="small"
                          danger
                          icon={<DeleteOutlined />}
                          loading={sending === d.id + 'erase'}
                        >
                          擦除全部
                        </Button>
                      </Popconfirm>
                    </Space>
                  </Col>

                  {/* 右侧：空调遥控面板 */}
                  <Col span={12}>
                    <div style={{ marginBottom: 12, fontWeight: 600, fontSize: 15 }}>
                      空调遥控面板
                      {isLearning && (
                        <Tag color="processing" style={{ marginLeft: 8 }}>学习中...</Tag>
                      )}
                    </div>

                    {/* 开始学习 / 取消学习 按钮 */}
                    <div style={{ marginBottom: 12 }}>
                      {isLearning ? (
                        <Button
                          block
                          size="large"
                          danger
                          icon={<StopOutlined />}
                          style={{ height: 60, fontSize: 16, fontWeight: 500 }}
                          onClick={() => cancelSequentialLearn(d.id)}
                        >
                          取消学习
                        </Button>
                      ) : (
                        <Button
                          block
                          size="large"
                          type="primary"
                          icon={<BulbOutlined />}
                          style={{ height: 60, fontSize: 16, fontWeight: 500 }}
                          onClick={() => startSequentialLearn(d.id)}
                        >
                          开始学习
                        </Button>
                      )}
                    </div>

                    {/* 空调控制按钮（顺序学习） */}
                    <Row gutter={[12, 12]}>
                      {AIRCON_BUTTONS.map((btn) => {
                        const Icon = ICON_MAP[btn.icon];
                        const learned = learnedCodes.includes(btn.no);
                        const isBlinking = isLearning && learningNo === btn.no;
                        const isLoading = airconSending === d.id + btn.key;
                        return (
                          <Col key={btn.key} span={12}>
                            <Button
                              block
                              size="large"
                              icon={Icon ? <Icon /> : undefined}
                              loading={isLoading}
                              className={isBlinking ? 'ir-blinking' : undefined}
                              style={{
                                height: 80,
                                fontSize: 16,
                                fontWeight: 500,
                                ...(learned && !isBlinking
                                  ? { borderColor: '#52c41a', color: '#52c41a' }
                                  : {}),
                              }}
                              onClick={() => emitAircon(d.id, btn)}
                            >
                              {btn.label}
                            </Button>
                          </Col>
                        );
                      })}
                    </Row>

                    {/* 温度按钮（单独学习） */}
                    <div style={{ marginTop: 16, marginBottom: 8, fontSize: 13, color: '#999' }}>
                      温度按钮（点击未学习的按钮开始单独学习）
                    </div>
                    <Row gutter={[12, 12]}>
                      {TEMP_BUTTONS.map((btn) => {
                        const learned = learnedCodes.includes(btn.no);
                        const isBlinking = isLearning && learningNo === btn.no;
                        return (
                          <Col key={btn.key} span={6}>
                            <Button
                              block
                              size="large"
                              className={isBlinking ? 'ir-blinking' : undefined}
                              style={{
                                height: 60,
                                fontSize: 15,
                                fontWeight: 500,
                                ...(learned && !isBlinking
                                  ? { borderColor: '#52c41a', color: '#52c41a' }
                                  : {}),
                              }}
                              onClick={() => {
                                if (isBlinking) {
                                  // 正在学习，取消
                                  cancelSequentialLearn(d.id);
                                } else if (learned) {
                                  // 已学习，发射
                                  emitAircon(d.id, { ...btn, icon: '' });
                                } else {
                                  // 未学习，开始单独学习
                                  learnSingleTemp(d.id, btn.no, btn.label);
                                }
                              }}
                            >
                              {btn.label}
                            </Button>
                          </Col>
                        );
                      })}
                    </Row>

                    {isLearning && (
                      <div style={{ marginTop: 12, fontSize: 13, color: '#666' }}>
                        当前学习：【{ALL_BUTTONS.find((b) => b.no === learningNo)?.label}】，请将遥控器对准设备按键
                      </div>
                    )}
                  </Col>
                </Row>
              </Card>
            </Col>
          );
        })}
      </Row>

      {/* 学习中提示弹窗（保留原有功能） */}
      <Modal
        open={learnModal.open}
        title="红外码学习中..."
        onCancel={() => {
          post(`/devices/${learnModal.deviceId}/ir/cancel`, {}).catch(() => {});
          setLearnModal({ ...learnModal, open: false });
        }}
        footer={[
          <Button key="cancel" onClick={() => {
            post(`/devices/${learnModal.deviceId}/ir/cancel`, {}).catch(() => {});
            setLearnModal({ ...learnModal, open: false });
          }}>
            取消学习
          </Button>,
          <Button key="done" type="primary" onClick={() => setLearnModal({ ...learnModal, open: false })}>
            学习完成
          </Button>,
        ]}
      >
        <Alert
          type="info"
          showIcon
          message={`正在学习编号 ${learnModal.no} 的红外码`}
          description={'请将遥控器对准红外控制器，按一下对应按键。听到"嘀"一声表示学习成功。'}
        />
      </Modal>
    </Spin>
  );
};

export default IRControl;
