// The K8s ingress routes any /api/* path directly to the Rust gateway service —
// there is no /api/gateway indirection or rewrite in production (a dev-only
// vite proxy used to do that rewrite, but it doesn't exist in the deployed
// build). Callers already pass fully-qualified /api/... paths; hit them as-is.

function getAuthHeaders(): Record<string, string> {
  const token = typeof window !== 'undefined'
    ? (sessionStorage.getItem('nxtgauge_access_token') || '')
    : '';
  return {
    'Content-Type': 'application/json',
    Accept: 'application/json',
    ...(token ? { Authorization: `Bearer ${token}` } : {}),
  };
}

export async function apiFetch(path: string, options?: RequestInit): Promise<any> {
  const res = await fetch(path, {
    headers: getAuthHeaders(),
    credentials: 'include',
    ...options,
  });
  if (!res.ok) {
    const text = await res.text().catch(() => '');
    throw new Error(`API error ${res.status}: ${text}`);
  }
  return res.json();
}

type ApiResponse<T = any> = {
  data: T;
  status: number;
  headers: Headers;
};

export async function request<T = any>(
  path: string,
  options?: { method?: string; body?: unknown; headers?: HeadersInit }
): Promise<ApiResponse<T>> {
  const mergedHeaders: HeadersInit = {
    ...getAuthHeaders(),
    ...(options?.headers || {}),
  };
  const init: RequestInit = {
    method: options?.method || "GET",
    headers: mergedHeaders,
    credentials: "include",
  };
  if (options?.body !== undefined) {
    init.body = JSON.stringify(options.body);
  }
  const res = await fetch(path, init);
  const raw = await res.text();
  const data = raw ? JSON.parse(raw) : null;
  if (!res.ok) {
    const message = (data && (data.message || data.error)) || `API error ${res.status}`;
    throw new Error(message);
  }
  return { data: data as T, status: res.status, headers: res.headers };
}

export type CaptchaChallenge = {
  captcha_id: string;
  challenge: string;
};

/**
 * Request a new server-side captcha challenge.
 * Single-use and expires after 5 minutes — callers must fetch a fresh one
 * whenever the previous captcha_id was consumed or the submit failed with
 * CAPTCHA_FAILED.
 */
export async function fetchCaptcha(): Promise<CaptchaChallenge> {
  return apiFetch('/api/auth/captcha', { method: 'POST' });
}

export async function fetchProfile(rolePrefix: string): Promise<any> {
  return apiFetch(`/api/${rolePrefix}/profile/me`);
}

export async function saveProfile(rolePrefix: string, payload: any): Promise<any> {
  return apiFetch(`/api/${rolePrefix}/profile/me`, {
    method: 'PATCH',
    body: JSON.stringify(payload),
  });
}

export async function fetchDocuments(rolePrefix: string): Promise<any[]> {
  const res = await apiFetch(`/api/${rolePrefix}/profile/documents`);
  return res?.data ?? [];
}

/**
 * Resolve a stored document reference into a short-lived, signed view URL.
 * Never render a stored document URL directly (e.g. as an <a href> or <img src>)
 * — always exchange it for a fresh one through this endpoint first.
 */
export async function presignDocumentUrl(url: string): Promise<string> {
  const res = await apiFetch('/api/profile/documents/presign', {
    method: 'POST',
    body: JSON.stringify({ url }),
  });
  return res?.url ?? url;
}

export async function submitProfileForVerification(rolePrefix: string): Promise<any> {
  return apiFetch(`/api/${rolePrefix}/profile/submit`, {
    method: 'POST',
  });
}

export async function fetchPortfolio(rolePrefix: string): Promise<any> {
  return apiFetch(`/api/${rolePrefix}/portfolio/me`);
}

export async function createPortfolioItem(rolePrefix: string, payload: any): Promise<any> {
  return apiFetch(`/api/${rolePrefix}/portfolio`, {
    method: 'POST',
    body: JSON.stringify(payload),
  });
}

export async function updatePortfolioItem(rolePrefix: string, id: string, payload: any): Promise<any> {
  return apiFetch(`/api/${rolePrefix}/portfolio/${id}`, {
    method: 'PATCH',
    body: JSON.stringify(payload),
  });
}

export async function deletePortfolioItem(rolePrefix: string, id: string): Promise<any> {
  return apiFetch(`/api/${rolePrefix}/portfolio/${id}`, {
    method: 'DELETE',
  });
}

export async function fetchServices(rolePrefix: string): Promise<any> {
  return apiFetch(`/api/${rolePrefix}/services`);
}

export async function createService(rolePrefix: string, payload: any): Promise<any> {
  return apiFetch(`/api/${rolePrefix}/services`, {
    method: 'POST',
    body: JSON.stringify(payload),
  });
}

export async function deleteService(rolePrefix: string, id: string): Promise<any> {
  return apiFetch(`/api/${rolePrefix}/services/${id}`, {
    method: 'DELETE',
  });
}

export async function fetchWallet(rolePrefix: string): Promise<any> {
  return apiFetch(`/api/${rolePrefix}/wallet`);
}

