import { authenticatedFetch, getApiUrl } from "@/lib/auth";
import type {
  BabyIndices,
  BabyTrimesterEntry,
  ParentIndexPhoto,
  ParentIndices,
  ParentType,
  ProjectIndicesResponse,
  Trimester,
  UpsertBabyIndicesPayload,
  UpsertBabyTrimesterPayload,
  UpsertParentIndicesPayload,
} from "@/types/indices";

function getErrorMessage(payload: unknown, fallback: string) {
  if (payload && typeof payload === "object" && "message" in payload) {
    const { message } = payload as { message?: unknown };
    if (typeof message === "string" && message.trim().length > 0) {
      return message;
    }
  }
  return fallback;
}

async function apiCall<T>(path: string, init?: RequestInit, fallbackError = "Erreur API") {
  const response = await authenticatedFetch(getApiUrl(), path, init);
  let payload: unknown = null;
  try {
    payload = await response.json();
  } catch {
    // ignore
  }
  if (!response.ok) {
    throw new Error(getErrorMessage(payload, fallbackError));
  }
  return payload as T;
}

export function getProjectIndices(projectId: string) {
  return apiCall<ProjectIndicesResponse>(
    `/projects/${projectId}/indices`,
    undefined,
    "Impossible de charger les indices",
  );
}

export function upsertParentIndices(
  projectId: string,
  parentType: ParentType,
  payload: UpsertParentIndicesPayload,
) {
  return apiCall<ParentIndices>(
    `/projects/${projectId}/indices/parents/${parentType}`,
    {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload),
    },
    "Impossible de sauvegarder les indices parent",
  );
}

export function uploadParentPhoto(projectId: string, parentType: ParentType, blob: Blob) {
  const formData = new FormData();
  formData.append("file", blob, "indices-photo.jpg");
  return apiCall<ParentIndexPhoto>(
    `/projects/${projectId}/indices/parents/${parentType}/photos`,
    { method: "POST", body: formData },
    "Impossible d'uploader la photo",
  );
}

export function deleteParentPhoto(projectId: string, parentType: ParentType, photoId: string) {
  return apiCall<{ deleted: boolean }>(
    `/projects/${projectId}/indices/parents/${parentType}/photos/${photoId}`,
    { method: "DELETE" },
    "Impossible de supprimer la photo",
  );
}

export function upsertBabyIndices(
  projectId: string,
  babyIndex: number,
  payload: UpsertBabyIndicesPayload,
) {
  return apiCall<BabyIndices>(
    `/projects/${projectId}/indices/babies/${babyIndex}`,
    {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload),
    },
    "Impossible de sauvegarder les indices bébé",
  );
}

export function upsertBabyTrimester(
  projectId: string,
  babyIndex: number,
  trimester: Trimester,
  payload: UpsertBabyTrimesterPayload,
) {
  return apiCall<BabyTrimesterEntry>(
    `/projects/${projectId}/indices/babies/${babyIndex}/trimesters/${trimester}`,
    {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload),
    },
    "Impossible de sauvegarder les données du trimestre",
  );
}

export function uploadTrimesterPhoto(
  projectId: string,
  babyIndex: number,
  trimester: Trimester,
  blob: Blob,
) {
  const formData = new FormData();
  formData.append("file", blob, "indices-photo.jpg");
  return apiCall<{ id: string; url: string; sortOrder: number; createdAt: string }>(
    `/projects/${projectId}/indices/babies/${babyIndex}/trimesters/${trimester}/photos`,
    { method: "POST", body: formData },
    "Impossible d'uploader la photo",
  );
}

export function deleteTrimesterPhoto(
  projectId: string,
  babyIndex: number,
  trimester: Trimester,
  photoId: string,
) {
  return apiCall<{ deleted: boolean }>(
    `/projects/${projectId}/indices/babies/${babyIndex}/trimesters/${trimester}/photos/${photoId}`,
    { method: "DELETE" },
    "Impossible de supprimer la photo",
  );
}
