import {
  AUTO_REFRESH_INTERVAL,
  EVENT_ALARM_DATA,
  EVENT_BANZONE_DATA,
  EVENT_ENTITY_DATA,
  EVENT_GPS_DATA,
  EVENT_TRACK_POINTS_DATA,
} from "@/constants";
import {
  queryAlarm,
  queryEntities,
  queryGpsData,
  queryTrackPoints,
} from "@/controller/DeviceController";
import { queryBanzones } from "@/controller/MapController";
import eventBus from "@/utils/eventBus";

const intervals: {
  gps: ReturnType<typeof setInterval> | null;
  alarm: ReturnType<typeof setInterval> | null;
  entities: ReturnType<typeof setInterval> | null;
  trackPoints: ReturnType<typeof setInterval> | null;
  banzones: ReturnType<typeof setInterval> | null;
} = {
  gps: null,
  alarm: null,
  entities: null,
  trackPoints: null,
  banzones: null,
};

export function getGpsEventBus() {
  if (intervals.gps) return;
  // console.log("Starting GPS poller");

  const getGpsData = async () => {
    try {
      // console.log("GPS: fetching data...");
      const resp = await queryGpsData();
      if (resp && resp.data) {
        // console.log("GPS: emitting data", resp.data);
        eventBus.emit(EVENT_GPS_DATA, resp.data);
      } else {
        console.log("GPS: no data returned");
      }
    } catch (err) {
      console.error("GPS: fetch error", err);
    }
  };

  // Run immediately once, then schedule
  getGpsData();
  intervals.gps = setInterval(() => {
    getGpsData();
  }, AUTO_REFRESH_INTERVAL);
}

export function getAlarmEventBus() {
  if (intervals.alarm) return;
  // console.log("Goi ham get Alarm");
  const getAlarmData = async () => {
    try {
      // console.log("Alarm: fetching data...");
      const resp = await queryAlarm();
      if (resp && resp.data) {
        // console.log(
        // "Alarm: emitting data",
        // resp.data?.alarms?.length ?? resp.data
        // );
        eventBus.emit(EVENT_ALARM_DATA, resp.data);
      } else {
        console.log("Alarm: no data returned");
      }
    } catch (err) {
      console.error("Alarm: fetch error", err);
    }
  };

  getAlarmData();
  intervals.alarm = setInterval(() => {
    getAlarmData();
  }, AUTO_REFRESH_INTERVAL);
}

export function getEntitiesEventBus() {
  if (intervals.entities) return;
  // console.log("Goi ham get Entities");
  const getEntitiesData = async () => {
    try {
      // console.log("Entities: fetching data...");
      const resp = await queryEntities();
      if (resp && resp.length > 0) {
        // console.log("Entities: emitting", resp.length);
        eventBus.emit(EVENT_ENTITY_DATA, resp);
      } else {
        console.log("Entities: no data returned");
      }
    } catch (err) {
      console.error("Entities: fetch error", err);
    }
  };

  getEntitiesData();
  intervals.entities = setInterval(() => {
    getEntitiesData();
  }, AUTO_REFRESH_INTERVAL);
}

export function getTrackPointsEventBus() {
  if (intervals.trackPoints) return;
  // console.log("Goi ham get Track Points");
  const getTrackPointsData = async () => {
    try {
      // console.log("TrackPoints: fetching data...");
      const resp = await queryTrackPoints();
      if (resp && resp.data && resp.data.length > 0) {
        // console.log("TrackPoints: emitting", resp.data.length);
        eventBus.emit(EVENT_TRACK_POINTS_DATA, resp.data);
      } else {
        console.log("TrackPoints: no data returned");
      }
    } catch (err) {
      console.error("TrackPoints: fetch error", err);
    }
  };

  getTrackPointsData();
  intervals.trackPoints = setInterval(() => {
    getTrackPointsData();
  }, AUTO_REFRESH_INTERVAL);
}

export function getBanzonesEventBus() {
  if (intervals.banzones) return;
  const getBanzonesData = async () => {
    try {
      // console.log("Banzones: fetching data...");
      const resp = await queryBanzones();
      if (resp && resp.data && resp.data.length > 0) {
        // console.log("Banzones: emitting", resp.data.length);
        eventBus.emit(EVENT_BANZONE_DATA, resp.data);
      } else {
        console.log("Banzones: no data returned");
      }
    } catch (err) {
      console.error("Banzones: fetch error", err);
    }
  };

  getBanzonesData();
  intervals.banzones = setInterval(() => {
    getBanzonesData();
  }, AUTO_REFRESH_INTERVAL * 60);
}

export function stopEvents() {
  Object.keys(intervals).forEach((k) => {
    const key = k as keyof typeof intervals;
    if (intervals[key]) {
      clearInterval(intervals[key] as ReturnType<typeof setInterval>);
      intervals[key] = null;
    }
  });
}

export function startEvents() {
  getGpsEventBus();
  getAlarmEventBus();
  getEntitiesEventBus();
  getTrackPointsEventBus();
  getBanzonesEventBus();
}
