type ApiErrorPayload = {
  message?: string;
  issues?: {
    formErrors?: string[];
    fieldErrors?: Record<string, string[] | undefined>;
  };
};

type ApiLikeError = Error & {
  statusCode?: number;
  status?: number;
  data?: ApiErrorPayload;
};

const apiFieldLabels: Record<string, string> = {
  email: "Email",
  password: "Пароль",
  confirmPassword: "Повтор пароля",
  title: "Заголовок",
  body: "Текст",
  status: "Статус",
  startsAt: "Начало",
  expiresAt: "Окончание"
};

function getApiFieldLabel(field: string) {
  return apiFieldLabels[field] ?? field;
}

function getApiErrorMessage(error: ApiLikeError) {
  const formErrors = Array.isArray(error.data?.issues?.formErrors)
    ? error.data!.issues!.formErrors.filter((entry) => typeof entry === "string" && entry.trim())
    : [];

  if (formErrors.length > 0) {
    return formErrors.join("\n");
  }

  const fieldErrors = error.data?.issues?.fieldErrors;
  if (fieldErrors && typeof fieldErrors === "object") {
    const messages = Object.entries(fieldErrors)
      .flatMap(([field, value]) =>
        (Array.isArray(value) ? value : [])
          .filter((entry) => typeof entry === "string" && entry.trim())
          .map((entry) => `${getApiFieldLabel(field)}: ${entry}`)
      );

    if (messages.length > 0) {
      return messages.join("\n");
    }
  }

  const responseMessage = typeof error.data?.message === "string" ? error.data.message.trim() : "";
  if (responseMessage) {
    return responseMessage;
  }

  const statusCode = error.statusCode ?? error.status;

  if (statusCode === 400) return "Проверьте правильность заполнения формы";
  if (statusCode === 401) return "Неверный логин или пароль";
  if (statusCode === 403) return "Недостаточно прав для выполнения действия";
  if (statusCode === 404) return "Запрашиваемые данные не найдены";
  if (statusCode === 409) return "Такая запись уже существует";
  if (statusCode === 422) return "Не удалось обработать введённые данные";
  if (statusCode && statusCode >= 500) return "Ошибка сервера. Попробуйте ещё раз позже";

  return error.message || "Не удалось выполнить запрос";
}

export function useApi<T>(path: string, options: Parameters<typeof $fetch<T>>[1] = {}) {
  const config = useRuntimeConfig();
  const token = useState<string | null>("auth-token", () => null);
  const baseUrl = process.server ? config.apiBaseInternal : config.public.apiBase;

  const headers = new Headers(options.headers as HeadersInit | undefined);
  if (!headers.has("Content-Type") && options.method && options.method !== "GET") {
    headers.set("Content-Type", "application/json");
  }
  if (token.value) {
    headers.set("Authorization", `Bearer ${token.value}`);
  }

  return $fetch<T>(`${baseUrl}${path}`, {
    ...options,
    headers,
    credentials: "include"
  }).catch((error: ApiLikeError) => {
    throw new Error(getApiErrorMessage(error));
  });
}
