import type {
  CreatePersonalAccessTokenResponse,
  PersonalAccessToken,
  User,
  UserNotification,
  UserSetting,
  UserStats,
  UserWebhook,
  UserSetting_GeneralSetting,
  UserSetting_WebhooksSetting,
} from "@/types/proto/api/v1/user_service_pb";
import { fetchJson, parseResourceId } from "./apiClient";
import { userFromApi } from "./converters";
import type { ApiUser } from "./types";

const defaultUserGeneralSetting: UserSetting_GeneralSetting = {
  locale: "en",
  memoVisibility: "PRIVATE",
  theme: "",
};

const defaultUserWebhooksSetting: UserSetting_WebhooksSetting = {
  webhooks: [],
};

const buildUserSettings = (parent: string): UserSetting[] => {
  return [
    {
      name: `${parent}/settings/GENERAL`,
      value: { case: "generalSetting", value: defaultUserGeneralSetting },
    },
    {
      name: `${parent}/settings/WEBHOOKS`,
      value: { case: "webhooksSetting", value: defaultUserWebhooksSetting },
    },
  ];
};

export const userServiceClient = {
  async listUsers(_request?: unknown): Promise<{ users: User[]; nextPageToken: string; totalSize: number }> {
    void _request;
    const data = await fetchJson<ApiUser[]>("/users", { method: "GET" });
    const users = Array.isArray(data) ? data.map(userFromApi) : [];
    return { users, nextPageToken: "", totalSize: users.length };
  },
  async getUser(request: { name: string }): Promise<User> {
    const userId = parseResourceId(request.name);
    const data = await fetchJson<ApiUser>(`/users/${userId}`, { method: "GET" });
    return userFromApi(data);
  },
  async createUser(request: { user?: User }): Promise<User> {
    const user = request.user;
    if (!user) {
      throw new Error("Missing user payload");
    }
    const email = user.email || (user.username ? `${user.username}@example.com` : undefined);
    const payload = {
      email,
      password: user.password || "",
    };
    const data = await fetchJson<ApiUser>("/users", { method: "POST", body: payload });
    return userFromApi(data);
  },
  async updateUser(request: { user?: User }): Promise<User> {
    const user = request.user;
    if (!user?.name) {
      throw new Error("Missing user name");
    }
    const userId = parseResourceId(user.name);
    const payload = {
      email: user.email,
      nickname: user.displayName,
    };
    const data = await fetchJson<ApiUser>(`/users/${userId}`, { method: "PATCH", body: payload });
    return userFromApi(data);
  },
  async deleteUser(_request?: { name: string }): Promise<void> {
    void _request;
    return;
  },
  async getUserStats(request: { name: string }): Promise<UserStats> {
    return {
      name: request.name,
      memoDisplayTimestamps: [],
      memoTypeStats: {
        linkCount: 0,
        codeCount: 0,
        todoCount: 0,
        undoCount: 0,
      },
      tagCount: {},
      pinnedMemos: [],
      totalMemoCount: 0,
    };
  },
  async listAllUserStats(_request?: unknown): Promise<{ stats: UserStats[] }> {
    void _request;
    return { stats: [] };
  },
  async listUserSettings(request: { parent: string }): Promise<{ settings: UserSetting[]; nextPageToken: string; totalSize: number }> {
    const settings = buildUserSettings(request.parent);
    return { settings, nextPageToken: "", totalSize: settings.length };
  },
  async updateUserSetting(request: { setting?: UserSetting }): Promise<UserSetting> {
    if (request.setting) {
      return request.setting;
    }
    return buildUserSettings("users/1")[0];
  },
  async listUserNotifications(_request: { parent: string }): Promise<{ notifications: UserNotification[]; nextPageToken: string }> {
    void _request;
    return { notifications: [], nextPageToken: "" };
  },
  async updateUserNotification(request: { notification?: UserNotification }): Promise<UserNotification> {
    if (request.notification) {
      return request.notification;
    }
    return {
      name: "users/1/notifications/1",
      sender: "users/1",
      status: 1,
      type: 0,
    };
  },
  async deleteUserNotification(_request: { name: string }): Promise<void> {
    void _request;
    return;
  },
  async listPersonalAccessTokens(_request: { parent: string }): Promise<{
    personalAccessTokens: PersonalAccessToken[];
    nextPageToken: string;
    totalSize: number;
  }> {
    void _request;
    return { personalAccessTokens: [], nextPageToken: "", totalSize: 0 };
  },
  async createPersonalAccessToken(request: {
    parent?: string;
    description?: string;
    expiresInDays?: number;
  }): Promise<CreatePersonalAccessTokenResponse> {
    const parent = request.parent || "users/1";
    const tokenId = Date.now().toString();
    const personalAccessToken: PersonalAccessToken = {
      name: `${parent}/personalAccessTokens/${tokenId}`,
      description: request.description || "",
    };
    return {
      personalAccessToken,
      token: "stub-token",
    };
  },
  async deletePersonalAccessToken(_request: { name: string }): Promise<void> {
    void _request;
    return;
  },
  async listUserWebhooks(_request: { parent: string }): Promise<{ webhooks: UserWebhook[] }> {
    void _request;
    return { webhooks: [] };
  },
  async createUserWebhook(request: { parent?: string; webhook?: UserWebhook }): Promise<UserWebhook> {
    const parent = request.parent || "users/1";
    const webhook = request.webhook;
    if (webhook?.name) {
      return webhook;
    }
    return {
      name: `${parent}/webhooks/${Date.now()}`,
      url: webhook?.url || "",
      displayName: webhook?.displayName || "",
    };
  },
  async updateUserWebhook(request: { webhook?: UserWebhook }): Promise<UserWebhook> {
    if (request.webhook) {
      return request.webhook;
    }
    return {
      name: "users/1/webhooks/1",
      url: "",
      displayName: "",
    };
  },
  async deleteUserWebhook(_request: { name: string }): Promise<void> {
    void _request;
    return;
  },
};

