/**
 * CRM Service API client — real backend only (Phase 6.0–6.3).
 * Browser → /api/crm BFF; SSR → direct upstream.
 */

import { getValidAccessToken, refreshSession } from "@/lib/auth";
import type {
  Attachment,
  AuditEntry,
  CallLog,
  Comment,
  Contact,
  CustomField,
  Forecast,
  Goal,
  HealthResponse,
  Lead,
  ListParams,
  LookupRead,
  Meeting,
  Mention,
  Note,
  Opportunity,
  Organization,
  Pipeline,
  PipelineStage,
  Playbook,
  Quote,
  SalesActivity,
  Tag,
  Target,
  Task,
  TeamMember,
  TimelineEvent,
} from "@/modules/crm/types";

const CRM_BASE =
  typeof window !== "undefined"
    ? "/api/crm"
    : process.env.CRM_SERVICE_URL ||
      process.env.NEXT_PUBLIC_CRM_API_URL ||
      "http://localhost:8003";

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

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);
  if (!headers.has("Content-Type") && init.body) {
    headers.set("Content-Type", "application/json");
  }
  headers.set("X-Tenant-ID", tenantId);
  if (auth) {
    const token = await getValidAccessToken();
    if (token) headers.set("Authorization", `Bearer ${token}`);
  }

  const url = path.startsWith("http")
    ? path
    : `${CRM_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(`اتصال به سرویس CRM برقرار نشد (${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 CrmApiError(
      res.status,
      body?.error?.code || body?.detail || "unknown_error",
      body?.error?.message || body?.detail || res.statusText
    );
  }
  if (res.status === 204) return undefined as T;
  return res.json() as Promise<T>;
}

