const API = '/api/gateway';

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}` } : {}),
  };
}

async function apiFetch(path: string, options?: RequestInit): Promise<any> {
  const cleanPath = path.startsWith('/api/') ? path.slice(4) : path;
  const res = await fetch(`${API}${cleanPath}`, {
    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;
};

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 cleanPath = path.startsWith('/api/') ? path.slice(4) : path;
  const res = await fetch(`${API}${cleanPath}`, 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 const api = {
  get: <T = any>(path: string, headers?: HeadersInit) =>
    request<T>(path, { method: "GET", headers }),
  post: <T = any>(path: string, body?: unknown, headers?: HeadersInit) =>
    request<T>(path, { method: "POST", body, headers }),
  put: <T = any>(path: string, body?: unknown, headers?: HeadersInit) =>
    request<T>(path, { method: "PUT", body, headers }),
  patch: <T = any>(path: string, body?: unknown, headers?: HeadersInit) =>
    request<T>(path, { method: "PATCH", body, headers }),
  delete: <T = any>(path: string, headers?: HeadersInit) =>
    request<T>(path, { method: "DELETE", headers }),
};

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 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): Promise<any> {
  return apiFetch('/api/payments/create-order', {
    method: 'POST',
    body: JSON.stringify({ amount, package_id: packageId }),
  });
}

export async function verifyPayment(orderId: string, paymentId: string): Promise<any> {
  return apiFetch('/api/payments/verify', {
    method: 'POST',
    body: JSON.stringify({ order_id: orderId, payment_id: paymentId }),
  });
}

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}/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();
}
