import type { DiagnosticFormValues } from './diagnosticForm';
import type { ContactFormValues } from './contactForm';
import type { ApplicateurFormValues } from './applicateurForm';
import type { LeadFormValues } from './leadForm';

/**
 * Soumission des formulaires vers HubSpot via l'API publique Forms Submission.
 *
 * Aucune clé secrète côté client : seuls le Portal ID et le Form GUID (publics) sont nécessaires.
 * Le token Private App ne sert qu'aux scripts de setup (scripts/hubspot/*).
 *
 * Les formulaires front sont alignés sur les formulaires client : les valeurs des options SONT déjà
 * les valeurs internes HubSpot, donc l'envoi est direct (pas de table de correspondance). Les champs
 * multi-sélection sont joints par ";".
 */

const PORTAL_ID = process.env.NEXT_PUBLIC_HUBSPOT_PORTAL_ID;
const DIAGNOSTIC_FORM_GUID = process.env.NEXT_PUBLIC_HUBSPOT_FORM_GUID_DIAGNOSTIC;
const CONTACT_FORM_GUID = process.env.NEXT_PUBLIC_HUBSPOT_FORM_GUID_CONTACT;
const APPLICATEUR_FORM_GUID = process.env.NEXT_PUBLIC_HUBSPOT_FORM_GUID_APPLICATEUR;
const LIVREBLANC_FORM_GUID = process.env.NEXT_PUBLIC_HUBSPOT_FORM_GUID_LIVREBLANC;
const ESTIMATION_FORM_GUID = process.env.NEXT_PUBLIC_HUBSPOT_FORM_GUID_ESTIMATION;
const SUBMIT_ENDPOINT = '/api/hubspot/submit';

// objectTypeId : "0-1" = contact (défaut), "0-2" = entreprise (company).
type Field = { key?: string; name: string; value: string; objectTypeId?: string };

export type HubspotFormFieldConfig = {
  localKey: string;
  name: string;
  objectTypeId?: string;
  active?: boolean;
  required?: boolean;
};

export type HubspotFormConfig = {
  code?: string;
  portalId?: string;
  formGuid?: string;
  mode?: string;
  fields?: HubspotFormFieldConfig[];
};

export const isHubspotConfigured = (): boolean => Boolean(PORTAL_ID && DIAGNOSTIC_FORM_GUID);
export const isHubspotContactConfigured = (): boolean => Boolean(PORTAL_ID && CONTACT_FORM_GUID);
export const isHubspotApplicateurConfigured = (): boolean => Boolean(PORTAL_ID && APPLICATEUR_FORM_GUID);

function readCookie(name: string): string | undefined {
  if (typeof document === 'undefined') return undefined;
  const match = document.cookie.match(new RegExp('(?:^|; )' + name + '=([^;]*)'));
  return match ? decodeURIComponent(match[1]) : undefined;
}

function applyFieldConfig(fields: Field[], config?: HubspotFormConfig): Field[] {
  if (!config?.fields?.length) return fields;

  const byKey = new Map<string, HubspotFormFieldConfig>();
  for (const field of config.fields) {
    const localKey = field.localKey?.trim();
    if (!localKey) continue;
    byKey.set(localKey, field);
  }

  return fields.flatMap((field) => {
    const configured = byKey.get(field.key ?? '') ?? byKey.get(field.name);
    if (configured?.active === false) return [];

    return {
      ...field,
      name: configured?.name?.trim() || field.name,
      objectTypeId: configured?.objectTypeId?.trim() || field.objectTypeId,
    };
  });
}

async function postHubspotForm(
  formGuid: string | undefined,
  fields: Field[],
  config?: HubspotFormConfig,
  captchaToken?: string,
): Promise<void> {
  const portalId = config?.portalId?.trim() || PORTAL_ID;
  const effectiveFormGuid = config?.formGuid?.trim() || formGuid;

  if (!portalId || !effectiveFormGuid) {
    throw new Error(
      'HubSpot non configuré : configuration WordPress ou NEXT_PUBLIC_HUBSPOT_PORTAL_ID / NEXT_PUBLIC_HUBSPOT_FORM_GUID_* manquants.',
    );
  }

  const configuredFields = applyFieldConfig(fields, config);
  const hutk = readCookie('hubspotutk');
  const body = {
    portalId,
    formGuid: effectiveFormGuid,
    captchaToken,
    fields: configuredFields
      .filter((f) => f.value !== '' && f.value != null)
      .map((f) => ({ objectTypeId: f.objectTypeId ?? '0-1', name: f.name, value: f.value })),
    context: {
      pageUri: typeof window !== 'undefined' ? window.location.href : undefined,
      pageName: typeof document !== 'undefined' ? document.title : undefined,
      ...(hutk ? { hutk } : {}),
    },
  };

  const res = await fetch(SUBMIT_ENDPOINT, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });

  if (!res.ok) {
    let detail = '';
    try {
      const json = await res.json();
      detail = json?.message || JSON.stringify(json);
    } catch {
      /* corps non-JSON */
    }
    throw new Error(`HubSpot ${res.status}${detail ? ` — ${detail}` : ''}`);
  }
}

