import { clientFetch } from '@/lib/api/client';
import { unwrap, type ApiEnvelope } from '@/lib/api/types';
import { AUTH_API_BASE } from '../constants';
import type {
  AuthApi,
  AuthTokens,
  LogoutRequest,
  Me,
  OtpRequest,
  OtpVerify,
  RefreshRequest,
  RequestOtpResult,
  SelectRoleDto,
} from '../types';

/**
 * Real HTTP implementation of the AuthApi seam. `clientFetch` returns the raw server
 * envelope, so each call reads its payload via `unwrap`. Routes are the exact snake_case
 * paths from the published swagger (`[controller]/[action]` transform).
 */
export const authClientApi: AuthApi = {
  requestOtp: async (body: OtpRequest) =>
    unwrap(
      await clientFetch<ApiEnvelope<RequestOtpResult>>(`${AUTH_API_BASE}/auth/request_otp`, {
        method: 'POST',
        body: JSON.stringify(body),
      }),
    ),

  verifyOtp: async (body: OtpVerify) =>
    unwrap(
      await clientFetch<ApiEnvelope<AuthTokens>>(`${AUTH_API_BASE}/auth/verify_otp`, {
        method: 'POST',
        body: JSON.stringify(body),
      }),
    ),

  refresh: async (body: RefreshRequest) =>
    unwrap(
      await clientFetch<ApiEnvelope<AuthTokens>>(`${AUTH_API_BASE}/auth/refresh`, {
        method: 'POST',
        body: JSON.stringify(body),
      }),
    ),

  // Success is an empty envelope (no `data`) — don't unwrap, just await the revocation.
  logout: async (body?: LogoutRequest) => {
    await clientFetch<ApiEnvelope<void>>(`${AUTH_API_BASE}/auth/logout`, {
      method: 'POST',
      body: JSON.stringify(body ?? {}),
    });
  },

  getMe: async () => unwrap(await clientFetch<ApiEnvelope<Me>>(`${AUTH_API_BASE}/me`)),

  selectRole: async (body: SelectRoleDto) =>
    unwrap(
      await clientFetch<ApiEnvelope<Me>>(`${AUTH_API_BASE}/me/select_role`, {
        method: 'POST',
        body: JSON.stringify(body),
      }),
    ),
};
