import { useRuntimeConfig } from "#app";
import type { FetchResponse } from "ofetch";
import { workpulseApiRaw } from "~/utils/workpulse-api-fetch";
import { normalizeWorkpulseApiBase } from "~/utils/workpulse-api-base";
import { readWorkpulseAccessToken } from "~/utils/workpulse-session-user";
import { useAuth } from "./useAuth";
import { useWorkpulseMe } from "./useWorkpulseMe";

const STATE_KEY = "workpulse:notifications-unread";

type ApiEnvelope<T> = {
  ok: boolean;
  data?: T;
  error?: { code?: string; message?: string };
};

export type NotificationRow = {
  id: number;
  title: string;
  body: string;
  createdAt: string;
  read: boolean;
  readAt?: string | null;
};

function apiBase(): string {
  return normalizeWorkpulseApiBase(String(useRuntimeConfig().public.workpulseApiBase || ""));
}

function bearerHeaders(): { Authorization: string } | undefined {
  const { accessToken } = useAuth();
  const t = accessToken.value || readWorkpulseAccessToken();
  if (!t) return undefined;
  return { Authorization: `Bearer ${t}` };
}

async function parseEnvelope<T>(raw: FetchResponse<unknown>): Promise<{
  ok: boolean;
  status: number;
  data?: T;
  message?: string;
}> {
  const status = raw.status;
  let body = raw._data as ApiEnvelope<T> | string | undefined;
  if (typeof body === "string") {
    try {
      body = JSON.parse(body) as ApiEnvelope<T>;
    } catch {
      body = undefined;
    }
  }
  if (!body) return { ok: false, status, message: `HTTP ${status}` };
  if (!body.ok) {
    return {
      ok: false,
      status,
      message: body.error?.message || body.error?.code || `HTTP ${status}`
    };
  }
  return { ok: true, status, data: body.data as T };
}

/**
 * Jumlah notifikasi belum dibaca (`GET /api/v1/me/summary` → `notificationsUnread`).
 * Dipakai badge sidebar / topbar.
 */
export function useNotificationUnreadCount() {
  const count = useState<number>(STATE_KEY, () => 0);

  const refresh = async () => {
    if (!import.meta.client) return;
    const { getMeSummary } = useWorkpulseMe();
    const r = await getMeSummary({ period: "month" });
    if (r.ok && r.data) count.value = Math.max(0, Number(r.data.notificationsUnread) || 0);
  };

  return { count, refresh };
}

export function useWorkpulseNotifications() {
  const { refresh: refreshUnread } = useNotificationUnreadCount();

  const listNotifications = async () => {
    const b = apiBase();
    if (!b) return { ok: false as const, status: 0, message: "Layanan belum siap.", items: [] as NotificationRow[] };
    const raw = await workpulseApiRaw(`${b}/api/v1/notifications`, {
      method: "GET",
      headers: bearerHeaders(),
      credentials: "include",
      ignoreResponseError: true
    });
    const parsed = await parseEnvelope<NotificationRow[]>(raw);
    if (!parsed.ok || !parsed.data) {
      return {
        ok: false as const,
        status: parsed.status,
        message: parsed.message || "Gagal memuat notifikasi.",
        items: [] as NotificationRow[]
      };
    }
    const items = Array.isArray(parsed.data) ? parsed.data : [];
    return { ok: true as const, status: parsed.status, items };
  };

  const markAllRead = async () => {
    const b = apiBase();
    if (!b) return { ok: false as const, status: 0, message: "Layanan belum siap." };
    const raw = await workpulseApiRaw(`${b}/api/v1/notifications/read`, {
      method: "PATCH",
      headers: bearerHeaders(),
      credentials: "include",
      body: {},
      ignoreResponseError: true
    });
    const parsed = await parseEnvelope<{ ok?: boolean }>(raw);
    if (!parsed.ok) {
      return { ok: false as const, status: parsed.status, message: parsed.message || "Gagal menandai semua." };
    }
    await refreshUnread();
    return { ok: true as const, status: parsed.status };
  };

  const markOneRead = async (id: number) => {
    const b = apiBase();
    if (!b) return { ok: false as const, status: 0, message: "Layanan belum siap." };
    const raw = await workpulseApiRaw(`${b}/api/v1/notifications/${id}/read`, {
      method: "PATCH",
      headers: bearerHeaders(),
      credentials: "include",
      body: {},
      ignoreResponseError: true
    });
    const parsed = await parseEnvelope<{ updated?: boolean }>(raw);
    if (!parsed.ok) {
      return { ok: false as const, status: parsed.status, message: parsed.message || "Gagal memperbarui." };
    }
    await refreshUnread();
    return { ok: true as const, status: parsed.status };
  };

  return { listNotifications, markAllRead, markOneRead };
}
