import { headers } from "next/headers";

/**
 * Extract domain from request headers
 */
export async function extractDomain(): Promise<string> {
  const headersList = await headers();

  const domain =
    headersList.get("x-domain") ||
    headersList.get("x-forwarded-host") ||
    headersList.get("host") ||
    "localhost";

  // "www.<host>" is the same tenant as "<host>", but the backend looks the
  // domain up verbatim (DetectTenantContext: X-Domain ?? getHost()), so a
  // visitor arriving on www.staging-web.youngengineers.org was rejected with
  // DomainNotRecognizedError while the bare host worked. Normalise it here so
  // both spellings resolve to the same franchisee.
  const cleanDomain = domain
    .replace(/^https?:\/\//, "")
    .split(":")[0]
    .replace(/^www\./, "");

  return cleanDomain;
}

/**
 * Cleans a franchiseeId string by removing any trailing query parameters or malformed characters.
 * Ensures the result is a clean string with no delimiters.
 */
export function cleanFranchiseeId(id: string | null): string | null {
  if (!id) return null;
  // Aggressively split by any common URL delimiter and take the first part
  const cleanId = id.split(/[?&/=\s]/)[0];
  // Remove any non-alphanumeric or non-hyphen characters if it looks like a UUID
  return cleanId.trim();
}

/**
 * Robustly extracts parameters from a URL search string, handling malformed "dirty" inputs
 * (e.g., ?franchiseeId=UUID?lang=fr)
 */
export function getSanitizedParams(searchParams: URLSearchParams): { franchiseeId: string | null, lang: string | null } {
  let franchiseeId = searchParams.get('franchiseeId');
  // `language` is accepted as an alias: LanguageContext already reads either
  // key and the API client sends both, so a URL carrying only `?language=`
  // would otherwise be honoured on the client but invisible to the server.
  let lang = searchParams.get('lang') || searchParams.get('language');

  // Recover from dirty franchiseeId (often seen as UUID?lang=fr)
  if (franchiseeId && franchiseeId.includes('?')) {
    const parts = franchiseeId.split('?');
    franchiseeId = parts[0];

    // If we didn't have a lang, try to extract it from the dirty franchiseeId string
    if (!lang && parts[1]) {
      const subParams = new URLSearchParams(parts[1]);
      lang = subParams.get('lang') || subParams.get('language');
    }
  }

  return {
    franchiseeId: cleanFranchiseeId(franchiseeId),
    lang: lang || null
  };
}

/**
 * Extract franchiseeId from middleware headers
 */
export async function extractFranchiseeIdFromHeaders(): Promise<string | null> {
  const headersList = await headers();
  const rawId = headersList.get("x-franchisee-id");
  const franchiseeId = cleanFranchiseeId(rawId);

  return franchiseeId;
}

/**
 * Extract franchiseeId from URL search params (for pages)
 */
export function extractFranchiseeId(searchParams: Record<string, string | string[]>): string | null {
  if (!searchParams.franchiseeId) return null;
  const rawId = Array.isArray(searchParams.franchiseeId) ? searchParams.franchiseeId[0] : searchParams.franchiseeId;
  const id = cleanFranchiseeId(rawId);

  return id;
}

/**
 * Extract language from URL search params
 * Handles both 'lang' and 'language' keys, prioritizing 'lang'.
 * Always returns a clean string, defaults to 'default' if not found.
 */
export function extractLanguage(searchParams: any): string {
  if (!searchParams) return "default";

  // Handle Promise searchParams if passed (though usually awaited in page)
  const params = searchParams && typeof searchParams === "object" ? searchParams : {};

  const langKey = params.lang ? "lang" : params.language ? "language" : null;
  if (!langKey) return "default";

  const val = params[langKey];
  const lang = Array.isArray(val) ? val[0] : val;

  return (lang as string) || "default";
}

/**
 * Get global parameters (franchiseeId and lang) from headers.
 * Safe to call in any Server Component or Server Action.
 */
export async function getGlobalParams() {
  const headersList = await headers();
  const franchiseeId = cleanFranchiseeId(headersList.get("x-franchisee-id"));
  const lang = headersList.get("x-lang") || "default";

  return { franchiseeId, lang };
}