import type {
    CommentType,
    CommentTypeFormValue,
} from "../types/comment-types-types";

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

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

function getApiUrl(path: string): string {
    return `${API_BASE_URL.replace(/\/$/, "")}/${path.replace(/^\//, "")}`;
}

async function parseResponse<T>(response: Response): Promise<T> {
    const body = (await response.json().catch(() => null)) as
        | ApiResponse<T>
        | T
        | null;

    if (!response.ok) {
        const message =
            body && typeof body === "object" && "message" in body
                ? String(body.message)
                : `Request failed with status ${response.status}`;

        throw new Error(message);
    }

    if (body && typeof body === "object" && "data" in body) {
        return body.data as T;
    }

    return body as T;
}

export async function getCommentTypes(): Promise<CommentType[]> {
    const response = await fetch(getApiUrl("comment-types"), {
        method: "GET",
        credentials: "include",
        headers: { Accept: "application/json" },
        cache: "no-store",
    });

    const data = await parseResponse<CommentType[] | { items?: CommentType[] }>(response);
    if (Array.isArray(data)) return data;
    return Array.isArray(data?.items) ? data.items : [];
}

export async function createCommentType(payload: CommentTypeFormValue): Promise<CommentType> {
    const response = await fetch(getApiUrl("comment-types"), {
        method: "POST",
        credentials: "include",
        headers: {
            Accept: "application/json",
            "Content-Type": "application/json",
        },
        body: JSON.stringify({
            name: payload.name.trim(),
            description: payload.description.trim() || null,
        }),
    });

    return parseResponse<CommentType>(response);
}

export async function updateCommentType(
    id: number,
    payload: CommentTypeFormValue,
): Promise<CommentType> {
    const response = await fetch(getApiUrl(`comment-types/${id}`), {
        method: "PATCH",
        credentials: "include",
        headers: {
            Accept: "application/json",
            "Content-Type": "application/json",
        },
        body: JSON.stringify({
            name: payload.name.trim(),
            description: payload.description.trim() || null,
        }),
    });

    return parseResponse<CommentType>(response);
}

export async function deleteCommentType(id: number): Promise<void> {
    const response = await fetch(getApiUrl(`comment-types/${id}`), {
        method: "DELETE",
        credentials: "include",
        headers: { Accept: "application/json" },
    });

    if (!response.ok) {
        await parseResponse<unknown>(response);
    }
}