function qs(params?: ListParams) {
  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}` : "";
}

function apiPath(segment: string) {
  return `/api/v1${segment.startsWith("/") ? segment : `/${segment}`}`;
}

export const crmApi = {
  health: () =>
    request<HealthResponse>("/health", {
      tenantId: "00000000-0000-0000-0000-000000000000",
      auth: false,
    }),

  leads: {
    list: (tenantId: string, params?: ListParams) =>
      request<Lead[]>(`${apiPath("/leads")}${qs(params)}`, { tenantId }),
    get: (tenantId: string, id: string) =>
      request<Lead>(apiPath(`/leads/${id}`), { tenantId }),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<Lead>(apiPath("/leads"), { tenantId, method: "POST", body: JSON.stringify(body) }),
    update: (tenantId: string, id: string, body: Record<string, unknown>) =>
      request<Lead>(apiPath(`/leads/${id}`), {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    assign: (tenantId: string, id: string, body: { assigned_user_id: string; note?: string }) =>
      request<Lead>(apiPath(`/leads/${id}/assign`), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    delete: (tenantId: string, id: string) =>
      request<Lead>(apiPath(`/leads/${id}/delete`), { tenantId, method: "POST" }),
    restore: (tenantId: string, id: string) =>
      request<Lead>(apiPath(`/leads/${id}/restore`), { tenantId, method: "POST" }),
  },

  contacts: {
    list: (tenantId: string, params?: ListParams) =>
      request<Contact[]>(`${apiPath("/contacts")}${qs(params)}`, { tenantId }),
    get: (tenantId: string, id: string) =>
      request<Contact>(apiPath(`/contacts/${id}`), { tenantId }),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<Contact>(apiPath("/contacts"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (tenantId: string, id: string, body: Record<string, unknown>) =>
      request<Contact>(apiPath(`/contacts/${id}`), {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    delete: (tenantId: string, id: string) =>
      request<Contact>(apiPath(`/contacts/${id}/delete`), { tenantId, method: "POST" }),
  },

  organizations: {
    list: (tenantId: string, params?: ListParams) =>
      request<Organization[]>(`${apiPath("/organizations")}${qs(params)}`, { tenantId }),
    get: (tenantId: string, id: string) =>
      request<Organization>(apiPath(`/organizations/${id}`), { tenantId }),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<Organization>(apiPath("/organizations"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (tenantId: string, id: string, body: Record<string, unknown>) =>
      request<Organization>(apiPath(`/organizations/${id}`), {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    delete: (tenantId: string, id: string) =>
      request<Organization>(apiPath(`/organizations/${id}/delete`), {
        tenantId,
        method: "POST",
      }),
  },

  opportunities: {
    list: (tenantId: string, params?: ListParams) =>
      request<Opportunity[]>(`${apiPath("/opportunities")}${qs(params)}`, { tenantId }),
    get: (tenantId: string, id: string) =>
      request<Opportunity>(apiPath(`/opportunities/${id}`), { tenantId }),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<Opportunity>(apiPath("/opportunities"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (tenantId: string, id: string, body: Record<string, unknown>) =>
      request<Opportunity>(apiPath(`/opportunities/${id}`), {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    changeStage: (tenantId: string, id: string, body: { stage_id: string; note?: string }) =>
      request<Opportunity>(apiPath(`/opportunities/${id}/stage`), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    win: (tenantId: string, id: string, body?: Record<string, unknown>) =>
      request<Opportunity>(apiPath(`/opportunities/${id}/win`), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body ?? {}),
      }),
    lose: (tenantId: string, id: string, body: Record<string, unknown>) =>
      request<Opportunity>(apiPath(`/opportunities/${id}/lose`), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    stageHistory: (tenantId: string, id: string) =>
      request<Record<string, unknown>[]>(apiPath(`/opportunities/${id}/stage-history`), {
        tenantId,
      }),
  },

  pipelines: {
    list: (tenantId: string, params?: ListParams) =>
      request<Pipeline[]>(`${apiPath("/pipelines")}${qs(params)}`, { tenantId }),
    get: (tenantId: string, id: string) =>
      request<Pipeline>(apiPath(`/pipelines/${id}`), { tenantId }),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<Pipeline>(apiPath("/pipelines"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (tenantId: string, id: string, body: Record<string, unknown>) =>
      request<Pipeline>(apiPath(`/pipelines/${id}`), {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    stages: (tenantId: string, pipelineId: string, params?: ListParams) =>
      request<PipelineStage[]>(
        `${apiPath(`/pipelines/${pipelineId}/stages`)}${qs(params)}`,
        { tenantId }
      ),
    createStage: (tenantId: string, body: Record<string, unknown>) =>
      request<PipelineStage>(apiPath("/pipelines/stages"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    updateStage: (tenantId: string, stageId: string, body: Record<string, unknown>) =>
      request<PipelineStage>(apiPath(`/pipelines/stages/${stageId}`), {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    getStage: (tenantId: string, stageId: string) =>
      request<PipelineStage>(apiPath(`/pipelines/stages/${stageId}`), { tenantId }),
  },

  activities: {
    list: (tenantId: string, params?: ListParams) =>
      request<SalesActivity[]>(`${apiPath("/activities")}${qs(params)}`, { tenantId }),
    get: (tenantId: string, id: string) =>
      request<SalesActivity>(apiPath(`/activities/${id}`), { tenantId }),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<SalesActivity>(apiPath("/activities"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (tenantId: string, id: string, body: Record<string, unknown>) =>
      request<SalesActivity>(apiPath(`/activities/${id}`), {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
    complete: (tenantId: string, id: string) =>
      request<SalesActivity>(apiPath(`/activities/${id}/complete`), {
        tenantId,
        method: "POST",
      }),
  },

  quotes: {
    list: (tenantId: string, params?: ListParams) =>
      request<Quote[]>(`${apiPath("/quotes")}${qs(params)}`, { tenantId }),
    get: (tenantId: string, id: string) =>
      request<Quote>(apiPath(`/quotes/${id}`), { tenantId }),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<Quote>(apiPath("/quotes"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (tenantId: string, id: string, body: Record<string, unknown>) =>
      request<Quote>(apiPath(`/quotes/${id}`), {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
  },

  tags: {
    list: (tenantId: string, params?: ListParams) =>
      request<Tag[]>(`${apiPath("/tags")}${qs(params)}`, { tenantId }),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<Tag>(apiPath("/tags"), { tenantId, method: "POST", body: JSON.stringify(body) }),
    assignLead: (tenantId: string, leadId: string, tagId: string) =>
      request<Record<string, unknown>>(apiPath(`/tags/leads/${leadId}`), {
        tenantId,
        method: "POST",
        body: JSON.stringify({ tag_id: tagId }),
      }),
    assignContact: (tenantId: string, contactId: string, tagId: string) =>
      request<Record<string, unknown>>(apiPath(`/tags/contacts/${contactId}`), {
        tenantId,
        method: "POST",
        body: JSON.stringify({ tag_id: tagId }),
      }),
    assignOrganization: (tenantId: string, orgId: string, tagId: string) =>
      request<Record<string, unknown>>(apiPath(`/tags/organizations/${orgId}`), {
        tenantId,
        method: "POST",
        body: JSON.stringify({ tag_id: tagId }),
      }),
  },

  notes: {
    list: (tenantId: string, entityType: string, entityId: string) =>
      request<Note[]>(
        `${apiPath("/notes")}?entity_type=${entityType}&entity_id=${entityId}`,
        { tenantId }
      ),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<Note>(apiPath("/notes"), { tenantId, method: "POST", body: JSON.stringify(body) }),
    update: (tenantId: string, id: string, body: Record<string, unknown>) =>
      request<Note>(apiPath(`/notes/${id}`), {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
  },

  attachments: {
    list: (tenantId: string, entityType: string, entityId: string) =>
      request<Attachment[]>(
        `${apiPath("/attachments")}?entity_type=${entityType}&entity_id=${entityId}`,
        { tenantId }
      ),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<Attachment>(apiPath("/attachments"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  customFields: {
    list: (tenantId: string, entityType: string) =>
      request<CustomField[]>(`${apiPath("/custom-fields")}?entity_type=${entityType}`, {
        tenantId,
      }),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<CustomField>(apiPath("/custom-fields"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    upsertValue: (tenantId: string, body: Record<string, unknown>) =>
      request<Record<string, unknown>>(apiPath("/custom-fields/values"), {
        tenantId,
        method: "PUT",
        body: JSON.stringify(body),
      }),
  },

  audit: {
    list: (tenantId: string, entityType: string, entityId: string) =>
      request<AuditEntry[]>(
        `${apiPath("/audit")}?entity_type=${entityType}&entity_id=${entityId}`,
        { tenantId }
      ),
  },

  lookups: {
    leadSources: {
      list: (tenantId: string, params?: ListParams) =>
        request<LookupRead[]>(`${apiPath("/lookups/lead-sources")}${qs(params)}`, { tenantId }),
      create: (tenantId: string, body: Record<string, unknown>) =>
        request<LookupRead>(apiPath("/lookups/lead-sources"), {
          tenantId,
          method: "POST",
          body: JSON.stringify(body),
        }),
    },
    leadStatuses: {
      list: (tenantId: string, params?: ListParams) =>
        request<LookupRead[]>(`${apiPath("/lookups/lead-statuses")}${qs(params)}`, { tenantId }),
      create: (tenantId: string, body: Record<string, unknown>) =>
        request<LookupRead>(apiPath("/lookups/lead-statuses"), {
          tenantId,
          method: "POST",
          body: JSON.stringify(body),
        }),
    },
    contactTypes: {
      list: (tenantId: string, params?: ListParams) =>
        request<LookupRead[]>(`${apiPath("/lookups/contact-types")}${qs(params)}`, { tenantId }),
      create: (tenantId: string, body: Record<string, unknown>) =>
        request<LookupRead>(apiPath("/lookups/contact-types"), {
          tenantId,
          method: "POST",
          body: JSON.stringify(body),
        }),
    },
    organizationTypes: {
      list: (tenantId: string, params?: ListParams) =>
        request<LookupRead[]>(
          `${apiPath("/lookups/organization-types")}${qs(params)}`,
          { tenantId }
        ),
      create: (tenantId: string, body: Record<string, unknown>) =>
        request<LookupRead>(apiPath("/lookups/organization-types"), {
          tenantId,
          method: "POST",
          body: JSON.stringify(body),
        }),
    },
    organizationIndustries: {
      list: (tenantId: string, params?: ListParams) =>
        request<LookupRead[]>(
          `${apiPath("/lookups/organization-industries")}${qs(params)}`,
          { tenantId }
        ),
      create: (tenantId: string, body: Record<string, unknown>) =>
        request<LookupRead>(apiPath("/lookups/organization-industries"), {
          tenantId,
          method: "POST",
          body: JSON.stringify(body),
        }),
    },
  },

  tasks: {
    list: (tenantId: string, params?: ListParams) =>
      request<Task[]>(`${apiPath("/tasks")}${qs(params)}`, { tenantId }),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<Task>(apiPath("/tasks"), { tenantId, method: "POST", body: JSON.stringify(body) }),
    complete: (tenantId: string, id: string) =>
      request<Task>(apiPath(`/tasks/${id}/complete`), { tenantId, method: "POST" }),
    createChecklistItem: (tenantId: string, body: Record<string, unknown>) =>
      request<Record<string, unknown>>(apiPath("/tasks/checklist"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    completeChecklistItem: (tenantId: string, itemId: string) =>
      request<Record<string, unknown>>(apiPath(`/tasks/checklist/${itemId}/complete`), {
        tenantId,
        method: "POST",
      }),
  },

  meetings: {
    list: (tenantId: string, params?: ListParams) =>
      request<Meeting[]>(`${apiPath("/meetings")}${qs(params)}`, { tenantId }),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<Meeting>(apiPath("/meetings"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    finish: (tenantId: string, id: string, body?: Record<string, unknown>) =>
      request<Meeting>(apiPath(`/meetings/${id}/finish`), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body ?? {}),
      }),
    addAttendee: (tenantId: string, body: Record<string, unknown>) =>
      request<Record<string, unknown>>(apiPath("/meetings/attendees"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  calls: {
    list: (tenantId: string, params?: ListParams) =>
      request<CallLog[]>(`${apiPath("/calls")}${qs(params)}`, { tenantId }),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<CallLog>(apiPath("/calls"), { tenantId, method: "POST", body: JSON.stringify(body) }),
  },

  emails: {
    createThread: (tenantId: string, body: Record<string, unknown>) =>
      request<Record<string, unknown>>(apiPath("/email-threads"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    createMessage: (tenantId: string, body: Record<string, unknown>) =>
      request<Record<string, unknown>>(apiPath("/emails"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  timeline: {
    list: (tenantId: string, params?: ListParams) =>
      request<TimelineEvent[]>(`${apiPath("/timeline")}${qs(params)}`, { tenantId }),
    forOpportunity: (tenantId: string, opportunityId: string) =>
      request<TimelineEvent[]>(apiPath(`/timeline/opportunities/${opportunityId}`), { tenantId }),
  },

  comments: {
    list: (tenantId: string, entityType: string, entityId: string) =>
      request<Comment[]>(
        `${apiPath("/comments")}?entity_type=${entityType}&entity_id=${entityId}`,
        { tenantId }
      ),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<Comment>(apiPath("/comments"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    update: (tenantId: string, id: string, body: Record<string, unknown>) =>
      request<Comment>(apiPath(`/comments/${id}`), {
        tenantId,
        method: "PATCH",
        body: JSON.stringify(body),
      }),
  },

  mentions: {
    unread: (tenantId: string) =>
      request<Mention[]>(apiPath("/mentions/unread"), { tenantId }),
    markRead: (tenantId: string, id: string) =>
      request<Mention>(apiPath(`/mentions/${id}/read`), { tenantId, method: "POST" }),
  },

  team: {
    members: {
      list: (tenantId: string, params?: ListParams) =>
        request<TeamMember[]>(`${apiPath("/team-members")}${qs(params)}`, { tenantId }),
      create: (tenantId: string, body: Record<string, unknown>) =>
        request<TeamMember>(apiPath("/team-members"), {
          tenantId,
          method: "POST",
          body: JSON.stringify(body),
        }),
    },
    roles: {
      create: (tenantId: string, body: Record<string, unknown>) =>
        request<Record<string, unknown>>(apiPath("/team-roles"), {
          tenantId,
          method: "POST",
          body: JSON.stringify(body),
        }),
    },
    assignments: {
      create: (tenantId: string, body: Record<string, unknown>) =>
        request<Record<string, unknown>>(apiPath("/team-assignments"), {
          tenantId,
          method: "POST",
          body: JSON.stringify(body),
        }),
    },
  },

  bookmarks: {
    list: (tenantId: string, params?: ListParams) =>
      request<Record<string, unknown>[]>(`${apiPath("/bookmarks")}${qs(params)}`, { tenantId }),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<Record<string, unknown>>(apiPath("/bookmarks"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  favorites: {
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<Record<string, unknown>>(apiPath("/favorites"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  playbooks: {
    list: (tenantId: string, params?: ListParams) =>
      request<Playbook[]>(`${apiPath("/playbooks")}${qs(params)}`, { tenantId }),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<Playbook>(apiPath("/playbooks"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    steps: (tenantId: string, playbookId: string) =>
      request<Record<string, unknown>[]>(apiPath(`/playbooks/${playbookId}/steps`), { tenantId }),
    createStep: (tenantId: string, body: Record<string, unknown>) =>
      request<Record<string, unknown>>(apiPath("/playbooks/steps"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    assign: (tenantId: string, body: Record<string, unknown>) =>
      request<Record<string, unknown>>(apiPath("/playbooks/assignments"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
    completeStep: (tenantId: string, assignmentId: string, body: Record<string, unknown>) =>
      request<Record<string, unknown>>(
        apiPath(`/playbooks/assignments/${assignmentId}/complete-step`),
        { tenantId, method: "POST", body: JSON.stringify(body) }
      ),
  },

  forecasts: {
    list: (tenantId: string, params?: ListParams) =>
      request<Forecast[]>(`${apiPath("/forecasts")}${qs(params)}`, { tenantId }),
    compute: (tenantId: string, body: Record<string, unknown>) =>
      request<Forecast>(apiPath("/forecasts/compute"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  goals: {
    list: (tenantId: string, params?: ListParams) =>
      request<Goal[]>(`${apiPath("/goals")}${qs(params)}`, { tenantId }),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<Goal>(apiPath("/goals"), { tenantId, method: "POST", body: JSON.stringify(body) }),
  },

  targets: {
    list: (tenantId: string, params?: ListParams) =>
      request<Target[]>(`${apiPath("/targets")}${qs(params)}`, { tenantId }),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<Target>(apiPath("/targets"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  salesProcesses: {
    list: (tenantId: string, params?: ListParams) =>
      request<Record<string, unknown>[]>(`${apiPath("/sales-processes")}${qs(params)}`, {
        tenantId,
      }),
    create: (tenantId: string, body: Record<string, unknown>) =>
      request<Record<string, unknown>>(apiPath("/sales-processes"), {
        tenantId,
        method: "POST",
        body: JSON.stringify(body),
      }),
  },

  winLoss: {
    categories: {
      list: (tenantId: string, params?: ListParams) =>
        request<Record<string, unknown>[]>(
          `${apiPath("/win-loss/categories")}${qs(params)}`,
          { tenantId }
        ),
      create: (tenantId: string, body: Record<string, unknown>) =>
        request<Record<string, unknown>>(apiPath("/win-loss/categories"), {
          tenantId,
          method: "POST",
          body: JSON.stringify(body),
        }),
    },
    reasons: {
      list: (tenantId: string, params?: ListParams) =>
        request<Record<string, unknown>[]>(
          `${apiPath("/win-loss/reasons")}${qs(params)}`,
          { tenantId }
        ),
      create: (tenantId: string, body: Record<string, unknown>) =>
        request<Record<string, unknown>>(apiPath("/win-loss/reasons"), {
          tenantId,
          method: "POST",
          body: JSON.stringify(body),
        }),
    },
    forOpportunity: (tenantId: string, opportunityId: string) =>
      request<Record<string, unknown>>(
        apiPath(`/win-loss/opportunities/${opportunityId}`),
        { tenantId }
      ),
  },

  collaborationPreferences: {
    upsert: (tenantId: string, userId: string, body: Record<string, unknown>) =>
      request<Record<string, unknown>>(apiPath(`/collaboration-preferences/${userId}`), {
        tenantId,
        method: "PUT",
        body: JSON.stringify(body),
      }),
  },
};

/** Fetch all pages client-side (backend has no total count). */
export async function crmFetchAll<T>(
  fetchPage: (params: ListParams) => Promise<T[]>,
  pageSize = 500
): Promise<T[]> {
  const all: T[] = [];
  let page = 1;
  for (;;) {
    const batch = await fetchPage({ page, page_size: pageSize });
    all.push(...batch);
    if (batch.length < pageSize) break;
    page += 1;
    if (page > 50) break;
  }
  return all;
}
