import { ref, onUnmounted } from "vue";
import { getDashboardDevice } from "@/apis/dashboard";

export function useDashboardDevice() {
  const rawData = ref([]);
  const subscribers = ref([]);

  // 獲取設備資料
  const getDevice = async (option = 1) => {
    try {
      const res = await getDashboardDevice({
        option: parseInt(option),
      });

      rawData.value = res.data.map((d) => ({
        ...d,
        key: d.subSys,
        // 初始化點位值物件
        device: d.device.map((device) => ({
          ...device,
          pointValues: {},
        })),
      }));
    } catch (err) {
      console.error("獲取設備資料失敗:", err);
    }
  };

  // 清理所有訂閱者
  const clearSubscribers = () => {
    subscribers.value.forEach((subscriber) => {
      try {
        subscriber.detach("changed");
        subscriber.unsubscribeAll();
      } catch (err) {
        console.warn("清理訂閱者失敗:", err);
      }
    });
    subscribers.value = [];
    console.log("所有設備訂閱已清除");
  };

  // 更新設備點位值
  const updateDevicePointValue = (deviceNumber, pointName, value) => {
    rawData.value.forEach((category) => {
      category.device.forEach((device) => {
        if (device.device_number === deviceNumber) {
          if (!device.pointValues) {
            device.pointValues = {};
          }
          device.pointValues[pointName] = value;
          console.log(`設備 ${deviceNumber} 的 ${pointName} 更新為:`, value);
        }
      });
    });
  };

  // 訂閱單個設備
  const subscribeToDevice = (item) => {
    const slotPath = item.slotPath;
    const ordString = `local:|foxs:|station:|${slotPath}`;

    // @ts-ignore
    window.require &&
      // @ts-ignore
      window.requirejs(["baja!"], (baja) => {
        // 建立訂閱器
        const subscriber = new baja.Subscriber();

        // 定義 changed 事件的處理函數
        subscriber.attach("changed", (prop) => {
          try {
            if (prop && prop.getName() === "out") {
              // 取得 out 的新值
              const match = prop.$display.match(/^(\d+(\.\d+)?)/);
              const newValue = match ? parseFloat(match[0]) : prop.newValue || 0;

              // 更新對應設備的點位值
              updateDevicePointValue(item.displayName, item.name, newValue);
            }
          } catch (error) {
            console.error(`處理 ${item.displayName} 的 ${item.name} 變化失敗:`, error);
          }
        });

        baja.Ord.make(ordString)
          .get({ subscriber })
          .then(() => {
            console.log(`成功訂閱設備: ${item.displayName} - ${item.name}`);
          })
          .catch((err) => {
            console.error(`訂閱 ${item.displayName} 失敗:`, err.message);
            subscriber.detach("changed");
          });

        subscribers.value.push(subscriber);
      });
  };

  // 訂閱 Niagara 資料
  const subscribeNiagaraData = async (option) => {
    try {
      // 先清理舊的訂閱者
      clearSubscribers();

      const ordString = `local:|foxs:|station:|slot:/Drivers|neql:IBMS:PD0${option}|bql:select slotPath,parent.displayName,name,out`;
      console.log("訂閱 Niagara 資料:", ordString);

      // @ts-ignore
      window.require &&
        // @ts-ignore
        window.requirejs(["baja!"], (baja) => {
          let deviceList = [];

          baja.Ord.make(ordString).get({
            cursor: {
              before: () => {
                console.log("開始獲取設備清單");
              },
              each: (record) => {
                const newItem = {
                  slotPath: record.get("slotPath"),
                  displayName: record.get("parent$2edisplayName"),
                  name: record.get("name"),
                  out: record.get("out")?.get("value") ?? 0,
                };
                deviceList.push(newItem);
              },
              after: () => {
                console.log(`找到 ${deviceList.length} 個設備點位`);
                // 對每個設備點位進行訂閱
                deviceList.forEach((item) => {
                  subscribeToDevice(item);
                });
              },
            },
          });
        });
    } catch (err) {
      console.error("訂閱 Niagara 資料失敗:", err);
    }
  };

  // 處理選項變更
  const handleOptionChange = async (newOption) => {
    try {
      // 先獲取設備資料，再訂閱 Niagara 資料
      await getDevice(newOption);
      await subscribeNiagaraData(newOption);
    } catch (err) {
      console.error("處理選項變更失敗:", err);
    }
  };

  // 取得特定設備的點位值
  const getDevicePointValue = (deviceNumber, pointName) => {
    for (const category of rawData.value) {
      const device = category.device.find(
        (d) => d.device_number === deviceNumber
      );
      if (device && device.pointValues) {
        return device.pointValues[pointName];
      }
    }
    return null;
  };

  // 取得特定類別的所有設備
  const getCategoryDevices = (subSys) => {
    const category = rawData.value.find((c) => c.subSys === subSys);
    return category ? category.device : [];
  };

  // 清理函數
  const cleanup = () => {
    clearSubscribers();
    rawData.value = [];
  };

  // 元件卸載時自動清理
  onUnmounted(() => {
    cleanup();
  });

  return {
    // 狀態
    rawData,

    // 方法
    getDevice,
    subscribeNiagaraData,
    handleOptionChange,
    getDevicePointValue,
    getCategoryDevices,
    cleanup,

    // 內部方法（如果需要的話）
    updateDevicePointValue,
    clearSubscribers,
  };
}
