import type { UserBlockResponseDto } from '@/api/generated/models' import { createServiceError, errorResult, handleServiceError, type ServiceCallOptions, type ServiceResult, shouldBubbleErrorToParent, successResult, } from '@/services/errorHandler' import { unwrapApiData } from '@/services/apiResponse' import { getUserBlocks } from '@/api/generated/user-blocks/user-blocks' import { texts } from '@/texts' import { parseRemittanceList } from '@/helpers/listResponse' // docs/workflows/fa/user-blocking-reporting.md, Flow A — a directed block // record (`blocker_id` = current user, `blocked_id` = the other user). // Effect is mutual: once either side has a row against the other, new // *direct* messages between them are rejected in both directions. Event // group chats are never affected. export type UserBlock = UserBlockResponseDto const userBlocksApi = getUserBlocks() export const BLOCK_USER = async (blockedId: string, options?: ServiceCallOptions): Promise> => { try { const res = await userBlocksApi.userBlocksControllerCreate({ blockedId }) const payload = res.data if (!payload.success) { throw createServiceError(payload.message || texts.chats.blockUserFailed, payload.code) } const block = unwrapApiData(payload) if (!block?.id) { throw createServiceError(texts.common.invalidServerResponse) } return successResult(block) } catch (error) { const normalizedError = handleServiceError(error, options) if (shouldBubbleErrorToParent(options)) { throw normalizedError } return errorResult(normalizedError) } } export const UNBLOCK_USER = async (blockedId: string, options?: ServiceCallOptions): Promise> => { try { const res = await userBlocksApi.userBlocksControllerUnblock(blockedId) const payload = res.data if (!payload.success) { throw createServiceError(payload.message || texts.chats.unblockUserFailed, payload.code) } const block = unwrapApiData(payload) if (!block?.id) { throw createServiceError(texts.common.invalidServerResponse) } return successResult(block) } catch (error) { const normalizedError = handleServiceError(error, options) if (shouldBubbleErrorToParent(options)) { throw normalizedError } return errorResult(normalizedError) } } /** * Checks whether the current user has an active block row against * `otherUserId`. Used to toggle the header menu between «مسدود کردن» and * «رفع مسدودیت» — there's no dedicated "is blocked" endpoint, so this * reuses `GET /user-blocks/me?filters[blockedId]=...` (paginated, so a * single-row page is enough to answer a yes/no question). * * Note: this only reflects blocks *I* created (`blocker_id = me`), not * ones the other person may have created against me — matching the known * gap documented in user-blocking-reporting.md ("هیچ endpoint «چه کسی مرا * مسدود کرده» وجود ندارد"). */ export const GET_MY_BLOCK_STATUS = async ( otherUserId: string, options?: ServiceCallOptions ): Promise> => { try { const res = await userBlocksApi.userBlocksControllerListMine({ page: 1, pageSize: 1, 'filters[blockedId]': otherUserId }) const payload = res.data if (!payload.success) { throw createServiceError(payload.message || texts.chats.blockStatusFailed) } const parsed = parseRemittanceList(unwrapApiData(payload) ?? {}, 'items') return successResult({ isBlocked: parsed.items.length > 0 }) } catch (error) { const normalizedError = handleServiceError(error, options) if (shouldBubbleErrorToParent(options)) { throw normalizedError } return errorResult(normalizedError) } }