/**
 * Accounting Service API client — real backend only.
 * Base: NEXT_PUBLIC_ACCOUNTING_API_URL (default http://localhost:8002)
 * Always sends Authorization + X-Tenant-ID.
 */

import { getValidAccessToken, refreshSession } from "@/lib/auth";

const ACCOUNTING_BASE =
  typeof window !== "undefined"
    ? "/api/accounting"
    : process.env.ACCOUNTING_SERVICE_URL ||
      process.env.NEXT_PUBLIC_ACCOUNTING_API_URL ||
      "http://localhost:8002";

export class AccountingApiError extends Error {
  constructor(
    public status: number,
    public code: string,
    message: string
  ) {
    super(message);
    this.name = "AccountingApiError";
  }
}

type RequestOptions = RequestInit & { tenantId: string; auth?: boolean };

async function request<T>(path: string, options: RequestOptions): Promise<T> {
  const { tenantId, auth = true, headers: customHeaders, ...init } = options;
  const headers = new Headers(customHeaders);
  headers.set("Content-Type", "application/json");
  headers.set("X-Tenant-ID", tenantId);
  if (auth) {
    // Never fall back to a raw stored token that may already be expired.
    const token = await getValidAccessToken();
    if (token) headers.set("Authorization", `Bearer ${token}`);
  }

  const url = path.startsWith("http")
    ? path
    : `${ACCOUNTING_BASE.replace(/\/$/, "")}${path.startsWith("/") ? path : `/${path}`}`;

  let res: Response;
  try {
    res = await fetch(url, { ...init, headers });
  } catch (err) {
    const detail = err instanceof Error ? err.message : "network_error";
    throw new Error(
      `اتصال به سرویس حسابداری برقرار نشد (${url}) — ${detail}`
    );
  }

  if (res.status === 401 && auth) {
    const refreshed = await refreshSession({ force: true });
    if (refreshed) {
      headers.set("Authorization", `Bearer ${refreshed}`);
      res = await fetch(url, { ...init, headers });
    }
  }

  if (!res.ok) {
    const body = await res.json().catch(() => ({}));
    throw new AccountingApiError(
      res.status,
      body?.error?.code || "unknown_error",
      body?.error?.message || res.statusText
    );
  }
  if (res.status === 204) return undefined as T;
  return res.json() as Promise<T>;
}

export type ChartOfAccounts = {
  id: string;
  tenant_id: string;
  name: string;
  code: string;
  description: string | null;
  is_default: boolean;
  is_active: boolean;
  created_at: string;
};

export type Account = {
  id: string;
  tenant_id: string;
  chart_id: string;
  parent_id?: string | null;
  code: string;
  name: string;
  account_type: string;
  account_category: string;
  level: number;
  is_group: boolean;
  is_postable: boolean;
  status: string;
  description?: string | null;
  created_at: string;
};

export type Currency = {
  id: string;
  tenant_id: string;
  code: string;
  name: string;
  symbol: string | null;
  is_base: boolean;
  is_active: boolean;
};

export type FiscalYear = {
  id: string;
  tenant_id: string;
  name: string;
  start_date: string;
  end_date: string;
  is_current: boolean;
  is_closed: boolean;
};

export type FiscalPeriod = {
  id: string;
  tenant_id: string;
  fiscal_year_id: string;
  name: string;
  period_number: number;
  start_date: string;
  end_date: string;
  status: string;
  is_current: boolean;
};

export type CostCenter = {
  id: string;
  tenant_id: string;
  code: string;
  name: string;
  parent_id?: string | null;
  is_active: boolean;
};

export type Project = {
  id: string;
  tenant_id: string;
  code: string;
  name: string;
  start_date?: string | null;
  end_date?: string | null;
  is_active: boolean;
};

export type VoucherLine = {
  id: string;
  line_number: number;
  account_id: string;
  debit: string;
  credit: string;
  description: string | null;
  cost_center_id?: string | null;
  project_id?: string | null;
};

export type Voucher = {
  id: string;
  tenant_id: string;
  fiscal_period_id: string;
  voucher_number: string;
  voucher_date: string;
  status: string;
  description: string | null;
  total_debit: string;
  total_credit: string;
  posted_at: string | null;
  source_module?: string | null;
  reference_number?: string | null;
  lines: VoucherLine[];
};

export type LedgerBalance = {
  account_id: string;
  fiscal_period_id: string;
  opening_balance: string;
  debit_total: string;
  credit_total: string;
  closing_balance: string;
  current_balance: string;
};

export type SetupStatus = {
  has_chart: boolean;
  has_accounts: boolean;
  has_currency: boolean;
  has_base_currency: boolean;
  has_fiscal_year: boolean;
  has_fiscal_period: boolean;
  has_cash_box: boolean;
  has_customer: boolean;
  has_voucher: boolean;
  completed_steps: number;
  total_steps: number;
  percent: number;
};

export type CoaTemplate = {
  id: string;
  name: string;
  description: string;
  business_type: string;
  accounts: {
    code: string;
    name: string;
    account_type: string;
    account_category: string;
    level: number;
    is_group: boolean;
    is_postable: boolean;
    parent_code?: string | null;
  }[];
};

export type HealthResponse = {
  status: string;
  service: string;
  version: string;
};

function qs(params?: Record<string, string | number | undefined | null>) {
  if (!params) return "";
  const sp = new URLSearchParams();
  Object.entries(params).forEach(([k, v]) => {
    if (v !== undefined && v !== null && v !== "") sp.set(k, String(v));
  });
  const s = sp.toString();
  return s ? `?${s}` : "";
}

