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";

type ApiEnvelope<T> = {
  ok: boolean;
  data?: T;
  error?: { code?: string; message?: string };
};

export type ChatMessageRow = {
  id: number;
  userId: number;
  authorName: string;
  authorEmail?: string;
  authorAvatarUrl?: string | null;
  body: string;
  mentionUserIds: number[];
  attachments: ChatAttachment[];
  replyTo?: ChatReply | null;
  createdAt: string;
};

export type ChatReply = {
  id: number;
  authorName: string;
  body: string;
};

export type ChatAttachment = {
  id: string;
  url: string;
  name: string;
  mimeType: string;
  size: number;
};

export type ChatMentionUser = {
  id: number;
  email: string;
  name: string;
  division: string;
};

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 };
}

export function useWorkpulseChat() {
  const listMessages = async (opts?: { beforeId?: number; limit?: number }) => {
    const b = apiBase();
    if (!b) {
      return { ok: false as const, status: 0, message: "Layanan belum siap.", items: [] as ChatMessageRow[] };
    }
    const params = new URLSearchParams();
    if (opts?.limit) params.set("limit", String(opts.limit));
    if (opts?.beforeId) params.set("beforeId", String(opts.beforeId));
    const qs = params.toString();
    const raw = await workpulseApiRaw(`${b}/api/v1/chat/messages${qs ? `?${qs}` : ""}`, {
      method: "GET",
      headers: bearerHeaders(),
      credentials: "include",
      ignoreResponseError: true
    });
    const parsed = await parseEnvelope<ChatMessageRow[]>(raw);
    if (!parsed.ok) {
      return {
        ok: false as const,
        status: parsed.status,
        message: parsed.message || "Gagal memuat pesan.",
        items: [] as ChatMessageRow[]
      };
    }
    const items = Array.isArray(parsed.data) ? parsed.data : parsed.data == null ? [] : [];
    return { ok: true as const, status: parsed.status, items };
  };

  const sendMessage = async (
    body: string,
    mentionUserIds: number[],
    files: File[] = [],
    replyToMessageId?: number | null
  ) => {
    const b = apiBase();
    if (!b) return { ok: false as const, status: 0, message: "Layanan belum siap." };
    let raw: FetchResponse<unknown>;
    if (files.length > 0) {
      const form = new FormData();
      form.append("body", body);
      form.append("mentionUserIds", JSON.stringify(mentionUserIds));
      if (replyToMessageId) form.append("replyToMessageId", String(replyToMessageId));
      for (const file of files) {
        form.append("files", file, file.name || "chat-image.png");
      }
      raw = await workpulseApiRaw(`${b}/api/v1/chat/messages/attachments`, {
        method: "POST",
        headers: bearerHeaders(),
        credentials: "include",
        body: form,
        ignoreResponseError: true
      });
    } else {
      raw = await workpulseApiRaw(`${b}/api/v1/chat/messages`, {
        method: "POST",
        headers: { ...bearerHeaders(), "Content-Type": "application/json" },
        credentials: "include",
        body: { body, mentionUserIds, replyToMessageId: replyToMessageId || undefined },
        ignoreResponseError: true
      });
    }
    const parsed = await parseEnvelope<ChatMessageRow>(raw);
    if (!parsed.ok) {
      return { ok: false as const, status: parsed.status, message: parsed.message || "Gagal mengirim." };
    }
    return { ok: true as const, status: parsed.status, message: parsed.data };
  };

  const searchMentionUsers = async (q: string) => {
    const b = apiBase();
    if (!b) return { ok: false as const, status: 0, message: "Layanan belum siap.", items: [] as ChatMentionUser[] };
    const params = new URLSearchParams();
    if (q.trim()) params.set("q", q.trim());
    params.set("limit", "20");
    const raw = await workpulseApiRaw(`${b}/api/v1/chat/mention-users?${params}`, {
      method: "GET",
      headers: bearerHeaders(),
      credentials: "include",
      ignoreResponseError: true
    });
    const parsed = await parseEnvelope<ChatMentionUser[]>(raw);
    if (!parsed.ok) {
      return {
        ok: false as const,
        status: parsed.status,
        message: parsed.message || "Gagal memuat daftar.",
        items: [] as ChatMentionUser[]
      };
    }
    const items = Array.isArray(parsed.data) ? parsed.data : parsed.data == null ? [] : [];
    return { ok: true as const, status: parsed.status, items };
  };

  const clearAllMessages = async () => {
    const b = apiBase();
    if (!b) return { ok: false as const, status: 0, message: "Layanan belum siap." };
    const raw = await workpulseApiRaw(`${b}/api/v1/chat/messages`, {
      method: "DELETE",
      headers: bearerHeaders(),
      credentials: "include",
      ignoreResponseError: true
    });
    const parsed = await parseEnvelope<{ deleted: number }>(raw);
    if (!parsed.ok) {
      return { ok: false as const, status: parsed.status, message: parsed.message || "Gagal menghapus chat." };
    }
    return { ok: true as const, status: parsed.status, deleted: parsed.data?.deleted ?? 0 };
  };

  return { listMessages, sendMessage, searchMentionUsers, clearAllMessages };
}
