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 type { WorkpulseLocale } from "~/utils/workpulse-locale-messages";
import { useAuth } from "./useAuth";

type ApiEnvelope<T> = {
  ok: boolean;
  data?: T;
  error?: { code?: string; message?: string };
};

export type WorkpulsePreferences = {
  theme?: "light" | "dark";
  language?: WorkpulseLocale;
};

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 };
}

function normalizePreferences(raw: Record<string, unknown> | undefined | null): WorkpulsePreferences {
  const prefs: WorkpulsePreferences = {};
  if (!raw) return prefs;
  const theme = raw.theme;
  if (theme === "light" || theme === "dark") prefs.theme = theme;
  const lang = raw.language;
  if (lang === "id" || lang === "en") prefs.language = lang;
  return prefs;
}

export function useWorkpulsePreferences() {
  const { setTheme } = useTheme();
  const { applyLocale } = useWorkpulseLocale();

  const applyPreferences = (prefs: WorkpulsePreferences) => {
    if (prefs.theme === "dark" || prefs.theme === "light") {
      setTheme(prefs.theme === "dark");
    }
    if (prefs.language === "id" || prefs.language === "en") {
      applyLocale(prefs.language);
    }
  };

  const getPreferences = async () => {
    const b = apiBase();
    if (!b) return { ok: false as const, status: 0, message: "API belum dikonfigurasi." };
    const raw = await workpulseApiRaw(`${b}/api/v1/settings`, {
      headers: bearerHeaders(),
      credentials: "include",
      ignoreResponseError: true
    });
    const parsed = await parseEnvelope<{ preferences: Record<string, unknown> }>(raw);
    if (!parsed.ok || !parsed.data) return parsed;
    const preferences = normalizePreferences(parsed.data.preferences);
    return { ...parsed, data: { preferences } };
  };

  const savePreferences = async (patch: WorkpulsePreferences) => {
    const b = apiBase();
    if (!b) return { ok: false as const, status: 0, message: "API belum dikonfigurasi." };

    const current = await getPreferences();
    const merged: WorkpulsePreferences = {
      ...(current.ok && current.data ? current.data.preferences : {}),
      ...patch
    };

    const body: Record<string, string> = {};
    if (merged.theme) body.theme = merged.theme;
    if (merged.language) body.language = merged.language;

    const raw = await workpulseApiRaw(`${b}/api/v1/settings`, {
      method: "PATCH",
      headers: { ...bearerHeaders(), "Content-Type": "application/json" },
      body: { preferences: body },
      credentials: "include",
      ignoreResponseError: true
    });
    const parsed = await parseEnvelope<{ preferences: Record<string, unknown> }>(raw);
    if (!parsed.ok || !parsed.data) return parsed;
    const preferences = normalizePreferences(parsed.data.preferences);
    applyPreferences(preferences);
    return { ...parsed, data: { preferences } };
  };

  const loadAndApplyPreferences = async () => {
    const res = await getPreferences();
    if (res.ok && res.data) {
      applyPreferences(res.data.preferences);
    }
    return res;
  };

  return {
    getPreferences,
    savePreferences,
    loadAndApplyPreferences,
    applyPreferences,
    normalizePreferences
  };
}