export const accountingApi = {
  health: () =>
    fetch(`${ACCOUNTING_BASE}/health`).then((r) => r.json() as Promise<HealthResponse>),

  setup: {
    status: (tenantId: string) =>
      request<SetupStatus>("/api/v1/setup/status", { tenantId }),
    peekNumber: (tenantId: string, documentType: string) =>
      request<{
        document_type: string;
        prefix: string;
        next_number: number;
        padding: number;
        preview: string;
      }>(`/api/v1/setup/sequences/next${qs({ document_type: documentType })}`, { tenantId }),
    allocateNumber: (tenantId: string, documentType: string) =>
      request<{ document_type: string; number: string }>("/api/v1/setup/sequences/allocate", {
        tenantId,
        method: "POST",
        body: JSON.stringify({ document_type: documentType }),
      }),
    getPostingPolicy: (tenantId: string) =>
      request<{
        auto_post: Record<string, boolean>;
        require_balanced: boolean;
        require_source_reference: boolean;
        lock_after_post: boolean;
        sequential_numbers: boolean;
        idempotent_source: boolean;
        posting_mode: string;
      }>("/api/v1/setup/posting-policy", { tenantId }),
    updatePostingPolicy: (
      tenantId: string,
      body: {
        auto_post?: Record<string, boolean>;
        require_balanced?: boolean;
        require_source_reference?: boolean;
        lock_after_post?: boolean;
        sequential_numbers?: boolean;
        idempotent_source?: boolean;
        posting_mode?: string;
      }
    ) =>
      request<{
        auto_post: Record<string, boolean>;
        require_balanced: boolean;
        require_source_reference: boolean;
        lock_after_post: boolean;
        sequential_numbers: boolean;
        idempotent_source: boolean;
        posting_mode: string;
      }>("/api/v1/setup/posting-policy", {
        tenantId,
        method: "PUT",
        body: JSON.stringify(body),
      }),
    getCompanyProfile: (tenantId: string) =>
      request<{
        legal_name: string;
        trade_name: string;
        national_id: string;
        economic_code: string;
        registration_number: string;
        postal_code: string;
        province: string;
        city: string;
        address: string;
        phone: string;
        mobile: string;
        email: string;
        website: string;
        ceo_name: string;
        accountant_name: string;
      }>("/api/v1/setup/company-profile", { tenantId }),
    updateCompanyProfile: (
      tenantId: string,
      body: Partial<{
        legal_name: string;
        trade_name: string;
        national_id: string;
        economic_code: string;
        registration_number: string;
        postal_code: string;
        province: string;
        city: string;
        address: string;
        phone: string;
        mobile: string;
        email: string;
        website: string;
        ceo_name: string;
        accountant_name: string;
      }>
    ) =>
      request<Record<string, string>>("/api/v1/setup/company-profile", {
        tenantId,
        method: "PUT",
        body: JSON.stringify(body),
      }),
  },

  charts: {
    list: (tenantId: string, page = 1, pageSize = 50) =>
      request<ChartOfAccounts[]>(`/api/v1/accounts/charts${qs({ page, page_size: pageSize })}`, {
        tenantId,
      }),
    get: (tenantId: string, id: string) =>
      request<ChartOfAccounts>(`/api/v1/accounts/charts/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: { name: string; code: string; description?: string; is_default?: boolean }
    ) =>
      request<ChartOfAccounts>("/api/v1/accounts/charts", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (
      tenantId: string,
      id: string,
      body: Partial<{ name: string; description: string; is_default: boolean; is_active: boolean }>
    ) =>
      request<ChartOfAccounts>(`/api/v1/accounts/charts/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    archive: (tenantId: string, id: string) =>
      request<ChartOfAccounts>(`/api/v1/accounts/charts/${id}/archive`, {
        tenantId,
        method: "POST",
      }),
  },

  templates: {
    list: (tenantId: string) =>
      request<CoaTemplate[]>("/api/v1/accounts/templates", { tenantId }),
    get: (tenantId: string, id: string) =>
      request<CoaTemplate>(`/api/v1/accounts/templates/${id}`, { tenantId }),
    import: (
      tenantId: string,
      templateId: string,
      body: { chart_id?: string; chart_name?: string; chart_code?: string }
    ) =>
      request<Account[]>(`/api/v1/accounts/templates/${templateId}/import`, {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  accounts: {
    list: (tenantId: string, page = 1, pageSize = 100, chartId?: string) =>
      request<Account[]>(
        `/api/v1/accounts${qs({ page, page_size: Math.min(pageSize, 500), chart_id: chartId })}`,
        { tenantId }
      ),
    get: (tenantId: string, id: string) =>
      request<Account>(`/api/v1/accounts/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        chart_id: string;
        code: string;
        name: string;
        account_type: string;
        account_category: string;
        level?: number;
        is_group?: boolean;
        is_postable?: boolean;
        parent_id?: string | null;
        description?: string;
      }
    ) =>
      request<Account>("/api/v1/accounts", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (
      tenantId: string,
      id: string,
      body: Partial<{
        name: string;
        account_type: string;
        account_category: string;
        level: number;
        is_group: boolean;
        is_postable: boolean;
        parent_id: string | null;
        description: string;
        status: string;
      }>
    ) =>
      request<Account>(`/api/v1/accounts/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    archive: (tenantId: string, id: string) =>
      request<Account>(`/api/v1/accounts/${id}/archive`, { tenantId, method: "POST" }),
  },

  currencies: {
    list: (tenantId: string) =>
      request<Currency[]>(`/api/v1/accounts/currencies${qs({ page_size: 100 })}`, { tenantId }),
    create: (
      tenantId: string,
      body: { code: string; name: string; symbol?: string; decimal_places?: number; is_base?: boolean }
    ) =>
      request<Currency>("/api/v1/accounts/currencies", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (
      tenantId: string,
      id: string,
      body: Partial<{ name: string; symbol: string; is_base: boolean; is_active: boolean }>
    ) =>
      request<Currency>(`/api/v1/accounts/currencies/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    setBase: (tenantId: string, id: string) =>
      request<Currency>(`/api/v1/accounts/currencies/${id}/set-base`, {
        tenantId,
        method: "POST",
      }),
    archive: (tenantId: string, id: string) =>
      request<Currency>(`/api/v1/accounts/currencies/${id}/archive`, {
        tenantId,
        method: "POST",
      }),
  },

  costCenters: {
    list: (tenantId: string) =>
      request<CostCenter[]>(`/api/v1/accounts/cost-centers${qs({ page_size: 100 })}`, { tenantId }),
    create: (tenantId: string, body: { code: string; name: string; parent_id?: string | null }) =>
      request<CostCenter>("/api/v1/accounts/cost-centers", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (
      tenantId: string,
      id: string,
      body: Partial<{ name: string; parent_id: string | null; is_active: boolean }>
    ) =>
      request<CostCenter>(`/api/v1/accounts/cost-centers/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    archive: (tenantId: string, id: string) =>
      request<CostCenter>(`/api/v1/accounts/cost-centers/${id}/archive`, {
        tenantId,
        method: "POST",
      }),
  },

  projects: {
    list: (tenantId: string) =>
      request<Project[]>(`/api/v1/accounts/projects${qs({ page_size: 100 })}`, { tenantId }),
    create: (
      tenantId: string,
      body: { code: string; name: string; start_date?: string; end_date?: string }
    ) =>
      request<Project>("/api/v1/accounts/projects", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (
      tenantId: string,
      id: string,
      body: Partial<{ name: string; start_date: string | null; end_date: string | null; is_active: boolean }>
    ) =>
      request<Project>(`/api/v1/accounts/projects/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    archive: (tenantId: string, id: string) =>
      request<Project>(`/api/v1/accounts/projects/${id}/archive`, {
        tenantId,
        method: "POST",
      }),
  },

  fiscal: {
    listYears: (tenantId: string) =>
      request<FiscalYear[]>("/api/v1/fiscal/years", { tenantId }),
    createYear: (
      tenantId: string,
      body: { name: string; start_date: string; end_date: string; is_current?: boolean }
    ) =>
      request<FiscalYear>("/api/v1/fiscal/years", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    updateYear: (
      tenantId: string,
      id: string,
      body: Partial<{ name: string; start_date: string; end_date: string; is_current: boolean }>
    ) =>
      request<FiscalYear>(`/api/v1/fiscal/years/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    setCurrentYear: (tenantId: string, id: string) =>
      request<FiscalYear>(`/api/v1/fiscal/years/${id}/set-current`, {
        tenantId,
        method: "POST",
      }),
    closeYear: (tenantId: string, id: string) =>
      request<FiscalYear>(`/api/v1/fiscal/years/${id}/close`, { tenantId, method: "POST" }),
    generatePeriods: (tenantId: string, id: string) =>
      request<FiscalPeriod[]>(`/api/v1/fiscal/years/${id}/generate-periods`, {
        tenantId,
        method: "POST",
      }),
    listPeriods: (tenantId: string) =>
      request<FiscalPeriod[]>("/api/v1/fiscal/periods", { tenantId }),
    createPeriod: (
      tenantId: string,
      body: {
        fiscal_year_id: string;
        name: string;
        period_number: number;
        start_date: string;
        end_date: string;
        is_current?: boolean;
      }
    ) =>
      request<FiscalPeriod>("/api/v1/fiscal/periods", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    updatePeriod: (
      tenantId: string,
      id: string,
      body: Partial<{ name: string; start_date: string; end_date: string; is_current: boolean; status: string }>
    ) =>
      request<FiscalPeriod>(`/api/v1/fiscal/periods/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    setCurrentPeriod: (tenantId: string, id: string) =>
      request<FiscalPeriod>(`/api/v1/fiscal/periods/${id}/set-current`, {
        tenantId,
        method: "POST",
      }),
    lockPeriod: (tenantId: string, id: string) =>
      request<FiscalPeriod>(`/api/v1/fiscal/periods/${id}/lock`, { tenantId, method: "POST" }),
    closePeriod: (tenantId: string, id: string) =>
      request<FiscalPeriod>(`/api/v1/fiscal/periods/${id}/close`, { tenantId, method: "POST" }),
    reopenPeriod: (tenantId: string, id: string) =>
      request<FiscalPeriod>(`/api/v1/fiscal/periods/${id}/reopen`, { tenantId, method: "POST" }),
  },

  vouchers: {
    list: (
      tenantId: string,
      page = 1,
      pageSize = 100,
      opts?: { status?: string; source?: string }
    ) =>
      request<Voucher[]>(
        `/api/v1/posting/vouchers${qs({
          page,
          page_size: pageSize,
          status: opts?.status || undefined,
          source: opts?.source || undefined,
        })}`,
        { tenantId }
      ),
    get: (tenantId: string, id: string) =>
      request<Voucher>(`/api/v1/posting/vouchers/${id}`, { tenantId }),
    create: (
      tenantId: string,
      body: {
        fiscal_period_id: string;
        voucher_number?: string;
        voucher_date: string;
        description?: string;
        reference_number?: string;
        source_module?: string;
        lines: {
          account_id: string;
          debit: string;
          credit: string;
          description?: string;
          cost_center_id?: string | null;
          project_id?: string | null;
        }[];
      }
    ) =>
      request<Voucher>("/api/v1/posting/vouchers", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (
      tenantId: string,
      id: string,
      body: {
        voucher_date?: string;
        description?: string;
        reference_number?: string;
        lines?: {
          account_id: string;
          debit: string;
          credit: string;
          description?: string;
          cost_center_id?: string | null;
          project_id?: string | null;
        }[];
      }
    ) =>
      request<Voucher>(`/api/v1/posting/vouchers/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    validate: (tenantId: string, id: string) =>
      request<Voucher>(`/api/v1/posting/vouchers/${id}/validate`, { tenantId, method: "POST" }),
    post: (tenantId: string, id: string, source_module?: string) =>
      request<Voucher>(`/api/v1/posting/vouchers/${id}/post`, {
        tenantId,
        method: "POST",
        body: JSON.stringify({ source_module }),
      }),
    reverse: (tenantId: string, id: string) =>
      request<Voucher>(`/api/v1/posting/vouchers/${id}/reverse`, {
        tenantId,
        method: "POST",
        body: JSON.stringify({}),
      }),
    reverseAndEdit: (tenantId: string, id: string) =>
      request<Voucher>(`/api/v1/posting/vouchers/${id}/reverse-and-edit`, {
        tenantId,
        method: "POST",
      }),
    cancel: (tenantId: string, id: string) =>
      request<Voucher>(`/api/v1/posting/vouchers/${id}/cancel`, { tenantId, method: "POST" }),
    auditLogs: (tenantId: string) =>
      request<
        {
          id: string;
          operation: string;
          actor_user_id: string;
          voucher_number: string | null;
          resource_type: string;
          resource_id: string;
          created_at: string;
        }[]
      >("/api/v1/posting/audit-logs", { tenantId }),
  },

  ledger: {
    balances: (tenantId: string, fiscalPeriodId: string) =>
      request<LedgerBalance[]>(
        `/api/v1/ledger/balances${qs({ fiscal_period_id: fiscalPeriodId })}`,
        { tenantId }
      ),
    trialBalance: (tenantId: string, fiscalPeriodId: string) =>
      request<{
        fiscal_period_id: string;
        total_debit: string;
        total_credit: string;
        difference: string;
        is_balanced: boolean;
      }>(`/api/v1/ledger/trial-balance${qs({ fiscal_period_id: fiscalPeriodId })}`, {
        tenantId,
        method: "POST",
      }),
    recalculate: (tenantId: string, fiscalPeriodId: string) =>
      request<{ recalculated_accounts: number }>(
        `/api/v1/ledger/recalculate${qs({ fiscal_period_id: fiscalPeriodId })}`,
        { tenantId, method: "POST" }
      ),
  },

  reporting: {
    trialBalance: (tenantId: string, fiscalPeriodId: string) =>
      request<{ id: string; report_type: string; data: unknown }>(
        `/api/v1/reporting/trial-balance${qs({ fiscal_period_id: fiscalPeriodId })}`,
        { tenantId, method: "POST" }
      ),
    balanceSheet: (tenantId: string, fiscalPeriodId: string) =>
      request<{ id: string; data: unknown }>(
        `/api/v1/reporting/balance-sheet${qs({ fiscal_period_id: fiscalPeriodId })}`,
        { tenantId, method: "POST" }
      ),
    incomeStatement: (tenantId: string, fiscalPeriodId: string) =>
      request<{ id: string; data: unknown }>(
        `/api/v1/reporting/income-statement${qs({ fiscal_period_id: fiscalPeriodId })}`,
        { tenantId, method: "POST" }
      ),
    subsidiaryLedger: (tenantId: string, fiscalPeriodId: string, accountId?: string) =>
      request<{ id: string; report_type: string; data: unknown }>(
        `/api/v1/reporting/subsidiary-ledger${qs({
          fiscal_period_id: fiscalPeriodId,
          account_id: accountId,
        })}`,
        { tenantId, method: "POST" }
      ),
    detailLedger: (tenantId: string, fiscalPeriodId: string, accountId?: string) =>
      request<{ id: string; report_type: string; data: unknown }>(
        `/api/v1/reporting/detail-ledger${qs({
          fiscal_period_id: fiscalPeriodId,
          account_id: accountId,
        })}`,
        { tenantId, method: "POST" }
      ),
    analytical: (tenantId: string, fiscalPeriodId: string) =>
      request<{ id: string; report_type: string; data: unknown }>(
        `/api/v1/reporting/analytical${qs({ fiscal_period_id: fiscalPeriodId })}`,
        { tenantId, method: "POST" }
      ),
    cashFlow: (tenantId: string, fiscalPeriodId: string) =>
      request<{ id: string; report_type: string; data: unknown }>(
        `/api/v1/reporting/cash-flow${qs({ fiscal_period_id: fiscalPeriodId })}`,
        { tenantId, method: "POST" }
      ),
    equityStatement: (tenantId: string, fiscalPeriodId: string) =>
      request<{ id: string; report_type: string; data: unknown }>(
        `/api/v1/reporting/equity-statement${qs({ fiscal_period_id: fiscalPeriodId })}`,
        { tenantId, method: "POST" }
      ),
    export: (tenantId: string, reportId: string, export_format: "json" | "csv" | "pdf" = "json") =>
      request<{ id: string; format: string; file_path: string | null }>(
        `/api/v1/reporting/reports/${reportId}/export`,
        { tenantId, method: "POST", body: JSON.stringify({ export_format }) }
      ),
  },

  treasury: {
    listCashBoxes: (tenantId: string) =>
      request<
        { id: string; tenant_id: string; code: string; name: string; current_balance: string; is_active: boolean }[]
      >("/api/v1/treasury/cash-boxes", { tenantId }),
    createCashBox: (
      tenantId: string,
      body: { code: string; name: string; opening_balance?: string }
    ) =>
      request<{ id: string }>("/api/v1/treasury/cash-boxes", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    updateCashBox: (tenantId: string, id: string, body: { name?: string; is_active?: boolean }) =>
      request<{ id: string }>(`/api/v1/treasury/cash-boxes/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    listBanks: (tenantId: string) =>
      request<{ id: string; code: string; name: string; is_active: boolean }[]>(
        "/api/v1/treasury/banks",
        { tenantId }
      ),
    createBank: (tenantId: string, body: { code: string; name: string }) =>
      request<{ id: string }>("/api/v1/treasury/banks", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    listBankAccounts: (tenantId: string) =>
      request<
        { id: string; bank_id: string; account_number: string; iban: string | null; is_active: boolean }[]
      >("/api/v1/treasury/bank-accounts", { tenantId }),
    createBankAccount: (
      tenantId: string,
      body: { bank_id: string; account_number: string; iban?: string }
    ) =>
      request<{ id: string }>("/api/v1/treasury/bank-accounts", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    cashReceipt: (
      tenantId: string,
      body: {
        cash_box_id: string;
        amount: string;
        debit_account_id: string;
        credit_account_id: string;
        description?: string;
        transaction_date?: string;
      }
    ) =>
      request<{ id: string; voucher_id: string }>("/api/v1/treasury/cash-receipts", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    listCheques: (tenantId: string) =>
      request<
        {
          id: string;
          cheque_number: string;
          amount: string;
          issue_date: string;
          due_date: string | null;
          status: string;
          is_incoming: boolean;
          payee: string | null;
        }[]
      >("/api/v1/treasury/cheques", { tenantId }),
    createCheque: (
      tenantId: string,
      body: {
        cheque_number: string;
        amount: string;
        issue_date: string;
        due_date?: string;
        is_incoming?: boolean;
        payee?: string;
        bank_account_id?: string;
        status?: string;
      }
    ) =>
      request<{ id: string; cheque_number: string }>("/api/v1/treasury/cheques", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    listTransfers: (tenantId: string) =>
      request<
        {
          id: string;
          transfer_date: string;
          amount: string;
          from_type: string;
          from_id: string;
          to_type: string;
          to_id: string;
          description: string | null;
          voucher_id?: string | null;
        }[]
      >("/api/v1/treasury/transfers", { tenantId }),
    createTransfer: (
      tenantId: string,
      body: {
        transfer_date: string;
        amount: string;
        from_type: string;
        from_id: string;
        to_type: string;
        to_id: string;
        description?: string;
      }
    ) =>
      request<{ id: string; voucher_id?: string | null; voucher_number?: string | null }>(
        "/api/v1/treasury/transfers",
        {
          tenantId,
          method: "POST",
          body: JSON.stringify(body),
        }
      ),
    listReceipts: (tenantId: string) =>
      request<
        {
          id: string;
          receipt_number: string;
          receipt_date: string;
          amount: string;
          payment_method: string;
          description: string | null;
          voucher_id?: string | null;
        }[]
      >("/api/v1/treasury/receipts", { tenantId }),
    createReceipt: (
      tenantId: string,
      body: {
        receipt_number: string;
        receipt_date: string;
        amount: string;
        payment_method?: string;
        cash_box_id?: string;
        bank_account_id?: string;
        counter_account_id?: string;
        description?: string;
      }
    ) =>
      request<{ id: string; receipt_number?: string; voucher_id?: string | null; voucher_number?: string | null }>(
        "/api/v1/treasury/receipts",
        {
          tenantId,
          method: "POST",
          body: JSON.stringify(body),
        }
      ),
    listPayments: (tenantId: string) =>
      request<
        {
          id: string;
          payment_number: string;
          payment_date: string;
          amount: string;
          payment_method: string;
          description: string | null;
          voucher_id?: string | null;
        }[]
      >("/api/v1/treasury/payments", { tenantId }),
    createPayment: (
      tenantId: string,
      body: {
        payment_number: string;
        payment_date: string;
        amount: string;
        payment_method?: string;
        cash_box_id?: string;
        bank_account_id?: string;
        counter_account_id?: string;
        description?: string;
      }
    ) =>
      request<{ id: string; payment_number?: string; voucher_id?: string | null; voucher_number?: string | null }>(
        "/api/v1/treasury/payments",
        {
          tenantId,
          method: "POST",
          body: JSON.stringify(body),
        }
      ),
    listReconciliations: (tenantId: string) =>
      request<
        {
          id: string;
          bank_account_id: string;
          statement_date: string;
          statement_balance: string;
          book_balance: string;
          difference: string;
          status: string;
        }[]
      >("/api/v1/treasury/reconciliations", { tenantId }),
    createReconciliation: (
      tenantId: string,
      body: {
        bank_account_id: string;
        statement_date: string;
        statement_balance: string;
        book_balance: string;
      }
    ) =>
      request<{ id: string; difference: string }>("/api/v1/treasury/reconciliations", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  ops: {
    listDocuments: (tenantId: string, module?: string, docType?: string) => {
      const q = new URLSearchParams();
      if (module) q.set("module", module);
      if (docType) q.set("doc_type", docType);
      const qs = q.toString();
      return request<
        {
          id: string;
          tenant_id: string;
          module: string;
          doc_type: string;
          number: string;
          doc_date: string;
          party_name: string | null;
          party_id?: string | null;
          amount: string;
          status: string;
          description: string | null;
          meta_json?: string | null;
        }[]
      >(`/api/v1/ops/documents${qs ? `?${qs}` : ""}`, { tenantId });
    },
    createDocument: (
      tenantId: string,
      body: {
        module: string;
        doc_type: string;
        number?: string;
        doc_date: string;
        party_name?: string;
        party_id?: string;
        amount?: string;
        status?: string;
        description?: string;
        meta_json?: string;
      }
    ) =>
      request<{ id: string }>("/api/v1/ops/documents", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    updateDocument: (
      tenantId: string,
      id: string,
      body: {
        party_name?: string;
        party_id?: string;
        amount?: string;
        status?: string;
        description?: string;
        doc_date?: string;
        meta_json?: string;
      }
    ) =>
      request<{ id: string; status: string }>(`/api/v1/ops/documents/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    confirmDocument: (tenantId: string, id: string) =>
      request<{ id: string; status: string; meta_json?: string | null }>(
        `/api/v1/ops/documents/${id}/confirm`,
        {
          tenantId,
          method: "POST",
          body: JSON.stringify({}),
        }
      ),
    listItems: (tenantId: string) =>
      request<
        {
          id: string;
          code: string;
          name: string;
          item_type: string;
          unit: string;
          quantity_on_hand: string;
          unit_cost: string;
          is_active: boolean;
        }[]
      >("/api/v1/ops/items", { tenantId }),
    createItem: (
      tenantId: string,
      body: {
        code: string;
        name: string;
        item_type?: string;
        unit?: string;
        quantity_on_hand?: string;
        unit_cost?: string;
      }
    ) =>
      request<{ id: string }>("/api/v1/ops/items", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    listWarehouses: (tenantId: string) =>
      request<{ id: string; code: string; name: string; is_active: boolean }[]>(
        "/api/v1/ops/warehouses",
        { tenantId }
      ),
    createWarehouse: (tenantId: string, body: { code: string; name: string }) =>
      request<{ id: string }>("/api/v1/ops/warehouses", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  customers: {
    list: (tenantId: string) =>
      request<
        { id: string; tenant_id: string; code: string; name: string; outstanding_balance: string; is_active: boolean }[]
      >("/api/v1/ar-ap/customers", { tenantId }),
    get: (tenantId: string, id: string) =>
      request<{
        id: string;
        code: string;
        name: string;
        outstanding_balance: string;
        is_active: boolean;
      }>(`/api/v1/ar-ap/customers/${id}`, { tenantId }),
    create: (tenantId: string, body: { code?: string; name: string; credit_limit?: string }) =>
      request<{ id: string; code: string; name: string }>("/api/v1/ar-ap/customers", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (
      tenantId: string,
      id: string,
      body: { name?: string; credit_limit?: string | null; is_active?: boolean }
    ) =>
      request<{ id: string }>(`/api/v1/ar-ap/customers/${id}`, {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    aging: (tenantId: string, id: string) =>
      request<{
        current: string;
        days_1_30: string;
        days_31_60: string;
        days_61_90: string;
        days_90_plus: string;
        total: string;
      }>(`/api/v1/ar-ap/customers/${id}/aging`, { tenantId }),
    listInvoices: (tenantId: string, customerId?: string) =>
      request<
        {
          id: string;
          customer_id: string;
          invoice_number: string;
          invoice_date: string;
          due_date: string | null;
          total_amount: string;
          remaining_amount: string;
          status: string;
        }[]
      >(`/api/v1/ar-ap/receivable-invoices${qs({ customer_id: customerId })}`, { tenantId }),
    createInvoice: (
      tenantId: string,
      body: {
        customer_id: string;
        invoice_number?: string;
        invoice_date: string;
        due_date?: string;
        total_amount: string;
      }
    ) =>
      request<{ id: string }>("/api/v1/ar-ap/receivable-invoices", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  suppliers: {
    list: (tenantId: string) =>
      request<
        { id: string; code: string; name: string; outstanding_balance: string; is_active: boolean }[]
      >("/api/v1/ar-ap/suppliers", { tenantId }),
    create: (tenantId: string, body: { code?: string; name: string }) =>
      request<{ id: string; code: string; name: string }>("/api/v1/ar-ap/suppliers", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  assets: {
    list: (tenantId: string) =>
      request<{ id: string; code: string; name: string; status: string }[]>("/api/v1/assets/assets", {
        tenantId,
      }),
    listCategories: (tenantId: string) =>
      request<{ id: string; code: string; name: string; default_useful_life_months: number }[]>(
        "/api/v1/assets/categories",
        { tenantId }
      ),
    createCategory: (
      tenantId: string,
      body: { code: string; name: string; default_useful_life_months?: number }
    ) =>
      request<{ id: string }>("/api/v1/assets/categories", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    create: (
      tenantId: string,
      body: {
        code: string;
        name: string;
        category_id?: string;
        acquisition_cost?: string;
        residual_value?: string;
      }
    ) =>
      request<{ id: string; code: string }>("/api/v1/assets/assets", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    activate: (tenantId: string, id: string) =>
      request<{ id: string; status: string }>(`/api/v1/assets/assets/${id}/activate`, {
        tenantId,
        method: "POST",
      }),
    depreciate: (
      tenantId: string,
      id: string,
      body: { expense_account_id: string; accumulated_account_id: string }
    ) =>
      request<{ id: string; amount: string; voucher_id: string }>(
        `/api/v1/assets/assets/${id}/depreciate`,
        { tenantId, method: "POST", body: JSON.stringify(body) }
      ),
    schedule: (tenantId: string, id: string) =>
      request<{ schedule: unknown[] }>(`/api/v1/assets/assets/${id}/depreciation-schedule`, {
        tenantId,
      }),
    listTransfers: (tenantId: string) =>
      request<
        {
          id: string;
          asset_id: string;
          transfer_date: string;
          from_location: string | null;
          to_location: string | null;
        }[]
      >("/api/v1/assets/transfers", { tenantId }),
    createTransfer: (
      tenantId: string,
      body: { asset_id: string; transfer_date: string; from_location?: string; to_location?: string }
    ) =>
      request<{ id: string }>("/api/v1/assets/transfers", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    listDisposals: (tenantId: string) =>
      request<
        {
          id: string;
          asset_id: string;
          disposal_date: string;
          disposal_type: string;
          sale_amount: string | null;
          gain_loss: string | null;
        }[]
      >("/api/v1/assets/disposals", { tenantId }),
    createDisposal: (
      tenantId: string,
      body: { asset_id: string; disposal_date: string; disposal_type?: string; sale_amount?: string }
    ) =>
      request<{ id: string }>("/api/v1/assets/disposals", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    listRevaluations: (tenantId: string) =>
      request<
        {
          id: string;
          asset_id: string;
          revaluation_date: string;
          old_book_value: string;
          new_book_value: string;
          difference: string;
        }[]
      >("/api/v1/assets/revaluations", { tenantId }),
    createRevaluation: (
      tenantId: string,
      body: {
        asset_id: string;
        revaluation_date: string;
        old_book_value: string;
        new_book_value: string;
      }
    ) =>
      request<{ id: string; difference: string }>("/api/v1/assets/revaluations", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  payroll: {
    listEmployees: (tenantId: string) =>
      request<{ id: string; code: string; name: string }[]>("/api/v1/payroll/employees", {
        tenantId,
      }),
    createEmployee: (
      tenantId: string,
      body: {
        employee_code: string;
        first_name: string;
        last_name: string;
        base_salary?: string;
        department_id?: string;
      }
    ) =>
      request<{ id: string; employee_code: string }>("/api/v1/payroll/employees", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    listDepartments: (tenantId: string) =>
      request<{ id: string; code: string; name: string }[]>("/api/v1/payroll/departments", {
        tenantId,
      }),
    createDepartment: (tenantId: string, body: { code: string; name: string }) =>
      request<{ id: string }>("/api/v1/payroll/departments", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    listPeriods: (tenantId: string) =>
      request<{ id: string; name: string; start_date: string; end_date: string; status: string }[]>(
        "/api/v1/payroll/periods",
        { tenantId }
      ),
    createPeriod: (
      tenantId: string,
      body: { name: string; start_date: string; end_date: string }
    ) =>
      request<{ id: string }>("/api/v1/payroll/periods", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    calculate: (tenantId: string, body: { payroll_period_id: string; employee_id: string }) =>
      request<{ id: string; gross_salary: string; net_salary: string; status: string }>(
        "/api/v1/payroll/calculate",
        { tenantId, method: "POST", body: JSON.stringify(body) }
      ),
    post: (tenantId: string, payrollId: string) =>
      request<{ id: string; status: string; voucher_id: string }>(
        `/api/v1/payroll/payrolls/${payrollId}/post`,
        { tenantId, method: "POST", body: JSON.stringify({}) }
      ),
    listContracts: (tenantId: string) =>
      request<
        {
          id: string;
          employee_id: string;
          contract_type: string;
          start_date: string;
          end_date: string | null;
          base_salary: string;
          is_active: boolean;
        }[]
      >("/api/v1/payroll/contracts", { tenantId }),
    createContract: (
      tenantId: string,
      body: {
        employee_id: string;
        contract_type?: string;
        start_date: string;
        end_date?: string;
        base_salary?: string;
      }
    ) =>
      request<{ id: string }>("/api/v1/payroll/contracts", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    listSalaryComponents: (tenantId: string) =>
      request<
        {
          id: string;
          code: string;
          name: string;
          component_type: string;
          is_taxable: boolean;
          is_active: boolean;
        }[]
      >("/api/v1/payroll/salary-components", { tenantId }),
    createSalaryComponent: (
      tenantId: string,
      body: { code: string; name: string; component_type?: string; is_taxable?: boolean }
    ) =>
      request<{ id: string }>("/api/v1/payroll/salary-components", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    listPayrolls: (tenantId: string) =>
      request<
        {
          id: string;
          payroll_period_id: string;
          employee_id: string;
          gross_salary: string;
          net_salary: string;
          status: string;
          voucher_id: string | null;
        }[]
      >("/api/v1/payroll/payrolls", { tenantId }),
  },

  compliance: {
    listAudit: (tenantId: string) =>
      request<
        { id: string; action: string; resource_type: string; actor_user_id: string; created_at: string }[]
      >("/api/v1/compliance/audit-records", { tenantId }),
    listPolicies: (tenantId: string) =>
      request<{ id: string; code: string; name: string; policy_type: string; is_active: boolean }[]>(
        "/api/v1/compliance/policies",
        { tenantId }
      ),
    createPolicy: (
      tenantId: string,
      body: { code: string; name: string; policy_type: string; rules_config: string; country_code?: string }
    ) =>
      request<{ id: string }>("/api/v1/compliance/policies", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    requestApproval: (
      tenantId: string,
      body: { workflow_id: string; resource_type: string; resource_id: string }
    ) =>
      request<{ id: string; status: string }>("/api/v1/compliance/approvals", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    approve: (tenantId: string, requestId: string) =>
      request<{ id: string; status: string }>(`/api/v1/compliance/approvals/${requestId}/approve`, {
        tenantId,
        method: "POST",
        body: JSON.stringify({}),
      }),
    reject: (tenantId: string, requestId: string, reason: string) =>
      request<{ id: string; status: string }>(`/api/v1/compliance/approvals/${requestId}/reject`, {
        tenantId,
        method: "POST",
        body: JSON.stringify({ reason }),
      }),
    listRisks: (tenantId: string) =>
      request<
        {
          id: string;
          code: string;
          title: string;
          risk_category: string;
          risk_level: string;
          risk_score: number;
          is_resolved: boolean;
        }[]
      >("/api/v1/compliance/risks", { tenantId }),
    createRisk: (
      tenantId: string,
      body: {
        code: string;
        title: string;
        risk_category: string;
        risk_level: string;
        risk_score?: number;
        description?: string;
      }
    ) =>
      request<{ id: string; risk_level: string }>("/api/v1/compliance/risks", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    listWorkflows: (tenantId: string) =>
      request<
        {
          id: string;
          name: string;
          resource_type: string;
          min_amount: string | null;
          max_amount: string | null;
          is_active: boolean;
        }[]
      >("/api/v1/compliance/workflows", { tenantId }),
    createWorkflow: (
      tenantId: string,
      body: { name: string; resource_type: string; min_amount?: string; max_amount?: string }
    ) =>
      request<{ id: string }>("/api/v1/compliance/workflows", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    listApprovals: (tenantId: string) =>
      request<
        {
          id: string;
          workflow_id: string;
          resource_type: string;
          resource_id: string;
          requested_by: string;
          status: string;
          current_step: number;
          rejection_reason: string | null;
        }[]
      >("/api/v1/compliance/approvals", { tenantId }),
    listGovernanceRules: (tenantId: string) =>
      request<
        {
          id: string;
          code: string;
          name: string;
          rule_type: string;
          condition_config: string;
          priority: number;
          is_active: boolean;
        }[]
      >("/api/v1/compliance/governance-rules", { tenantId }),
    createGovernanceRule: (
      tenantId: string,
      body: {
        code: string;
        name: string;
        rule_type?: string;
        condition_config: string;
        action_config?: string;
        priority?: number;
      }
    ) =>
      request<{ id: string }>("/api/v1/compliance/governance-rules", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    listControls: (tenantId: string) =>
      request<
        {
          id: string;
          code: string;
          name: string;
          control_type: string;
          description: string | null;
          is_active: boolean;
        }[]
      >("/api/v1/compliance/controls", { tenantId }),
    createControl: (
      tenantId: string,
      body: {
        code: string;
        name: string;
        control_type: string;
        description?: string;
        validation_config?: string;
      }
    ) =>
      request<{ id: string }>("/api/v1/compliance/controls", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    listViolations: (tenantId: string) =>
      request<
        {
          id: string;
          policy_id: string;
          resource_type: string;
          resource_id: string;
          severity: string;
          description: string;
          detected_at: string;
          is_resolved: boolean;
        }[]
      >("/api/v1/compliance/violations", { tenantId }),
    createViolation: (
      tenantId: string,
      body: {
        policy_id: string;
        resource_type: string;
        resource_id: string;
        severity: string;
        description: string;
      }
    ) =>
      request<{ id: string }>("/api/v1/compliance/violations", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  settlements: {
    list: (tenantId: string, partyType?: string) => {
      const q = partyType ? `?party_type=${encodeURIComponent(partyType)}` : "";
      return request<
        {
          id: string;
          settlement_number: string;
          settlement_date: string;
          settlement_type: string;
          party_type: string;
          party_id: string;
          total_amount: string;
          status: string;
        }[]
      >(`/api/v1/ar-ap/settlements${q}`, { tenantId });
    },
    create: (
      tenantId: string,
      body: {
        settlement_number: string;
        settlement_date: string;
        settlement_type: string;
        party_type: string;
        party_id: string;
        total_amount: string;
        allocations: { invoice_id?: string; amount: string }[];
      }
    ) =>
      request<{ id: string; status: string }>("/api/v1/ar-ap/settlements", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  salesAccounting: {
    listProfiles: (tenantId: string) =>
      request<{ id: string; name: string; document_type: string; is_default: boolean; is_active: boolean }[]>(
        "/api/v1/sales-accounting/posting-profiles",
        { tenantId }
      ),
    createProfile: (
      tenantId: string,
      body: {
        name: string;
        document_type: string;
        revenue_account_id?: string;
        receivable_account_id?: string;
        cash_account_id?: string;
        discount_account_id?: string;
        tax_account_id?: string;
        is_default?: boolean;
      }
    ) =>
      request<{ id: string }>("/api/v1/sales-accounting/posting-profiles", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    preview: (
      tenantId: string,
      body: {
        document_type?: string;
        total_amount: string;
        discount_amount?: string;
        tax_amount?: string;
        profile_id?: string;
      }
    ) =>
      request<{
        is_balanced: boolean;
        total_debit: string;
        total_credit: string;
        preview_data: unknown;
      }>("/api/v1/sales-accounting/preview", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    post: (
      tenantId: string,
      body: {
        document_type?: string;
        source_document_id: string;
        total_amount: string;
        discount_amount?: string;
        tax_amount?: string;
        profile_id?: string;
      }
    ) =>
      request<{ voucher_id: string; voucher_number: string; status: string }>(
        "/api/v1/sales-accounting/post",
        { tenantId, method: "POST", body: JSON.stringify(body) }
      ),
  },

  purchaseInventory: {
    listProfiles: (tenantId: string) =>
      request<
        {
          id: string;
          name: string;
          is_default: boolean;
          is_active: boolean;
          inventory_account_id?: string | null;
          grni_account_id?: string | null;
          liability_account_id?: string | null;
          expense_account_id?: string | null;
        }[]
      >("/api/v1/purchase-inventory/posting-profiles", { tenantId }),
    ensureDefaultProfile: (tenantId: string) =>
      request<{
        id: string;
        name: string;
        is_default: boolean;
        inventory_account_id?: string | null;
        liability_account_id?: string | null;
      }>("/api/v1/purchase-inventory/posting-profiles/ensure-default", {
        tenantId,
        method: "POST",
        body: JSON.stringify({}),
      }),
    createProfile: (
      tenantId: string,
      body: {
        name: string;
        inventory_account_id?: string;
        grni_account_id?: string;
        liability_account_id?: string;
        is_default?: boolean;
      }
    ) =>
      request<{ id: string; name: string }>("/api/v1/purchase-inventory/posting-profiles", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    previewGoodsReceipt: (
      tenantId: string,
      body: { source_document_id: string; amount: string; profile_id?: string }
    ) =>
      request<{ is_balanced: boolean; total_debit: string }>(
        "/api/v1/purchase-inventory/preview/goods-receipt",
        { tenantId, method: "POST", body: JSON.stringify(body) }
      ),
    postGoodsReceipt: (
      tenantId: string,
      body: {
        source_document_id: string;
        amount: string;
        profile_id?: string;
        credit_mode?: string;
        credit_account_id?: string;
        warehouse_name?: string;
        source_note?: string;
        party_name?: string;
      }
    ) =>
      request<{ voucher_id: string; voucher_number?: string; status: string }>(
        "/api/v1/purchase-inventory/post/goods-receipt",
        {
          tenantId,
          method: "POST",
          body: JSON.stringify(body),
        }
      ),
    previewPurchaseInvoice: (
      tenantId: string,
      body: { source_document_id: string; amount: string; profile_id?: string }
    ) =>
      request<{ is_balanced: boolean; total_debit: string; total_credit?: string }>(
        "/api/v1/purchase-inventory/preview/purchase-invoice",
        { tenantId, method: "POST", body: JSON.stringify(body) }
      ),
    postPurchaseInvoice: (
      tenantId: string,
      body: { source_document_id: string; amount: string; profile_id?: string }
    ) =>
      request<{ voucher_id: string; voucher_number?: string; status: string }>(
        "/api/v1/purchase-inventory/post/purchase-invoice",
        {
          tenantId,
          method: "POST",
          body: JSON.stringify(body),
        }
      ),
    postPurchaseReturn: (
      tenantId: string,
      body: {
        source_document_id: string;
        amount: string;
        profile_id?: string;
        source_invoice_id?: string;
        source_invoice_number?: string;
        party_id?: string;
        party_name?: string;
        lines_summary?: string;
      }
    ) =>
      request<{ voucher_id: string; voucher_number?: string; status: string }>(
        "/api/v1/purchase-inventory/post/purchase-return",
        {
          tenantId,
          method: "POST",
          body: JSON.stringify(body),
        }
      ),
    postInventoryIssue: (
      tenantId: string,
      body: {
        source_document_id: string;
        amount: string;
        reason: string;
        debit_account_id: string;
        credit_account_id?: string;
        profile_id?: string;
        barter_debit_account_id?: string;
        barter_amount?: string;
      }
    ) =>
      request<{ voucher_id: string; voucher_number?: string; status: string }>(
        "/api/v1/purchase-inventory/post/inventory-issue",
        {
          tenantId,
          method: "POST",
          body: JSON.stringify(body),
        }
      ),
    valuation: (
      tenantId: string,
      body: {
        item_id: string;
        quantity: string;
        unit_cost: string;
        method?: string;
        warehouse_id?: string;
      }
    ) =>
      request<{ id: string; total_value: string }>("/api/v1/purchase-inventory/valuation", {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },
};
