// lib/api/leads.api.ts
//
// Same shape as my-audits.api.ts — thin wrappers over fetchApi so the
// components never build URLs by hand.

import { fetchApi } from '@/lib/api/http';
import type {
  AssignLeadPayload,
  CreateLeadPayload,
  Lead,
  LeadAnalytics,
  LeadListParams,
  LeadListResponse,
  UpdateLeadPayload,
  DuplicateMatch,
  SelectableClientGroup,
} from '@/lib/api/types/leads.types';

const API_BASE_URL =
  process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3007/api';

// Generic rather than Record<string, unknown>: interfaces don't get an
// implicit index signature in TypeScript, so LeadListParams would be
// rejected here even though its shape is fine. `T extends object` accepts
// both interfaces and inline literals.
const qs = <T extends object>(params: T) => {
  const sp = new URLSearchParams();
  Object.entries(params).forEach(([k, v]) => {
    if (v !== undefined && v !== null && v !== '') sp.append(k, String(v));
  });
  const s = sp.toString();
  return s ? `?${s}` : '';
};

export const getLeads = (params: LeadListParams = {}) =>
  fetchApi<LeadListResponse>(`${API_BASE_URL}/leads${qs(params)}`);

export const getLead = (id: number) =>
  fetchApi<Lead>(`${API_BASE_URL}/leads/${id}`);

export const getLeadAnalytics = () =>
  fetchApi<LeadAnalytics>(`${API_BASE_URL}/leads/analytics`);

export const getClientGroupOptions = () =>
  fetchApi<{
    options: { value: SelectableClientGroup; label: string }[];
    legacy_rollup: Record<string, string>;
  }>(`${API_BASE_URL}/leads/client-groups`);

export const getLeadTags = () =>
  fetchApi<string[]>(`${API_BASE_URL}/leads/tags`);

export const createLead = (payload: CreateLeadPayload) =>
  fetchApi<Lead>(`${API_BASE_URL}/leads`, {
    method: 'POST',
    body: JSON.stringify(payload),
  });

export const updateLead = (id: number, payload: UpdateLeadPayload) =>
  fetchApi<Lead>(`${API_BASE_URL}/leads/${id}`, {
    method: 'PATCH',
    body: JSON.stringify(payload),
  });

/**
 * Ownership changes go here, never through updateLead — this is the call
 * that triggers the notification and the email on the backend.
 */
export const assignLead = (id: number, payload: AssignLeadPayload) =>
  fetchApi<{ message: string; changed: boolean; lead?: Lead }>(
    `${API_BASE_URL}/leads/${id}/assign`,
    { method: 'POST', body: JSON.stringify(payload) },
  );

export const deleteLead = (id: number) =>
  fetchApi<{ message: string; id: number }>(`${API_BASE_URL}/leads/${id}`, {
    method: 'DELETE',
  });

export const bulkUpdateLeads = (payload: {
  ids: number[];
  action: 'status' | 'reassign' | 'client_group';
  status?: string;
  lost_reason?: string;
  assigned_to?: number;
  client_group?: SelectableClientGroup;
  note?: string;
}) =>
  fetchApi<{ message: string; count: number }>(
    `${API_BASE_URL}/leads/bulk-update`,
    { method: 'POST', body: JSON.stringify(payload) },
  );

export const bulkDeleteLeads = (ids: number[]) =>
  fetchApi<{ message: string; count: number }>(
    `${API_BASE_URL}/leads/bulk-destroy`,
    { method: 'POST', body: JSON.stringify({ ids }) },
  );

export const checkLeadDuplicates = (params: {
  company?: string;
  contact?: string;
  phone?: string;
  email?: string;
  ignore_id?: number;
}) =>
  fetchApi<{ matches: DuplicateMatch[]; client_matches: unknown[] }>(
    `${API_BASE_URL}/leads/check-duplicates${qs(params)}`,
  );

export const requestLeadHandover = (
  id: number,
  payload: { reason: string; note?: string },
) =>
  fetchApi<{ message: string }>(
    `${API_BASE_URL}/leads/${id}/request-handover`,
    { method: 'POST', body: JSON.stringify(payload) },
  );

/** Users pickable as an assignee. Point this at your real users endpoint. */
export const getAssignableUsers = () =>
  fetchApi<any>(`${API_BASE_URL}/users?limit=200`);

/**
 * The standards list that feeds the multi-select — same source
 * BatchAuditRequestForm's `standards` prop is built from.
 *
 * Leads store standards as a JSON array of NAMES, not FK ids: the `leads`
 * table has no join to `standards`, and the CSV import already keys off
 * names ("ISO 9001|ISO 14001"). So the option value is the name, while
 * BatchForm's is the numeric id. Everything else about the control matches.
 */
export const getStandardOptions = async (): Promise<
  { value: string; label: string }[]
> => {
  const res = await fetchApi<any>(`${API_BASE_URL}/standards?limit=200`);
  const rows = Array.isArray(res) ? res : (res?.data ?? res?.rows ?? []);

  return rows
    .map((s: any) => {
      // Tolerate whichever column your standards table actually uses.
      const name =
        s.name ?? s.standard_name ?? s.title ?? s.code ?? s.standard ?? null;
      return name ? { value: String(name), label: String(name) } : null;
    })
    .filter(Boolean) as { value: string; label: string }[];
};
