// ---------------------------------------------------------------------------
// Ummahid API Client Library
// ---------------------------------------------------------------------------
// Provides typesafe HTTP methods for Souq, Learn, Forum, and FLH resources.
// Use these functions in Next.js API routes to call the Ummah ID backend
// instead of making direct Prisma queries.
//
// Usage (named imports — used by Souq routes):
//   import { getSouqListings } from "@/lib/ummahid-client";
//
// Usage (aggregate object — used by Learn & Forum routes):
//   import { ummahidClient } from "@/lib/ummahid-client";
//   ummahidClient.getLearnCourses(params, token);
// ---------------------------------------------------------------------------

import { NextRequest } from "next/server";

const UMMAHID_BASE = process.env.UMMAHID_URL || "http://falah_ummahid:3000";

// ---------------------------------------------------------------------------
// Internal helpers
// ---------------------------------------------------------------------------

/**
 * Extract a Bearer token from an incoming NextRequest.
 */
async function getToken(request: NextRequest): Promise<string | null> {
  const auth = request.headers.get("authorization");
  return auth?.startsWith("Bearer ") ? auth.slice(7) : null;
}

/**
 * Generic fetch wrapper against the Ummah ID API.
 */
async function apiCall(
  url: string,
  options?: {
    method?: string;
    body?: unknown;
    token?: string | null;
  },
): Promise<Response> {
  const headers: Record<string, string> = {
    "Content-Type": "application/json",
  };
  if (options?.token) {
    headers["Authorization"] = `Bearer ${options.token}`;
  }
  return fetch(`${UMMAHID_BASE}${url}`, {
    method: options?.method || "GET",
    headers,
    body: options?.body ? JSON.stringify(options.body) : undefined,
  });
}

// ---------------------------------------------------------------------------
// S O U Q  (Marketplace)
// ---------------------------------------------------------------------------

/**
 * GET /api/souq/categories
 */
async function getSouqCategories(token?: string | null): Promise<Response> {
  return apiCall("/api/souq/categories", { token });
}

/**
 * GET /api/souq/listings
 */
async function getSouqListings(
  params?: Record<string, unknown>,
  token?: string | null,
): Promise<Response> {
  const qs = new URLSearchParams();
  if (params) {
    for (const [key, value] of Object.entries(params)) {
      if (value !== undefined && value !== null) {
        qs.set(key, String(value));
      }
    }
  }
  const q = qs.toString();
  return apiCall(`/api/souq/listings${q ? `?${q}` : ""}`, { token });
}

/**
 * GET /api/souq/listings/:id
 */
async function getSouqListing(
  id: string,
  token?: string | null,
): Promise<Response> {
  return apiCall(`/api/souq/listings/${encodeURIComponent(id)}`, { token });
}

/**
 * POST /api/souq/listings
 */
async function createSouqListing(
  data: unknown,
  token: string,
): Promise<Response> {
  return apiCall("/api/souq/listings", { method: "POST", body: data, token });
}

/**
 * GET /api/souq/orders
 */
async function getSouqOrders(
  params?: Record<string, unknown>,
  token?: string,
): Promise<Response> {
  const qs = new URLSearchParams();
  if (params) {
    for (const [key, value] of Object.entries(params)) {
      if (value !== undefined && value !== null) {
        qs.set(key, String(value));
      }
    }
  }
  const q = qs.toString();
  return apiCall(`/api/souq/orders${q ? `?${q}` : ""}`, { token });
}

/**
 * POST /api/souq/orders
 */
async function createSouqOrder(
  data: unknown,
  token: string,
): Promise<Response> {
  return apiCall("/api/souq/orders", { method: "POST", body: data, token });
}

/**
 * GET /api/souq/orders/:id
 */
async function getSouqOrder(id: string, token: string): Promise<Response> {
  return apiCall(`/api/souq/orders/${encodeURIComponent(id)}`, { token });
}

/**
 * PATCH /api/souq/orders/:id
 */
async function updateSouqOrder(
  id: string,
  data: unknown,
  token: string,
): Promise<Response> {
  return apiCall(`/api/souq/orders/${encodeURIComponent(id)}`, {
    method: "PATCH",
    body: data,
    token,
  });
}

/**
 * POST /api/souq/reviews
 */
async function createSouqReview(
  data: unknown,
  token: string,
): Promise<Response> {
  return apiCall("/api/souq/reviews", { method: "POST", body: data, token });
}

/**
 * GET /api/souq/sellers/:id
 */
async function getSouqSeller(
  id: string,
  token?: string | null,
): Promise<Response> {
  return apiCall(`/api/souq/sellers/${encodeURIComponent(id)}`, { token });
}

// ---------------------------------------------------------------------------
// L E A R N  (Courses & Certification)
// ---------------------------------------------------------------------------

