import type { Memo, Reaction } from "@/types/proto/api/v1/memo_service_pb";
import { fetchJson, parseResourceId } from "./apiClient";
import { applyMemoFilter, extractTagFilter, memoFromApi, visibilityToApi } from "./converters";
import type { ApiMemo } from "./types";

export const memoServiceClient = {
  async listMemos(request: { filter?: string } = {}): Promise<{ memos: Memo[]; nextPageToken: string }> {
    const tag = extractTagFilter(request.filter);
    const params = new URLSearchParams();
    if (tag) params.append("tag", tag);
    if (request.filter) {
      console.log("DEBUG listMemos filter:", request.filter);
      params.append("filter", request.filter);
    }
    const query = params.toString() ? `?${params.toString()}` : "";
    console.log("DEBUG listMemos URL:", `/memos${query}`);
    const data = await fetchJson<ApiMemo[]>(`/memos${query}`, { method: "GET" });
    console.log("DEBUG listMemos response count:", Array.isArray(data) ? data.length : 0);
    const memos = Array.isArray(data) ? data.map(memoFromApi) : [];
    const filtered = applyMemoFilter(memos, request.filter);
    console.log("DEBUG listMemos after filter count:", filtered.length);
    return { memos: filtered, nextPageToken: "" };
  },
  async getMemo(request: { name: string }): Promise<Memo> {
    const memoId = parseResourceId(request.name);
    const data = await fetchJson<ApiMemo>(`/memos/${memoId}`, { method: "GET" });
    return memoFromApi(data);
  },
  async createMemo(request: { memo?: Memo }): Promise<Memo> {
    const memo = request.memo;
    if (!memo) {
      throw new Error("Missing memo payload");
    }
    const payload = {
      content: memo.content,
      visibility: visibilityToApi(memo.visibility),
      tags: memo.tags || [],
      create_time: memo.createTime ? new Date(Number(memo.createTime.seconds) * 1000).toISOString() : undefined,
    };
    const data = await fetchJson<ApiMemo>("/memos", { method: "POST", body: payload });
    return memoFromApi(data);
  },
  async updateMemo(request: { memo?: Memo }): Promise<Memo> {
    const memo = request.memo;
    if (!memo?.name) {
      throw new Error("Missing memo name");
    }
    const memoId = parseResourceId(memo.name);
    const payload: { content?: string; visibility?: string; tags?: string[] } = {};
    if (memo.content !== undefined) {
      payload.content = memo.content;
    }
    if (memo.visibility !== undefined) {
      payload.visibility = visibilityToApi(memo.visibility);
    }
    if (memo.tags) {
      payload.tags = memo.tags;
    }
    const data = await fetchJson<ApiMemo>(`/memos/${memoId}`, { method: "PATCH", body: payload });
    return memoFromApi(data);
  },
  async deleteMemo(request: { name: string }): Promise<void> {
    const memoId = parseResourceId(request.name);
    await fetchJson(`/memos/${memoId}`, { method: "DELETE" });
  },
  async createMemoComment(request: { name: string; comment?: Memo; anonymousId?: string; anonymousName?: string }): Promise<Memo> {
    if (!request.comment) {
      throw new Error("Missing comment payload");
    }
    const memoId = parseResourceId(request.name);
    const payload: {
      content: string;
      visibility: string;
      tags: string[];
      anonymous_id?: string;
      anonymous_name?: string;
    } = {
      content: request.comment.content,
      visibility: visibilityToApi(request.comment.visibility),
      tags: request.comment.tags || [],
    };
    // Add anonymous fields if provided
    if (request.anonymousId) {
      payload.anonymous_id = request.anonymousId;
    }
    if (request.anonymousName) {
      payload.anonymous_name = request.anonymousName;
    }
    const data = await fetchJson<ApiMemo>(`/memos/${memoId}/comments`, {
      method: "POST",
      body: payload,
    });
    return memoFromApi(data);
  },
  async listMemoComments(request: { name: string; anonymousId?: string }): Promise<{ memos: Memo[]; nextPageToken: string; totalSize: number }> {
    const memoId = parseResourceId(request.name);
    const url = new URL(`/memos/${memoId}/comments`, window.location.origin);
    if (request.anonymousId) {
      url.searchParams.set("anonymous_id", request.anonymousId);
    }
    const data = await fetchJson<{ memos: ApiMemo[]; nextPageToken: string; totalSize: number }>(
      url.pathname + url.search,
      { method: "GET" }
    );
    const memos = Array.isArray(data.memos) ? data.memos.map(memoFromApi) : [];
    return {
      memos,
      nextPageToken: data.nextPageToken || "",
      totalSize: data.totalSize || memos.length,
    };
  },
  async upsertMemoReaction(request: { name: string; reaction?: Partial<Reaction> }): Promise<Reaction> {
    const reactionType = request.reaction?.reactionType || "";
    const contentId = request.reaction?.contentId || request.name;
    return {
      name: `${request.name}/reactions/1`,
      creator: "users/1",
      contentId,
      reactionType,
    };
  },
  async deleteMemoReaction(_request: { name: string }): Promise<void> {
    void _request;
    return;
  },
};

