import { fetchClient } from '@ablogcms/fetch-client';
import { xhrUpload } from '@ablogcms/fetch-client/xhr-upload';
import type { MediaTransport, MediaListApiResponse, MediaDetailApiResponse } from '@ablogcms/media/types';

/**
 * `@ablogcms/media` はデータ取得をしない方針のため、CMS バックエンド固有の知識
 * （URL・クエリ・認証ヘッダ・POST ハンドラのフィールド名）はすべてこの実装に集約する。
 *
 * 各メソッドの URL・クエリ・HTTP メソッド・ボディは、移設前にパッケージ内で直接
 * 実行していたコードと完全に同一になるようにしている（`api/create-transport.test.ts` で
 * `ACMS.Library.acmsLink` / `fetchClient` / `$.ajax` / `xhrUpload` の呼び出し引数を検証）。
 */
export function createAcmsMediaTransport(): MediaTransport {
  return {
    async fetchMediaList(setting) {
      const url = ACMS.Library.acmsLink(
        {
          tpl: 'ajax/edit/media.json',
          bid: ACMS.Config.bid,
          page: setting.page,
          tag: setting.tag,
          keyword: setting.keyword,
          order: setting.order,
          limit: setting.limit,
          date: setting.date,
          Query: {
            type: setting.filetype,
            ext: setting.fileext,
            year: setting.year,
            month: setting.month,
            owner: setting.owner ? 'true' : 'false',
            blogAxis: setting.blogAxis ? 'true' : 'false',
            cache: new Date().getTime().toString(),
          },
        },
        false
      );
      const { data } = await fetchClient.get<MediaListApiResponse>(url);
      return data;
    },

    async fetchTagList() {
      const url = ACMS.Library.acmsLink(
        {
          bid: ACMS.Config.bid,
          tpl: 'ajax/edit/media-tag.json',
        },
        false
      );
      const { data } = await fetchClient.get<string[]>(url);
      return data;
    },

    async fetchMediaTags(tags) {
      const url = ACMS.Library.acmsLink(
        {
          tpl: 'ajax/edit/media-tag.json',
          bid: ACMS.Config.bid,
          Query: {
            cache: new Date().getTime().toString(),
          },
        },
        false
      );
      if (tags === undefined) {
        const { data } = await fetchClient.get<string[]>(url);
        return data;
      }
      const { data } = await fetchClient.get<string[]>(url, {
        params: { tags: tags.join(',') },
      });
      return data;
    },

    async fetchMediaDetail(mediaId) {
      const url = ACMS.Library.acmsLink(
        {
          tpl: 'ajax/edit/media-edit.json',
          bid: ACMS.Config.bid,
          Query: {
            cache: new Date().getTime().toString(),
          },
        },
        false
      );
      const { data } = await fetchClient.get<MediaDetailApiResponse>(url, {
        params: { _mid: mediaId },
      });
      return data;
    },

    async updateMedia(mediaId, formData) {
      const url = ACMS.Library.acmsLink({
        Query: {
          _mid: mediaId,
        },
      });
      return $.ajax({
        url,
        type: 'POST',
        data: formData,
        processData: false,
        contentType: false,
      });
    },

    async updateMediaAsNew(mediaId, formData) {
      const url = ACMS.Library.acmsLink({
        Query: {
          _mid: mediaId,
        },
      });
      return $.ajax({
        url,
        type: 'POST',
        data: formData,
        processData: false,
        contentType: false,
      });
    },

    async deleteMedia(formData) {
      return $.ajax({
        url: ACMS.Library.acmsLink({ bid: ACMS.Config.bid }),
        type: 'POST',
        data: formData,
        processData: false,
        contentType: false,
      });
    },

    async addTagsToMedia(formData) {
      return $.ajax({
        url: ACMS.Library.acmsLink({ bid: ACMS.Config.bid }),
        data: formData,
        type: 'POST',
        processData: false,
        contentType: false,
      });
    },

    async uploadMedia(formData, options) {
      return xhrUpload(location.href, formData, options);
    },
  };
}
