import { endpoint, unwrap } from "@/utils/endpoint";
import { client } from "@/utils/api";

import type {
  CreateFileUploadFieldDto,
  CreateFileUploadSettingDto,
  FileUploadField,
  FileUploadSetting,
  UpdateFileUploadFieldDto,
  UpdateFileUploadSettingDto,
} from "@/types/fileUploadSettings";
import { URL_CONSTANTS } from "@/constants/URLS";
import { QUERY_KEYS } from "@/constants/TANSTACK_QUEY_KEY";
import { ApiResponse } from "@/types/apiResponse";

const BASE = "/api/file-upload-settings";

// function unwrap<T>(payload: Envelope<T>): T {
//   if (
//     payload &&
//     typeof payload === "object" &&
//     "data" in (payload as object)
//   ) {
//     return (payload as { data: T }).data;
//   }

//   return payload as T;
// }

export const fileUploadSettingsService = {
  // GET /file-upload-settings
  list: async (): Promise<FileUploadSetting[]> => {
    const response = await client.get<ApiResponse<FileUploadSetting[]>>(BASE);
    return unwrap(response.data);
  },

  // GET /file-upload-settings/:id
  getById: async (id: string): Promise<FileUploadSetting> => {
    const response = await client.get<ApiResponse<FileUploadSetting>>(
      `${BASE}/${id}`,
    );

    return unwrap(response.data);
  },

  // GET /file-upload-settings/by-entity/:entity
  getByEntity: async (entity: string): Promise<FileUploadSetting[]> => {
    const response = await client.get<ApiResponse<FileUploadSetting[]>>(
      `${BASE}/by-entity/${encodeURIComponent(entity)}`,
    );
    return unwrap(response.data);
  },

  // GET /file-upload-settings/by-code/:code
  getByCode: async (code: string): Promise<FileUploadSetting> => {
    const response = await client.get<ApiResponse<FileUploadSetting>>(
      `${BASE}/by-code/${encodeURIComponent(code)}`,
    );

    return unwrap(response.data);
  },

  // POST /file-upload-settings
  create: async (
    payload: CreateFileUploadSettingDto,
  ): Promise<FileUploadSetting> => {
    const response = await client.post<ApiResponse<FileUploadSetting>>(
      BASE,
      payload,
    );

    return unwrap(response.data);
  },

  // PATCH /file-upload-settings/:id
  update: async (
    id: string,
    payload: UpdateFileUploadSettingDto,
  ): Promise<FileUploadSetting> => {
    const response = await client.patch<ApiResponse<FileUploadSetting>>(
      `${BASE}/${id}`,
      payload,
    );

    return unwrap(response.data);
  },

  // DELETE /file-upload-settings/:id
  remove: async (id: string): Promise<void> => {
    await client.delete(`${BASE}/${id}`);
  },

  // PUT /file-upload-settings/:id/fields
  replaceFields: async (
    id: string,
    fields: CreateFileUploadFieldDto[],
  ): Promise<FileUploadField[]> => {
    const response = await client.put<ApiResponse<FileUploadField[]>>(
      `${BASE}/${id}/fields`,
      fields,
    );
    return unwrap(response.data);
  },

  // POST /file-upload-settings/:id/fields
  addField: async (
    id: string,
    payload: CreateFileUploadFieldDto,
  ): Promise<FileUploadField> => {
    const response = await client.post<ApiResponse<FileUploadField>>(
      `${BASE}/${id}/fields`,
      payload,
    );

    return unwrap(response.data);
  },

  // PATCH /file-upload-settings/fields/:fieldId
  updateField: async (
    fieldId: string,
    payload: UpdateFileUploadFieldDto,
  ): Promise<FileUploadField> => {
    const response = await client.patch<ApiResponse<FileUploadField>>(
      `${BASE}/fields/${fieldId}`,
      payload,
    );
    return unwrap(response.data);
  },

  // DELETE /file-upload-settings/fields/:fieldId
  removeField: async (fieldId: string): Promise<void> => {
    await client.delete(`${BASE}/fields/${fieldId}`);
  },
};

export const getFileUploadSettingByCode = endpoint<string, FileUploadSetting>(
  QUERY_KEYS.FILES.FILE_UPLOAD_SETTINGS,
  QUERY_KEYS.FILES.BY_CODE,
  (code) =>
    client
      .get<
        ApiResponse<FileUploadSetting>
      >(`${URL_CONSTANTS.FILES.FILE_UPLOAD_SETTINGS_BY_CODE}/${code}`)
      .then((res: any) => res.data.data),
);
