import {
  mapApiMeetingToCalendarRow,
  type MeetingCalendarApiMeeting,
  type MeetingCalendarApiListResponse,
  type MeetingCalendarRow,
} from "./meeting-calendar-data";
import type { MeetingSavePayload } from "./meeting-create-form";

const API_BASE_URL =
  process.env.NEXT_PUBLIC_API_URL || "http://localhost:3001/api/v1";

type ApiResponse<T> = {
  success: boolean;
  statusCode: number;
  message: string;
  data: T;
};

export type MeetingGuestUser = {
  id: number;
  name?: string | null;
  email?: string | null;
  avatar?: string | null;
  position?: string | null;
};

function getAccessToken() {
  if (typeof window === "undefined") return "";

  return (
    localStorage.getItem("accessToken") ||
    localStorage.getItem("token") ||
    localStorage.getItem("authToken") ||
    ""
  );
}

async function apiFetch<T>(path: string, options: RequestInit = {}): Promise<T> {
  const token = getAccessToken();
  const hasBody = Boolean(options.body);

  const response = await fetch(`${API_BASE_URL}${path}`, {
    ...options,
    cache: "no-store",
    credentials: "include",
    headers: {
      Accept: "application/json",
      ...(hasBody ? { "Content-Type": "application/json" } : {}),
      ...(token ? { Authorization: `Bearer ${token}` } : {}),
      ...options.headers,
    },
  });

  const json = (await response
    .json()
    .catch(() => null)) as ApiResponse<T> | null;

  if (!response.ok) {
    throw new Error(json?.message || `API error ${response.status}`);
  }

  return json?.data as T;
}

export async function getMeetingCalendarRows(): Promise<MeetingCalendarRow[]> {
  const data = await apiFetch<MeetingCalendarApiListResponse>("/meetings");

  return data.items.map(mapApiMeetingToCalendarRow);
}

export async function getMeetingById(
  id: number,
): Promise<MeetingCalendarApiMeeting> {
  return apiFetch<MeetingCalendarApiMeeting>(`/meetings/${id}`);
}

export async function createMeeting(
  payload: MeetingSavePayload,
): Promise<MeetingCalendarApiMeeting> {
  const data = await apiFetch<{
    message: string;
    meeting: MeetingCalendarApiMeeting;
  }>("/meetings", {
    method: "POST",
    body: JSON.stringify(payload),
  });

  return data.meeting;
}

export async function updateMeeting(
  id: number,
  payload: MeetingSavePayload,
): Promise<MeetingCalendarApiMeeting> {
  const data = await apiFetch<{
    message: string;
    meeting: MeetingCalendarApiMeeting;
  }>(`/meetings/${id}`, {
    method: "PATCH",
    body: JSON.stringify(payload),
  });

  return data.meeting;
}

export async function getMeetingRequestGuestUsers(
  meetingRequestId: number,
): Promise<MeetingGuestUser[]> {
  return apiFetch<MeetingGuestUser[]>(
    `/meetings/meeting-requests/${meetingRequestId}/guest-users`,
  );
}
