import type {
  ApiResponse,
  PaginatedResponse,
  CreateItemPayload,
  UpdateItemPayload,
  ItemDetailData,
  ItemSummaryData,
  components,
} from '@alqove/types';
import type { AlqoveClient } from '../client';

export type ItemBrowseResponse = components['schemas']['ItemBrowseResponse'];

export interface ItemSearchQueryInput {
  q?: string;
  category_slug?: string;
  brand?: string[];
  size?: string[];
  condition?: string[];
  colors?: string[];
  store_id?: string[];
  min_price?: number;
  max_price?: number;
  sort?: string;
  page?: number;
  per_page?: number;
}

function serializeBrowseParams(
  input: ItemSearchQueryInput
): Record<string, string | string[]> {
  const params: Record<string, string | string[]> = {};

  if (input.q) params.q = input.q;
  if (input.category_slug) params.category_slug = input.category_slug;
  if (input.brand?.length) params.brand = input.brand;
  if (input.size?.length) params.size = input.size;
  if (input.condition?.length) params.condition = input.condition;
  if (input.colors?.length) params.colors = input.colors;
  if (input.store_id?.length) params.store_id = input.store_id;
  if (input.min_price !== undefined) params.min_price = String(input.min_price);
  if (input.max_price !== undefined) params.max_price = String(input.max_price);
  if (input.sort) params.sort = input.sort;
  if (input.page !== undefined) params.page = String(input.page);
  if (input.per_page !== undefined) params.per_page = String(input.per_page);

  return params;
}

export function createItemEndpoints(client: AlqoveClient) {
  return {
    // Public endpoints
    // /v1/items returns { data: ItemSummary[], meta, facets } at the top level
    // (no extra {data: ...} wrapper).
    browse(params?: ItemSearchQueryInput) {
      return client.get<ItemBrowseResponse>(
        '/v1/items',
        params ? serializeBrowseParams(params) : undefined
      );
    },

    getPublic(itemId: string) {
      return client.get<ApiResponse<ItemDetailData>>(`/v1/items/${itemId}`);
    },

    // Seller endpoints (store-scoped)
    list(storeId: string, params?: Record<string, string>) {
      return client.get<PaginatedResponse<ItemSummaryData>>(
        `/v1/stores/${storeId}/items`,
        params
      );
    },

    get(storeId: string, itemId: string) {
      return client.get<ApiResponse<ItemDetailData>>(
        `/v1/stores/${storeId}/items/${itemId}`
      );
    },

    create(storeId: string, payload: CreateItemPayload) {
      return client.post<ApiResponse<ItemDetailData>>(
        `/v1/stores/${storeId}/items`,
        payload
      );
    },

    update(storeId: string, itemId: string, payload: UpdateItemPayload) {
      return client.put<ApiResponse<ItemDetailData>>(
        `/v1/stores/${storeId}/items/${itemId}`,
        payload
      );
    },

    delete(storeId: string, itemId: string) {
      return client.delete<{ message: string }>(
        `/v1/stores/${storeId}/items/${itemId}`
      );
    },

    // Image endpoints
    uploadImages(storeId: string, itemId: string, images: File[]) {
      const formData = new FormData();
      images.forEach((image) => formData.append('images[]', image));
      return client.postFormData<ApiResponse<ItemDetailData>>(
        `/v1/stores/${storeId}/items/${itemId}/images`,
        formData
      );
    },

    removeImage(storeId: string, itemId: string, mediaId: number) {
      return client.delete<{ message: string }>(
        `/v1/stores/${storeId}/items/${itemId}/images/${mediaId}`
      );
    },

    // Status endpoints
    publish(storeId: string, itemId: string) {
      return client.post<ApiResponse<ItemDetailData>>(
        `/v1/stores/${storeId}/items/${itemId}/publish`
      );
    },

    remove(storeId: string, itemId: string) {
      return client.post<ApiResponse<ItemDetailData>>(
        `/v1/stores/${storeId}/items/${itemId}/remove`
      );
    },

    relist(storeId: string, itemId: string) {
      return client.post<ApiResponse<ItemDetailData>>(
        `/v1/stores/${storeId}/items/${itemId}/relist`
      );
    },

    // Snap endpoint
    snapPublish(storeId: string, payload: CreateItemPayload, images: File[]) {
      const formData = new FormData();
      Object.entries(payload).forEach(([key, value]) => {
        if (value === null || value === undefined) return;
        if (Array.isArray(value)) {
          value.forEach((v) => formData.append(`${key}[]`, String(v)));
        } else if (typeof value === 'object') {
          Object.entries(value).forEach(([k, v]) =>
            formData.append(`${key}[${k}]`, String(v))
          );
        } else {
          formData.append(key, String(value));
        }
      });
      images.forEach((image) => formData.append('images[]', image));
      return client.postFormData<ApiResponse<ItemDetailData>>(
        `/v1/stores/${storeId}/snap/items`,
        formData
      );
    },
  };
}