// Mapping /diagnostic : email→email, firstName→firstname, lastName→lastname, company→company,
// phone→phone (E.164), profil→profil, city→city, postalCode→zip, country→country, enjeux[]→enjeux,
// typeRevetement[]→type_de_revetement, superficie→superficie_a_traiter__en_m2_,
// prestation[]→prestation_souhaitee, message→message.
export async function submitDiagnosticToHubspot(
  data: DiagnosticFormValues,
  config?: HubspotFormConfig,
  captchaToken?: string,
): Promise<void> {
  await postHubspotForm(DIAGNOSTIC_FORM_GUID, [
    { key: 'email', name: 'email', value: data.email },
    { key: 'firstName', name: 'firstname', value: data.firstName },
    { key: 'lastName', name: 'lastname', value: data.lastName },
    { key: 'company', name: 'company', value: data.company ?? '' },
    { key: 'phone', name: 'phone', value: data.phone },
    { key: 'profil', name: 'profil', value: data.profil },
    { key: 'city', name: 'city', value: data.city ?? '' },
    { key: 'postalCode', name: 'zip', value: data.postalCode ?? '' },
    { key: 'country', name: 'country', value: data.country ?? '' },
    { key: 'enjeux', name: 'enjeux', value: (data.enjeux ?? []).join(';') },
    { key: 'typeRevetement', name: 'type_de_revetement', value: (data.typeRevetement ?? []).join(';') },
    { key: 'superficie', name: 'superficie_a_traiter__en_m2_', value: data.superficie != null ? String(data.superficie) : '' },
    { key: 'prestation', name: 'prestation_souhaitee', value: (data.prestation ?? []).join(';') },
    { key: 'message', name: 'message', value: data.message?.trim() ?? '' },
  ], config, captchaToken);
}

// Mapping /contact : email→email, firstName→firstname, lastName→lastname, company→company,
// phone→phone (E.164), city→city, country→country, message→message.
export async function submitContactToHubspot(
  data: ContactFormValues,
  config?: HubspotFormConfig,
  captchaToken?: string,
): Promise<void> {
  await postHubspotForm(CONTACT_FORM_GUID, [
    { key: 'email', name: 'email', value: data.email },
    { key: 'firstName', name: 'firstname', value: data.firstName },
    { key: 'lastName', name: 'lastname', value: data.lastName },
    { key: 'company', name: 'company', value: data.company ?? '' },
    { key: 'phone', name: 'phone', value: data.phone },
    { key: 'city', name: 'city', value: data.city ?? '' },
    { key: 'country', name: 'country', value: data.country ?? '' },
    { key: 'message', name: 'message', value: data.message?.trim() ?? '' },
  ], config, captchaToken);
}

// Mapping /devenir-applicateur : champs Contact (0-1) + champs Entreprise (0-2).
// Entreprise : annee_de_creation… (number), avez_vous_deja_effectue… (bool), metier (texte),
// clientele (multi → ";"), ou_avez_vous_entendu_parler… (texte).
export async function submitApplicateurToHubspot(
  data: ApplicateurFormValues,
  config?: HubspotFormConfig,
  captchaToken?: string,
): Promise<void> {
  await postHubspotForm(APPLICATEUR_FORM_GUID, [
    { key: 'firstName', name: 'firstname', value: data.firstName },
    { key: 'lastName', name: 'lastname', value: data.lastName },
    { key: 'email', name: 'email', value: data.email },
    { key: 'phone', name: 'phone', value: data.phone },
    { key: 'company', name: 'company', value: data.company ?? '' },
    { key: 'country', name: 'country', value: data.country ?? '' },
    { key: 'city', name: 'city', value: data.city ?? '' },
    { key: 'anneeCreation', objectTypeId: '0-2', name: 'annee_de_creation_de_l_entreprise____a_2_ans_minimum_', value: data.anneeCreation != null ? String(data.anneeCreation) : '' },
    { key: 'chantierCoolRoof', objectTypeId: '0-2', name: 'avez_vous_deja_effectue_des_chantiers_cool_roof__', value: data.chantierCoolRoof ? 'true' : 'false' },
    { key: 'metier', objectTypeId: '0-2', name: 'metier', value: data.metier ?? '' },
    { key: 'clientele', objectTypeId: '0-2', name: 'clientele', value: (data.clientele ?? []).join(';') },
    { key: 'source', objectTypeId: '0-2', name: 'ou_avez_vous_entendu_parler_de_covalba__', value: data.source },
  ], config, captchaToken);
}

// Mapping lead (livre blanc / estimation) : firstName→firstname, lastName→lastname, email→email, company→company.
export async function submitLivreBlancToHubspot(
  data: LeadFormValues,
  config?: HubspotFormConfig,
  captchaToken?: string,
): Promise<void> {
  await postHubspotForm(LIVREBLANC_FORM_GUID, [
    { key: 'firstName', name: 'firstname', value: data.firstName },
    { key: 'lastName', name: 'lastname', value: data.lastName },
    { key: 'email', name: 'email', value: data.email },
    { key: 'company', name: 'company', value: data.company },
  ], config, captchaToken);
}

export async function submitEstimationToHubspot(
  data: LeadFormValues,
  config?: HubspotFormConfig,
  captchaToken?: string,
): Promise<void> {
  await postHubspotForm(ESTIMATION_FORM_GUID, [
    { key: 'firstName', name: 'firstname', value: data.firstName },
    { key: 'lastName', name: 'lastname', value: data.lastName },
    { key: 'email', name: 'email', value: data.email },
    { key: 'company', name: 'company', value: data.company },
    // Le formulaire HubSpot estimation/ROI exige `mobilephone` (sinon HTTP 400 REQUIRED_FIELD).
    { key: 'phone', name: 'mobilephone', value: data.phone ?? '' },
  ], config, captchaToken);
}