/**
 * GET /api/learn/categories
 */
async function getLearnCategories(token?: string): Promise<Response> {
  return apiCall("/api/learn/categories", { token });
}

/**
 * GET /api/learn/courses
 */
async function getLearnCourses(
  params?: Record<string, unknown>,
  token?: string,
): Promise<Response> {
  const qs = new URLSearchParams();
  if (params) {
    for (const [key, value] of Object.entries(params)) {
      if (value !== undefined && value !== null) {
        qs.set(key, String(value));
      }
    }
  }
  const q = qs.toString();
  return apiCall(`/api/learn/courses${q ? `?${q}` : ""}`, { token });
}

/**
 * GET /api/learn/courses/:slug
 */
async function getLearnCourse(
  slug: string,
  token?: string,
): Promise<Response> {
  return apiCall(`/api/learn/courses/${encodeURIComponent(slug)}`, { token });
}

/**
 * POST /api/learn/progress
 */
async function updateLearnProgress(
  data: unknown,
  token: string,
): Promise<Response> {
  return apiCall("/api/learn/progress", { method: "POST", body: data, token });
}

/**
 * GET /api/learn/pass/status
 */
async function getLearnPassStatus(token: string): Promise<Response> {
  return apiCall("/api/learn/pass/status", { token });
}

/**
 * POST /api/learn/pass/purchase
 */
async function purchaseLearnPass(
  data: unknown,
  token: string,
): Promise<Response> {
  return apiCall("/api/learn/pass/purchase", {
    method: "POST",
    body: data,
    token,
  });
}

/**
 * GET /api/learn/certificates
 */
async function getLearnCertificates(token: string): Promise<Response> {
  return apiCall("/api/learn/certificates", { token });
}

/**
 * GET /api/learn/certificates/:serial
 */
async function getLearnCertificate(
  serial: string,
  token?: string,
): Promise<Response> {
  return apiCall(
    `/api/learn/certificates/${encodeURIComponent(serial)}`,
    { token },
  );
}

/**
 * GET /api/learn/certificates/verify/:serial
 */
async function verifyLearnCertificate(serial: string): Promise<Response> {
  return apiCall(
    `/api/learn/certificates/verify/${encodeURIComponent(serial)}`,
  );
}

/**
 * GET /api/learn/tts
 */
async function getLearnTts(
  params?: Record<string, unknown>,
  token?: string,
): Promise<Response> {
  const qs = new URLSearchParams();
  if (params) {
    for (const [key, value] of Object.entries(params)) {
      if (value !== undefined && value !== null) {
        qs.set(key, String(value));
      }
    }
  }
  const q = qs.toString();
  return apiCall(`/api/learn/tts${q ? `?${q}` : ""}`, { token });
}

/**
 * POST /api/learn/tts — trigger TTS generation for a module
 */
async function updateLearnTts(
  data: unknown,
  token: string,
): Promise<Response> {
  return apiCall("/api/learn/tts", { method: "POST", body: data, token });
}

/**
 * POST /api/learn/sync
 */
async function syncLearnCourses(
  data: unknown,
  syncToken?: string,
): Promise<Response> {
  return apiCall("/api/learn/sync", {
    method: "POST",
    body: data,
    token: syncToken,
  });
}

// ---------------------------------------------------------------------------
// F O R U M  (Discussions & Groups)
// ---------------------------------------------------------------------------

/**
 * GET /api/forum/categories
 */
async function getForumCategories(token?: string): Promise<Response> {
  return apiCall("/api/forum/categories", { token });
}

/**
 * GET /api/forum/threads
 */
async function getForumThreads(
  params?: Record<string, unknown>,
  token?: string,
): Promise<Response> {
  const qs = new URLSearchParams();
  if (params) {
    for (const [key, value] of Object.entries(params)) {
      if (value !== undefined && value !== null) {
        qs.set(key, String(value));
      }
    }
  }
  const q = qs.toString();
  return apiCall(`/api/forum/threads${q ? `?${q}` : ""}`, { token });
}

/**
 * POST /api/forum/threads
 */
async function createForumThread(
  data: unknown,
  token: string,
): Promise<Response> {
  return apiCall("/api/forum/threads", { method: "POST", body: data, token });
}

/**
 * GET /api/forum/posts
 */
async function getForumPosts(
  params?: Record<string, unknown>,
  token?: string,
): Promise<Response> {
  const qs = new URLSearchParams();
  if (params) {
    for (const [key, value] of Object.entries(params)) {
      if (value !== undefined && value !== null) {
        qs.set(key, String(value));
      }
    }
  }
  const q = qs.toString();
  return apiCall(`/api/forum/posts${q ? `?${q}` : ""}`, { token });
}

