import { HttpError } from "../../shared/api/errors";
import { httpClient, type RequestOptions } from "../../shared/api/httpClient";
import type { JsonResult, PageResult } from "../../shared/api/types";
import {
  isDocumentDetail,
  isDocumentSummary,
  isMainPlanBriefResult,
  isPageResult,
  type DocumentDetail,
  type DocumentSummary,
  type MainPlanBrief,
} from "../documents/documentTypes";
import {
  isAttachmentBindingSummary,
  type AttachmentBindingSummary,
  type AttachmentListQuery,
  type MountedAttachmentQuery,
} from "./attachmentTypes";

interface AttachmentHttpClient {
  get<T>(path: string, options?: RequestOptions): Promise<JsonResult<T>>;
}

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

export function createAttachmentApi(client: AttachmentHttpClient = httpClient) {
  return {
    async list(
      query: AttachmentListQuery,
      signal?: AbortSignal,
    ): Promise<PageResult<DocumentSummary>> {
      const result = await client.get<unknown>("attachments", {
        query: { ...query },
        signal,
      });
      if (!isPageResult(result.data, isDocumentSummary)) {
        throw contractError(result, "共享附件列表");
      }
      return result.data;
    },

    async detail(id: string, signal?: AbortSignal): Promise<DocumentDetail> {
      const result = await client.get<unknown>(`attachments/${id}`, { signal });
      if (!isDocumentDetail(result.data)) {
        throw contractError(result, "共享附件详情");
      }
      return result.data;
    },

    async mainPlans(id: string, signal?: AbortSignal): Promise<MainPlanBrief[]> {
      const result = await client.get<unknown>(
        `attachments/${id}/main-plans`,
        { signal },
      );
      if (!isMainPlanBriefResult(result.data)) {
        throw contractError(result, "附件反向挂载主案列表");
      }
      return result.data.items;
    },

    async mountedByMainPlan(
      mainPlanId: string,
      query: MountedAttachmentQuery,
      signal?: AbortSignal,
    ): Promise<PageResult<AttachmentBindingSummary>> {
      const result = await client.get<unknown>(
        `main-plans/${mainPlanId}/attachments`,
        { query: { ...query }, signal },
      );
      if (!isPageResult(result.data, isAttachmentBindingSummary)) {
        throw contractError(result, "主案已挂载附件列表");
      }
      return result.data;
    },
  };
}

export const attachmentApi = createAttachmentApi();
export type AttachmentApi = ReturnType<typeof createAttachmentApi>;
