import { clientFetch } from '@/lib/api/client';
import { unwrap, type ApiEnvelope, type Paginated } from '@/lib/api/types';
import { CATEGORIES_PAGE_SIZE, MY_VARIANTS_PAGE_SIZE } from '../constants';
import type {
  CatalogApi,
  CreateVariantInput,
  NurseServiceVariant,
  ServiceCategory,
  ServiceOptionGroup,
  UpdateVariantInput,
} from '../types';

const CATALOG_BASE = '/api/v1/catalog';
const VARIANTS_BASE = '/api/v1/nurse_variants';

/**
 * Real HTTP implementation of the CatalogApi seam (b5 contract `dev/contracts/domains/catalog.md`).
 * Routes are action-style + snake_case; JSON bodies/fields are camelCase; ids for edit/toggle come
 * from the route, never the body. Mutations use POST. The duplicate-listing conflict surfaces as
 * `409` — `clientFetch` throws `ApiError(409)` (no toast; "other 4xx"), which the builder maps to
 * the inline duplicate warning. Selected once USE_CATALOG_MOCK is false.
 *
 * Pagination binds to the server's `PageSize` property (camelCase `pageSize`, case-insensitive), not
 * snake_case `page_size` — matching the proven b4 `serviceAreas` client. The domain query param
 * `category_id` is snake_case per the contract.
 */
export const catalogClientApi: CatalogApi = {
  listCategories: async (params) => {
    const query = new URLSearchParams();
    query.set('page', String(params?.page ?? 1));
    query.set('pageSize', String(params?.pageSize ?? CATEGORIES_PAGE_SIZE));
    return unwrap(
      await clientFetch<ApiEnvelope<Paginated<ServiceCategory>>>(`${CATALOG_BASE}/categories?${query.toString()}`),
    );
  },

  getCategoryOptionGroups: async (categoryId) =>
    unwrap(
      await clientFetch<ApiEnvelope<ServiceOptionGroup[]>>(`${CATALOG_BASE}/option_groups?category_id=${categoryId}`),
    ),

  listMyVariants: async (params) => {
    const query = new URLSearchParams();
    query.set('page', String(params?.page ?? 1));
    query.set('pageSize', String(params?.pageSize ?? MY_VARIANTS_PAGE_SIZE));
    return unwrap(
      await clientFetch<ApiEnvelope<Paginated<NurseServiceVariant>>>(`${VARIANTS_BASE}/list?${query.toString()}`),
    );
  },

  getVariant: async (id) =>
    unwrap(await clientFetch<ApiEnvelope<NurseServiceVariant>>(`${VARIANTS_BASE}/get/${id}`)),

  createVariant: async (input: CreateVariantInput) =>
    unwrap(
      await clientFetch<ApiEnvelope<NurseServiceVariant>>(`${VARIANTS_BASE}/create`, {
        method: 'POST',
        body: JSON.stringify(input),
      }),
    ),

  updateVariant: async (id, input: UpdateVariantInput) =>
    unwrap(
      await clientFetch<ApiEnvelope<NurseServiceVariant>>(`${VARIANTS_BASE}/update/${id}`, {
        method: 'POST',
        body: JSON.stringify(input),
      }),
    ),

  setVariantActive: async (id, isActive) => {
    await clientFetch<ApiEnvelope<boolean>>(`${VARIANTS_BASE}/set_active/${id}`, {
      method: 'POST',
      body: JSON.stringify({ isActive }),
    });
  },
};
