import type { Statistic } from "@allurereport/core-api";
import { errorMessageFromUnknown, fetchReportJsonData } from "@allurereport/web-commons";
import { signal } from "@preact/signals";

import type { StoreSignalState } from "@/stores/types";

import type { AwesomeTree } from "../../types";

export const reportStatsStore = signal<StoreSignalState<Statistic>>({
  loading: true,
  error: undefined,
  data: {
    total: 0,
  },
});

export const statsByEnvStore = signal<StoreSignalState<Record<string, Statistic>>>({
  loading: true,
  error: undefined,
  data: {},
});

export const fetchReportStats = async () => {
  reportStatsStore.value = {
    ...reportStatsStore.peek(),
    loading: true,
    error: undefined,
  };

  try {
    const res = await fetchReportJsonData<Statistic>("widgets/statistic.json", { bustCache: true });

    reportStatsStore.value = {
      data: res,
      error: undefined,
      loading: false,
    };
  } catch (err) {
    reportStatsStore.value = {
      data: { total: 0 },
      error: errorMessageFromUnknown(err),
      loading: false,
    };
  }
};

export const fetchEnvStats = async (envs: string[]) => {
  const envsToFetch = envs.filter((env) => !statsByEnvStore.peek().data?.[env]);

  // all envs have already been fetched
  if (envsToFetch.length === 0) {
    return;
  }

  statsByEnvStore.value = {
    ...statsByEnvStore.peek(),
    loading: true,
    error: undefined,
  };

  try {
    const data = await Promise.all(
      envsToFetch.map((env) => fetchReportJsonData<AwesomeTree>(`widgets/${env}/statistic.json`, { bustCache: true })),
    );
    const previous = statsByEnvStore.peek().data;

    statsByEnvStore.value = {
      data: envsToFetch.reduce(
        (acc, env, index) => {
          return {
            ...acc,
            [env]: data[index],
          };
        },
        { ...previous },
      ),
      loading: false,
      error: undefined,
    };
  } catch (err) {
    statsByEnvStore.value = {
      ...statsByEnvStore.peek(),
      error: errorMessageFromUnknown(err),
      loading: false,
    };
  }
};
