export type LeadInput = {
  businessType: string;
  volume: string;
  city: string;
  name: string;
  phone: string;
  website?: string;
  services: string[];
  lang?: string;
  company?: string; // honeypot
};

function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null && !Array.isArray(value);
}

function asTrimmedString(value: unknown, max: number): string | null {
  if (typeof value !== 'string') return null;
  const trimmed = value.trim();
  if (trimmed.length < 1) return null;
  if (trimmed.length > max) return null;
  return trimmed;
}

function asOptionalTrimmedString(value: unknown, max: number): string | undefined {
  if (value === undefined || value === null) return undefined;
  if (typeof value !== 'string') return undefined;
  const trimmed = value.trim();
  if (trimmed.length === 0) return '';
  if (trimmed.length > max) return undefined;
  return trimmed;
}

function isValidPhone(phoneRaw: string) {
  // Allow digits + whitespace only. Explicitly reject "+" and any other symbols.
  if (phoneRaw.includes('+')) return false;
  if (/[^0-9\s]/.test(phoneRaw)) return false;

  const digitsOnly = phoneRaw.replace(/\s+/g, '');
  if (!/^\d+$/.test(digitsOnly)) return false;

  // Morocco mobile formats:
  // - Local: 06xxxxxxxx / 07xxxxxxxx / 05xxxxxxxx / 08xxxxxxxx (10 digits)
  // - Without leading 0 (some UIs): 6xxxxxxxx / 7xxxxxxxx / 5xxxxxxxx / 8xxxxxxxx (9 digits)
  if (digitsOnly.startsWith('0')) {
    if (digitsOnly.length !== 10) return false;
    return /^0[5678]\d{8}$/.test(digitsOnly);
  }

  if (digitsOnly.length !== 9) return false;
  return /^[5678]\d{8}$/.test(digitsOnly);
}

function isValidWebsite(websiteRaw: string) {
  const value = websiteRaw.trim();
  if (!value) return true;
  if (/\s/.test(value)) return false;

  const hasScheme = /^https?:\/\//i.test(value);
  const candidate = hasScheme ? value : `https://${value}`;

  try {
    const url = new URL(candidate);
    // Basic hostname sanity: require at least one dot (example.com) and a TLD-ish ending.
    if (!url.hostname.includes('.')) return false;
    if (!/[a-z]{2,}$/i.test(url.hostname.split('.').pop() ?? '')) return false;
    return true;
  } catch {
    return false;
  }
}

function asStringArray(value: unknown, maxItems: number, maxLen: number): string[] | null {
  if (!Array.isArray(value)) return null;
  if (value.length > maxItems) return null;
  const out: string[] = [];
  for (const v of value) {
    if (typeof v !== 'string') return null;
    const s = v.trim();
    if (s.length < 1 || s.length > maxLen) return null;
    out.push(s);
  }
  return out;
}

export function parseLeadInput(payload: unknown): LeadInput | null {
  if (!isRecord(payload)) return null;

  const businessType = asTrimmedString(payload.businessType, 64);
  const volume = asTrimmedString(payload.volume, 64);
  const city = asTrimmedString(payload.city, 120);
  const name = asTrimmedString(payload.name, 120);
  const phone = asTrimmedString(payload.phone, 40);
  const website = asOptionalTrimmedString(payload.website, 200);
  const services = asStringArray(payload.services ?? [], 20, 64);
  const lang = asOptionalTrimmedString(payload.lang, 10);
  const company = asOptionalTrimmedString(payload.company, 200);

  if (!businessType || !volume || !city || !name || !phone || !services) return null;
  if (!isValidPhone(phone)) return null;
  if (website !== undefined && website !== '' && !isValidWebsite(website)) return null;
  const allowedServices = new Set(['ramassage', 'stockage', 'affiliate']);
  if (services.some((s) => !allowedServices.has(s))) return null;

  return {
    businessType,
    volume,
    city,
    name,
    phone,
    website,
    services,
    lang,
    company,
  };
}
