import { arrayToDateTimeString } from "@/app/utils/formatUtil";
import dayjs, { type Dayjs } from "dayjs";

export type ConnectivityHistoryEvent = {
  deviceId: string;
  status: string;
  recordedAt?: unknown;
};

export type ConnectivityChartBuckets = {
  bucketMinutes: number;
  categories: string[];
  offlineCounts: number[];
  poorCounts: number[];
  affectedDeviceCounts: number[];
};

export function parseMonitoringDateTime(value: unknown): Dayjs | null {
  if (value == null) return null;
  if (Array.isArray(value)) {
    const s = arrayToDateTimeString(value as (number | undefined)[]);
    const d = dayjs(s);
    return d.isValid() ? d : null;
  }
  const d = dayjs(value as string | number);
  return d.isValid() ? d : null;
}

export function pickBucketMinutes(rangeHours: number): number {
  if (rangeHours <= 6) return 15;
  if (rangeHours <= 48) return 30;
  if (rangeHours <= 24 * 7) return 60;
  return 360;
}

export function buildConnectivityChartBuckets(
  events: ConnectivityHistoryEvent[],
  fromLocal: string,
  toLocal: string
): ConnectivityChartBuckets | null {
  const from = dayjs(fromLocal.replace(" ", "T"));
  const to = dayjs(toLocal.replace(" ", "T"));
  if (!from.isValid() || !to.isValid() || !from.isBefore(to)) {
    return null;
  }

  const rangeHours = to.diff(from, "minute") / 60;
  const bucketMinutes = pickBucketMinutes(rangeHours);
  const categories: string[] = [];
  const offlineCounts: number[] = [];
  const poorCounts: number[] = [];
  const affectedDeviceCounts: number[] = [];

  let cursor = from;
  while (cursor.isBefore(to)) {
    const bucketEnd = cursor.add(bucketMinutes, "minute");
    const end = bucketEnd.isAfter(to) ? to : bucketEnd;

    const inBucket = events.filter((ev) => {
      const t = parseMonitoringDateTime(ev.recordedAt);
      return t != null && !t.isBefore(cursor) && t.isBefore(end);
    });

    const offline = inBucket.filter((e) => e.status === "offline").length;
    const poor = inBucket.filter((e) => e.status === "poor").length;
    const devices = new Set(inBucket.map((e) => e.deviceId)).size;

    const label =
      bucketMinutes >= 60
        ? cursor.format("MM-DD HH:mm")
        : cursor.format("HH:mm");

    categories.push(label);
    offlineCounts.push(offline);
    poorCounts.push(poor);
    affectedDeviceCounts.push(devices);

    cursor = end;
  }

  return {
    bucketMinutes,
    categories,
    offlineCounts,
    poorCounts,
    affectedDeviceCounts,
  };
}