/**
 * POST /api/forum/posts
 */
async function createForumPost(
  data: unknown,
  token: string,
): Promise<Response> {
  return apiCall("/api/forum/posts", { method: "POST", body: data, token });
}

/**
 * POST /api/forum/groups
 */
async function createForumGroup(
  data: unknown,
  token: string,
): Promise<Response> {
  return apiCall("/api/forum/groups", { method: "POST", body: data, token });
}

/**
 * POST /api/forum/groups/join
 */
async function joinForumGroup(
  inviteCode: string,
  token: string,
): Promise<Response> {
  return apiCall("/api/forum/groups/join", {
    method: "POST",
    body: { inviteCode },
    token,
  });
}

// ---------------------------------------------------------------------------
// F L H  (Financial Liberation Hub)
// ---------------------------------------------------------------------------

/**
 * GET /api/flh/balance
 */
async function getFlhBalance(token: string): Promise<Response> {
  return apiCall("/api/flh/balance", { token });
}

/**
 * GET /api/flh/zakat/status
 */
async function getZakatStatus(token: string): Promise<Response> {
  return apiCall("/api/flh/zakat/status", { token });
}

/**
 * POST /api/flh/zakat/pay
 */
async function payZakat(data: unknown, token: string): Promise<Response> {
  return apiCall("/api/flh/zakat/pay", { method: "POST", body: data, token });
}

/**
 * GET /api/flh/sadaqah/causes
 */
async function getSadaqahCauses(token?: string): Promise<Response> {
  return apiCall("/api/flh/sadaqah/causes", { token });
}

/**
 * POST /api/flh/sadaqah/send
 */
async function sendSadaqah(data: unknown, token: string): Promise<Response> {
  return apiCall("/api/flh/sadaqah/send", {
    method: "POST",
    body: data,
    token,
  });
}

/**
 * POST /api/flh/hibah/send
 */
async function sendHibah(data: unknown, token: string): Promise<Response> {
  return apiCall("/api/flh/hibah/send", { method: "POST", body: data, token });
}

/**
 * POST /api/flh/waqf/create
 */
async function createWaqf(data: unknown, token: string): Promise<Response> {
  return apiCall("/api/flh/waqf/create", { method: "POST", body: data, token });
}

/**
 * POST /api/flh/waqf/contribute
 */
async function contributeWaqf(
  data: unknown,
  token: string,
): Promise<Response> {
  return apiCall("/api/flh/waqf/contribute", {
    method: "POST",
    body: data,
    token,
  });
}

// ---------------------------------------------------------------------------
// Aggregated client object (used by Learn & Forum routes)
// ---------------------------------------------------------------------------

const ummahidClient = {
  // Souq
  getSouqCategories,
  getSouqListings,
  getSouqListing,
  createSouqListing,
  getSouqOrders,
  createSouqOrder,
  getSouqOrder,
  updateSouqOrder,
  createSouqReview,
  getSouqSeller,
  // Learn
  getLearnCategories,
  getLearnCourses,
  getLearnCourse,
  updateLearnProgress,
  getLearnPassStatus,
  purchaseLearnPass,
  getLearnCertificates,
  getLearnCertificate,
  verifyLearnCertificate,
  getLearnTts,
  updateLearnTts,
  syncLearnCourses,
  // Forum
  getForumCategories,
  getForumThreads,
  createForumThread,
  getForumPosts,
  createForumPost,
  createForumGroup,
  joinForumGroup,
  // FLH
  getFlhBalance,
  getZakatStatus,
  payZakat,
  getSadaqahCauses,
  sendSadaqah,
  sendHibah,
  createWaqf,
  contributeWaqf,
};

export {
  // helpers
  getToken,
  apiCall,
  // aggregated client
  ummahidClient,
  // Souq
  getSouqCategories,
  getSouqListings,
  getSouqListing,
  createSouqListing,
  getSouqOrders,
  createSouqOrder,
  getSouqOrder,
  updateSouqOrder,
  createSouqReview,
  getSouqSeller,
  // Learn
  getLearnCategories,
  getLearnCourses,
  getLearnCourse,
  updateLearnProgress,
  getLearnPassStatus,
  purchaseLearnPass,
  getLearnCertificates,
  getLearnCertificate,
  verifyLearnCertificate,
  getLearnTts,
  updateLearnTts,
  syncLearnCourses,
  // Forum
  getForumCategories,
  getForumThreads,
  createForumThread,
  getForumPosts,
  createForumPost,
  createForumGroup,
  joinForumGroup,
  // FLH
  getFlhBalance,
  getZakatStatus,
  payZakat,
  getSadaqahCauses,
  sendSadaqah,
  sendHibah,
  createWaqf,
  contributeWaqf,
};
