import { HttpError } from "../../shared/api/errors";
import { httpClient, type RequestOptions } from "../../shared/api/httpClient";
import type { JsonResult } from "../../shared/api/types";
import {
  isPermissionDetail,
  isSavePermissionsRequest,
  type PermissionDetail,
  type SavePermissionsRequest,
} from "./permissionTypes";

interface PermissionHttpClient {
  get<T>(path: string, options?: RequestOptions): Promise<JsonResult<T>>;
  put<T>(
    path: string,
    body?: unknown,
    options?: RequestOptions,
  ): Promise<JsonResult<T>>;
}

export interface PermissionResult {
  data: PermissionDetail;
  requestId: string;
}

function assertId(id: unknown): asserts id is string {
  if (typeof id !== "string" || !/^[0-9]+$/.test(id)) {
    throw new TypeError("文档ID必须是十进制字符串");
  }
}

function parseDetail(
  result: JsonResult<unknown>,
  target: string,
): PermissionResult {
  if (!isPermissionDetail(result.data)) {
    throw new HttpError({
      httpStatus: result.httpStatus,
      code: "INTERNAL_ERROR",
      message: `${target}响应不符合DMS接口契约`,
      details: null,
      requestId: result.requestId,
    });
  }
  return { data: result.data, requestId: result.requestId };
}

export function createPermissionApi(client: PermissionHttpClient = httpClient) {
  return {
    async get(
      documentId: string,
      signal?: AbortSignal,
    ): Promise<PermissionResult> {
      assertId(documentId);
      const result = await client.get<unknown>(
        `documents/${documentId}/permissions`,
        { signal },
      );
      return parseDetail(result, "权限详情");
    },

    async save(
      documentId: string,
      request: SavePermissionsRequest,
      signal?: AbortSignal,
    ): Promise<PermissionResult> {
      assertId(documentId);
      if (!isSavePermissionsRequest(request)) {
        throw new TypeError("权限保存请求不符合DMS接口契约");
      }
      const result = await client.put<unknown>(
        `documents/${documentId}/permissions`,
        request,
        { signal },
      );
      return parseDetail(result, "权限保存");
    },
  };
}

export const permissionApi = createPermissionApi();
export type PermissionApi = ReturnType<typeof createPermissionApi>;