export async function fetchLedger(rolePrefix: string, page = 1, limit = 20): Promise<any> {
  return apiFetch(`/api/${rolePrefix}/wallet/ledger?page=${page}&limit=${limit}`);
}

export async function fetchInvoices(rolePrefix: string, page = 1, limit = 20): Promise<any> {
  return apiFetch(`/api/${rolePrefix}/wallet/invoices?page=${page}&limit=${limit}`);
}

export async function createPaymentOrder(
  amount: number,
  packageId?: string,
  currency = "INR"
): Promise<any> {
  return apiFetch('/api/payments/create-order', {
    method: 'POST',
    body: JSON.stringify({ amount, currency, package_id: packageId }),
  });
}

export async function verifyPayment(
  orderId: string,
  paymentId: string,
  signature: string
): Promise<any> {
  return apiFetch('/api/payments/verify', {
    method: 'POST',
    body: JSON.stringify({
      txnid: orderId,
      mihpayid: paymentId,
      status: 'SUCCESS',
      hash: signature,
    }),
  });
}

export async function fetchPaymentStatus(paymentId: string): Promise<any> {
  return apiFetch(`/api/payments/${paymentId}/status`);
}

export async function fetchJobs(rolePrefix: string, params?: Record<string, string>): Promise<any> {
  const qs = params ? '?' + new URLSearchParams(params).toString() : '';
  return apiFetch(`/api/${rolePrefix}/jobs${qs}`);
}

export async function applyToJob(rolePrefix: string, jobId: string, payload: any): Promise<any> {
  return apiFetch(`/api/${rolePrefix}/jobs/${jobId}/apply`, {
    method: 'POST',
    body: JSON.stringify(payload),
  });
}

export async function fetchMyApplications(rolePrefix: string): Promise<any> {
  return apiFetch(`/api/${rolePrefix}/applications`);
}

export async function fetchRequirements(rolePrefix: string): Promise<any> {
  return apiFetch(`/api/${rolePrefix}/requirements`);
}

export async function createRequirement(rolePrefix: string, payload: any): Promise<any> {
  return apiFetch(`/api/${rolePrefix}/requirements`, {
    method: 'POST',
    body: JSON.stringify(payload),
  });
}

export async function fetchMarketplace(rolePrefix: string, page = 1, limit = 20): Promise<any> {
  return apiFetch(`/api/${rolePrefix}/marketplace?page=${page}&limit=${limit}`);
}

export async function createLeadRequest(rolePrefix: string, payload: any): Promise<any> {
  return apiFetch(`/api/${rolePrefix}/leads/request`, {
    method: 'POST',
    body: JSON.stringify(payload),
  });
}

export async function fetchMyLeadRequests(rolePrefix: string): Promise<any> {
  return apiFetch(`/api/${rolePrefix}/leads/requests`);
}

export async function uploadDocument(rolePrefix: string, file: File, documentType: string): Promise<any> {
  const formData = new FormData();
  formData.append('file', file);
  formData.append('document_type', documentType);

  const token = typeof window !== 'undefined'
    ? (sessionStorage.getItem('nxtgauge_access_token') || '')
    : '';

  const res = await fetch(`/api/${rolePrefix}/profile/documents`, {
    method: 'POST',
    headers: {
      ...(token ? { Authorization: `Bearer ${token}` } : {}),
    },
    credentials: 'include',
    body: formData,
  });

  if (!res.ok) {
    const text = await res.text().catch(() => '');
    throw new Error(`Upload error ${res.status}: ${text}`);
  }
  return res.json();
}

/**
 * Submit a COMPANY profile + documents in a single multipart POST.
 * Used by the 3-step wizard on the Company dashboard.
 * Returns: { verification_id, status, documents_uploaded, documents_failed, storage_backend, document_errors? }
 */
export async function submitCompanyProfileWithDocuments(
  profileData: Record<string, any>,
  documents: Array<{ documentType: string; file: File }>
): Promise<any> {
  const token = typeof window !== 'undefined'
    ? (sessionStorage.getItem('nxtgauge_access_token') || '')
    : '';
  const fd = new FormData();
  fd.append('profile', JSON.stringify(profileData));
  for (const { documentType, file } of documents) {
    // Append a stable filename so the backend can derive document_type from the stem
    // Use | as separator so the backend can split on the first | to recover documentType,
    // regardless of underscores in either the doc type key or the original filename.
    fd.append('documents', file, `${documentType}|${file.name}`);
  }
  const res = await fetch(`/api/companies/profile/submit-with-documents`, {
    method: 'POST',
    headers: token ? { Authorization: `Bearer ${token}` } : {},
    credentials: 'include',
    body: fd,
  });
  const text = await res.text().catch(() => '');
  if (!res.ok) {
    let msg = `Submit failed: ${res.status}`;
    try { msg = JSON.parse(text).error || msg; } catch { /* keep default */ }
    throw new Error(msg);
  }
  return text ? JSON.parse(text) : {};
}
