/* MIRAI onboarding — estado, condiciones y outputs */

const MIRAI_ONBOARDING_HANDOFF_LABELS = ["Derivar a asesor", "Derivar a un humano"];

function miraiOnboardingBaseAnswers(submittedAt = "") {
  return {
    client: {},
    business: {},
    objectives: {},
    flows: [],
    data_capture: {},
    catalog: {},
    handoff: {},
    tone: {},
    integrations: {},
    reference_bot: {},
    metadata: {
      submitted_at: submittedAt,
      version: MIRAI_ONBOARDING_VERSION,
    },
  };
}

function miraiOnboardingIsBusiness(values) {
  return values.business_type === "Empresa";
}

function miraiOnboardingActiveSections(values) {
  if (!values.business_type) return [MIRAI_ONBOARDING_TYPE_SECTION];
  const rest = miraiOnboardingIsBusiness(values) ? MIRAI_ONBOARDING_SECTIONS_BUSINESS : MIRAI_ONBOARDING_SECTIONS_REALESTATE;
  return [MIRAI_ONBOARDING_TYPE_SECTION, ...rest];
}

function miraiOnboardingActiveQuestions(values) {
  if (!values.business_type) return [MIRAI_ONBOARDING_TYPE_QUESTION];
  const rest = miraiOnboardingIsBusiness(values) ? MIRAI_ONBOARDING_QUESTIONS_BUSINESS : MIRAI_ONBOARDING_QUESTIONS_REALESTATE;
  return [MIRAI_ONBOARDING_TYPE_QUESTION, ...rest];
}

function miraiOnboardingAllQuestions() {
  const seen = new Set();
  const all = [MIRAI_ONBOARDING_TYPE_QUESTION, ...MIRAI_ONBOARDING_QUESTIONS_REALESTATE, ...MIRAI_ONBOARDING_QUESTIONS_BUSINESS];
  return all.filter((q) => {
    if (seen.has(q.id)) return false;
    seen.add(q.id);
    return true;
  });
}

function miraiOnboardingInitialValues() {
  return miraiOnboardingAllQuestions().reduce((acc, q) => {
    if (q.type === "multi") acc[q.id] = [];
    else if (q.type === "slider") acc[q.id] = q.defaultValue ?? q.min ?? 1;
    else acc[q.id] = "";
    return acc;
  }, {});
}

function miraiOnboardingIsEmpty(value) {
  if (Array.isArray(value)) return value.length === 0;
  return value == null || String(value).trim() === "";
}

function miraiOnboardingMatchesRule(rule, values) {
  if (!rule) return true;
  if (rule.any) return rule.any.some((r) => miraiOnboardingMatchesRule(r, values));
  if (rule.all) return rule.all.every((r) => miraiOnboardingMatchesRule(r, values));

  const value = values[rule.field];
  if (Object.prototype.hasOwnProperty.call(rule, "equals")) return value === rule.equals;
  if (rule.includesAny) {
    const list = Array.isArray(value) ? value : value ? [value] : [];
    return rule.includesAny.some((x) => list.includes(x));
  }
  if (rule.exists) return !miraiOnboardingIsEmpty(value);
  return true;
}

function miraiOnboardingVisibleSections(values) {
  return miraiOnboardingActiveSections(values).filter((section) =>
    miraiOnboardingMatchesRule(section.showIf, values)
  );
}

function miraiOnboardingVisibleQuestions(sectionId, values) {
  return miraiOnboardingActiveQuestions(values).filter((q) =>
    q.section === sectionId && miraiOnboardingMatchesRule(q.showIf, values)
  );
}

function miraiOnboardingValidateEmail(value) {
  const text = String(value || "").trim();
  return /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(text);
}

function miraiOnboardingValidateWhatsApp(value) {
  const text = String(value || "").trim();
  if (!/^[+\d\s().-]+$/.test(text)) return false;
  if ((text.match(/\+/g) || []).length > 1) return false;
  if (text.includes("+") && !text.startsWith("+")) return false;
  const digits = text.replace(/\D/g, "");
  return digits.length >= 8 && digits.length <= 15;
}

function miraiOnboardingValidateQuestion(question, values) {
  const value = values[question.id];
  if (question.required && miraiOnboardingIsEmpty(value)) return "Completa este campo para continuar.";
  if (miraiOnboardingIsEmpty(value)) return "";
  if (question.type === "email" && !miraiOnboardingValidateEmail(value)) {
    return "Ingresa un email valido, por ejemplo nombre@empresa.com.";
  }
  if (question.type === "tel" && !miraiOnboardingValidateWhatsApp(value)) {
    return "Ingresa un WhatsApp valido con codigo de area. Puede incluir +, espacios, guiones o parentesis.";
  }
  return "";
}

function miraiOnboardingSectionErrors(sectionId, values) {
  return miraiOnboardingVisibleQuestions(sectionId, values).reduce((acc, q) => {
    const error = miraiOnboardingValidateQuestion(q, values);
    if (error) acc[q.id] = error;
    return acc;
  }, {});
}

function miraiOnboardingSectionComplete(sectionId, values) {
  return Object.keys(miraiOnboardingSectionErrors(sectionId, values)).length === 0;
}

function miraiOnboardingVisibleValidationIssues(values) {
  const visibleSectionIds = miraiOnboardingVisibleSections(values).map((s) => s.id);
  return miraiOnboardingActiveQuestions(values).filter((q) => {
    if (!visibleSectionIds.includes(q.section)) return false;
    return miraiOnboardingMatchesRule(q.showIf, values);
  }).reduce((acc, q) => {
    const error = miraiOnboardingValidateQuestion(q, values);
    if (error) acc.push(q.label);
    return acc;
  }, []);
}

function miraiOnboardingVisibleRequiredMissing(values) {
  return miraiOnboardingVisibleValidationIssues(values);
}

function miraiOnboardingSetTarget(answers, target, value) {
  if (!target || target[0] === "flows") return;
  const [bucket, key] = target;
  if (!answers[bucket]) answers[bucket] = {};
  answers[bucket][key] = value;
}

function miraiOnboardingUnique(list) {
  return Array.from(new Set((list || []).filter(Boolean)));
}

function miraiOnboardingSelected(values, id) {
  return Array.isArray(values[id]) ? values[id] : [];
}

function miraiOnboardingValueWithOther(values, id, otherId) {
  const value = values[id];
  const other = values[otherId];
  if (Array.isArray(value)) {
    return value.map((item) => item === "Otro" && other ? `Otro: ${other}` : item);
  }
  if (value === "Otro" && other) return `Otro: ${other}`;
  return value;
}

function miraiOnboardingHasHandoff(values) {
  return miraiOnboardingSelected(values, "agent_capabilities").some((c) => MIRAI_ONBOARDING_HANDOFF_LABELS.includes(c));
}

function miraiOnboardingDeriveFlowsRealEstate(values) {
  const operations = miraiOnboardingSelected(values, "operation_types");
  const capabilities = miraiOnboardingSelected(values, "agent_capabilities");
  const flows = [];

  if (operations.includes("Alquiler")) flows.push("Quiero alquilar");
  if (operations.includes("Compra")) flows.push("Quiero comprar");
  if (operations.includes("Venta / tasacion")) flows.push("Quiero vender", "Quiero tasar");
  if (operations.includes("Administracion de propiedades")) flows.push("Ya soy cliente y necesito soporte");
  if (operations.includes("Emprendimientos")) flows.push("Consulto por un emprendimiento");
  if (operations.includes("Inversiones")) flows.push("Busco inversion");
  if (capabilities.includes("Enviar fichas o links") || capabilities.includes("Responder consultas sobre propiedades")) {
    flows.push("Consulto por una propiedad especifica");
  }
  if (capabilities.includes("Agendar visitas")) flows.push("Quiero visitar una propiedad");
  if (capabilities.includes("Hacer seguimiento")) flows.push("Seguimiento de lead");
  if (capabilities.includes("Derivar a asesor")) flows.push("Quiero hablar con un asesor");
  if (capabilities.includes("Responder preguntas frecuentes") || capabilities.includes("Detectar intencion")) {
    flows.push("Consulta general");
  }

  return miraiOnboardingUnique(flows);
}

function miraiOnboardingDeriveFlowsBusiness(values) {
  const operations = miraiOnboardingSelected(values, "operation_types");
  const capabilities = miraiOnboardingSelected(values, "agent_capabilities");
  const flows = [];

  if (operations.includes("Ventas")) flows.push("Quiero comprar o cotizar");
  if (operations.includes("Consultas de producto/servicio")) flows.push("Tengo una consulta sobre un producto o servicio");
  if (operations.includes("Soporte / postventa")) flows.push("Necesito soporte o ayuda postventa");
  if (operations.includes("Turnos o reservas")) flows.push("Quiero agendar un turno o reserva");
  if (operations.includes("Cotizaciones / presupuestos")) flows.push("Quiero un presupuesto");
  if (operations.includes("Reclamos")) flows.push("Quiero hacer un reclamo");
  if (capabilities.includes("Enviar informacion o catalogos") || capabilities.includes("Responder consultas sobre productos o servicios")) {
    flows.push("Consulto por un producto o servicio especifico");
  }
  if (capabilities.includes("Agendar turnos o reuniones")) flows.push("Quiero agendar una reunion");
  if (capabilities.includes("Hacer seguimiento")) flows.push("Seguimiento de lead");
  if (capabilities.includes("Derivar a un humano")) flows.push("Quiero hablar con una persona");
  if (capabilities.includes("Responder preguntas frecuentes") || capabilities.includes("Detectar intencion")) {
    flows.push("Consulta general");
  }

  return miraiOnboardingUnique(flows);
}

function miraiOnboardingDeriveFlows(values) {
  return miraiOnboardingIsBusiness(values) ? miraiOnboardingDeriveFlowsBusiness(values) : miraiOnboardingDeriveFlowsRealEstate(values);
}

function miraiOnboardingNeedsCatalog(values) {
  return miraiOnboardingVisibleSections(values).some((s) => s.id === "catalog");
}

function miraiOnboardingDerivedAskBeforeHandoff(values) {
  return miraiOnboardingHasHandoff(values) ? "Si" : "No";
}

function miraiOnboardingDerivedCanSendProperties(values) {
  return miraiOnboardingNeedsCatalog(values) ? "Si" : "No";
}

function miraiOnboardingCreateAnswers(values, submittedAt = "") {
  const answers = miraiOnboardingBaseAnswers(submittedAt);
  const activeQuestions = miraiOnboardingActiveQuestions(values);
  const activeSections = miraiOnboardingActiveSections(values);

  activeQuestions.forEach((q) => {
    const section = activeSections.find((s) => s.id === q.section);
    if (section && !miraiOnboardingMatchesRule(section.showIf, values)) return;
    if (!miraiOnboardingMatchesRule(q.showIf, values)) return;
    const value = values[q.id];
    if (miraiOnboardingIsEmpty(value) && q.type !== "slider") return;
    miraiOnboardingSetTarget(answers, q.target, value);
  });

  const selectedFlows = miraiOnboardingDeriveFlows(values);
  const flowSpecificData = miraiOnboardingValueWithOther(values, "flow_specific_data", "flow_specific_data_other");
  const hasHandoff = miraiOnboardingHasHandoff(values);

  answers.flows = selectedFlows.map((type) => ({
    type,
    first_version: "Si",
    ask_before_handoff: miraiOnboardingDerivedAskBeforeHandoff(values),
    can_send_properties: miraiOnboardingDerivedCanSendProperties(values),
    advisor_specific: hasHandoff ? (values.advisor_assignment || "A definir") : "No aplica",
    extra_data_to_capture: flowSpecificData,
    direct_to_human_notes: hasHandoff ? miraiOnboardingValueWithOther(values, "handoff_moments", "handoff_moments_other").join(", ") : "No aplica",
  }));

  answers.objectives.inferred_flows = selectedFlows;
  answers.objectives.has_handoff = hasHandoff ? "Si" : "No";
  answers.data_capture.default_for_operation = flowSpecificData;
  answers.integrations.auto_create_records = miraiOnboardingSelected(values, "agent_capabilities").includes("Registrar datos en CRM/Sheets") ? "Si" : "A definir";
  answers.integrations.save_conversation_history = "A definir en implementacion";
  answers.integrations.technical_owner = "Mirai";
  answers.tone.one_question_at_time = Number(values.qualification_depth || 3) >= 3 ? "Si" : "A definir";

  return answers;
}

function miraiOnboardingFmt(value, fallback = "A definir") {
  if (Array.isArray(value)) return value.length ? value.join(", ") : fallback;
  if (value == null || String(value).trim() === "") return fallback;
  return String(value);
}

function miraiOnboardingList(value, fallback = "- A definir") {
  const list = Array.isArray(value) ? value : value ? [value] : [];
  if (!list.length) return fallback;
  return list.map((x) => `- ${x}`).join("\n");
}

function miraiOnboardingFutureChannels(values) {
  const channels = miraiOnboardingSelected(values, "channels_to_connect");
  return channels.filter((ch) => ch !== "WhatsApp");
}

function miraiOnboardingBlueprintItemsFor(values, config) {
  const missing = miraiOnboardingVisibleValidationIssues(values);
  const channels = miraiOnboardingSelected(values, "channels_to_connect").length
    ? miraiOnboardingValueWithOther(values, "channels_to_connect", "channels_to_connect_other")
    : miraiOnboardingValueWithOther(values, "lead_channels", "lead_channels_other");

  return [
    {
      label: config.nameLabel,
      value: miraiOnboardingFmt(values.agency_name),
    },
    {
      label: "Habilidades",
      value: miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "agent_capabilities", "agent_capabilities_other")),
    },
    {
      label: "Canales",
      value: miraiOnboardingFmt(channels),
    },
    {
      label: "Flujos inferidos",
      value: miraiOnboardingFmt(miraiOnboardingDeriveFlows(values)),
    },
    {
      label: "Datos minimos",
      value: miraiOnboardingFmt(values.basic_data),
    },
    {
      label: config.catalogLabel,
      value: miraiOnboardingNeedsCatalog(values)
        ? miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "property_source", "property_source_other"), config.catalogFallback)
        : "No requerido para la primera version",
    },
    {
      label: "Derivacion",
      value: miraiOnboardingHasHandoff(values) ? miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "handoff_moments", "handoff_moments_other")) : "No requerida",
    },
    {
      label: "Entrega",
      value: miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "lead_summary_delivery", "lead_summary_delivery_other")),
    },
    {
      label: "Pendiente",
      value: missing.length ? `${missing.length} dato(s) requerido(s)` : "Listo para generar",
    },
  ];
}

function miraiOnboardingBlueprintItems(values) {
  if (!values.business_type) {
    return [{ label: "Tipo de negocio", value: "Elegi inmobiliaria o empresa para ver los planos" }];
  }
  return miraiOnboardingIsBusiness(values)
    ? miraiOnboardingBlueprintItemsFor(values, {
        nameLabel: "Empresa",
        catalogLabel: "Catalogo",
        catalogFallback: "Pendiente definir fuente de productos o servicios",
      })
    : miraiOnboardingBlueprintItemsFor(values, {
        nameLabel: "Inmobiliaria",
        catalogLabel: "Catalogo",
        catalogFallback: "Pendiente definir fuente de propiedades",
      });
}

function miraiOnboardingBuildClientMarkdownRealEstate(values) {
  const answers = miraiOnboardingCreateAnswers(values, "");
  const needsCatalog = miraiOnboardingNeedsCatalog(values);
  const hasHandoff = miraiOnboardingHasHandoff(values);
  const missing = miraiOnboardingVisibleValidationIssues(values);
  const catalogText = needsCatalog
    ? [
        `Fuente actual: ${miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "property_source", "property_source_other"))}.`,
        `Estado del catalogo: ${miraiOnboardingFmt(values.catalog_freshness)}.`,
        `Si no hay coincidencia exacta: ${miraiOnboardingFmt(values.no_match_behavior)}.`,
      ].join("\n")
    : "En esta primera version no parece necesario que el agente envie propiedades automaticamente.";
  const handoffText = hasHandoff
    ? [
        "Momentos de derivacion:",
        miraiOnboardingList(miraiOnboardingValueWithOther(values, "handoff_moments", "handoff_moments_other")),
        "",
        `Asignacion: ${miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "advisor_assignment", "advisor_assignment_other"))}.`,
        `Contacto del asesor: ${miraiOnboardingFmt(values.advisor_reply_channel)}.`,
        `Fuera de horario: ${miraiOnboardingFmt(values.after_hours_behavior)}.`,
      ].join("\n")
    : "No se configuro derivacion a asesor para la primera version.";

  return `# Planos iniciales del agente

## Inmobiliaria
${miraiOnboardingFmt(values.agency_name)}
Contacto: ${miraiOnboardingFmt(values.contact_name_role)}
Email: ${miraiOnboardingFmt(values.email)}
WhatsApp: ${miraiOnboardingFmt(values.whatsapp)}

## Habilidades del agente
${miraiOnboardingList(miraiOnboardingValueWithOther(values, "agent_capabilities", "agent_capabilities_other"))}

## Canales
Entrada actual:
${miraiOnboardingList(miraiOnboardingValueWithOther(values, "lead_channels", "lead_channels_other"))}

Primera etapa:
${miraiOnboardingList(miraiOnboardingValueWithOther(values, "channels_to_connect", "channels_to_connect_other"))}

## Flujos incluidos
${miraiOnboardingList(answers.objectives.inferred_flows)}

## Datos que el agente va a pedir
Datos minimos:
${miraiOnboardingList(values.basic_data)}

Datos extra segun operacion:
${miraiOnboardingList(miraiOnboardingValueWithOther(values, "flow_specific_data", "flow_specific_data_other"))}

Nivel de calificacion: ${miraiOnboardingFmt(values.qualification_depth)} / 5.

## Propiedades y recomendaciones
${catalogText}

## Derivacion a asesores
${handoffText}

## Entrega de resumenes
${miraiOnboardingList(miraiOnboardingValueWithOther(values, "lead_summary_delivery", "lead_summary_delivery_other"))}

## Tono del agente
Estilo: ${miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "tone_style", "tone_style_other"))}.
Longitud de respuesta: ${miraiOnboardingFmt(values.response_length)} / 5.
Presentacion: ${miraiOnboardingFmt(values.bot_intro)}.

## Limites de comunicacion
${miraiOnboardingFmt(values.tone_limits, "A definir junto con Mirai")}

## Informacion pendiente
${missing.length ? miraiOnboardingList(missing) : "- No quedan campos requeridos pendientes."}

## Proximo paso
Mirai revisara este onboarding y preparara una propuesta ajustada a la operacion.`;
}

function miraiOnboardingBuildClientMarkdownBusiness(values) {
  const answers = miraiOnboardingCreateAnswers(values, "");
  const needsCatalog = miraiOnboardingNeedsCatalog(values);
  const hasHandoff = miraiOnboardingHasHandoff(values);
  const missing = miraiOnboardingVisibleValidationIssues(values);
  const catalogText = needsCatalog
    ? [
        `Fuente actual: ${miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "property_source", "property_source_other"))}.`,
        `Estado del catalogo: ${miraiOnboardingFmt(values.catalog_freshness)}.`,
        `Si no hay coincidencia exacta: ${miraiOnboardingFmt(values.no_match_behavior)}.`,
      ].join("\n")
    : "En esta primera version no parece necesario que el agente envie productos o servicios automaticamente.";
  const handoffText = hasHandoff
    ? [
        "Momentos de derivacion:",
        miraiOnboardingList(miraiOnboardingValueWithOther(values, "handoff_moments", "handoff_moments_other")),
        "",
        `Asignacion: ${miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "advisor_assignment", "advisor_assignment_other"))}.`,
        `Contacto del responsable: ${miraiOnboardingFmt(values.advisor_reply_channel)}.`,
        `Fuera de horario: ${miraiOnboardingFmt(values.after_hours_behavior)}.`,
      ].join("\n")
    : "No se configuro derivacion a una persona para la primera version.";

  return `# Planos iniciales del agente

## Empresa
${miraiOnboardingFmt(values.agency_name)}
Contacto: ${miraiOnboardingFmt(values.contact_name_role)}
Email: ${miraiOnboardingFmt(values.email)}
WhatsApp: ${miraiOnboardingFmt(values.whatsapp)}

## Habilidades del agente
${miraiOnboardingList(miraiOnboardingValueWithOther(values, "agent_capabilities", "agent_capabilities_other"))}

## Canales
Entrada actual:
${miraiOnboardingList(miraiOnboardingValueWithOther(values, "lead_channels", "lead_channels_other"))}

Primera etapa:
${miraiOnboardingList(miraiOnboardingValueWithOther(values, "channels_to_connect", "channels_to_connect_other"))}

## Flujos incluidos
${miraiOnboardingList(answers.objectives.inferred_flows)}

## Datos que el agente va a pedir
Datos minimos:
${miraiOnboardingList(values.basic_data)}

Datos extra segun consulta:
${miraiOnboardingList(miraiOnboardingValueWithOther(values, "flow_specific_data", "flow_specific_data_other"))}

Nivel de calificacion: ${miraiOnboardingFmt(values.qualification_depth)} / 5.

## Productos, servicios y recomendaciones
${catalogText}

## Derivacion a una persona
${handoffText}

## Entrega de resumenes
${miraiOnboardingList(miraiOnboardingValueWithOther(values, "lead_summary_delivery", "lead_summary_delivery_other"))}

## Tono del agente
Estilo: ${miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "tone_style", "tone_style_other"))}.
Longitud de respuesta: ${miraiOnboardingFmt(values.response_length)} / 5.
Presentacion: ${miraiOnboardingFmt(values.bot_intro)}.

## Limites de comunicacion
${miraiOnboardingFmt(values.tone_limits, "A definir junto con Mirai")}

## Informacion pendiente
${missing.length ? miraiOnboardingList(missing) : "- No quedan campos requeridos pendientes."}

## Proximo paso
Mirai revisara este onboarding y preparara una propuesta ajustada a la operacion.`;
}

function miraiOnboardingBuildClientMarkdown(values) {
  return miraiOnboardingIsBusiness(values)
    ? miraiOnboardingBuildClientMarkdownBusiness(values)
    : miraiOnboardingBuildClientMarkdownRealEstate(values);
}

function miraiOnboardingBuildInternalMarkdownRealEstate(values) {
  const answers = miraiOnboardingCreateAnswers(values, "");
  const hasHandoff = miraiOnboardingHasHandoff(values);
  const futureChannels = miraiOnboardingFutureChannels(values);
  const futureChannelText = futureChannels.length
    ? `Canales adicionales seleccionados: ${futureChannels.join(", ")}. Considerar complejidad adicional o fase futura si el alcance inicial prioriza WhatsApp.`
    : "Sin canales adicionales declarados para fase futura.";
  const handoffText = hasHandoff
    ? [
        `Momentos: ${miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "handoff_moments", "handoff_moments_other"))}`,
        `Asignacion: ${miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "advisor_assignment", "advisor_assignment_other"))}`,
        `Canal de contacto del asesor: ${miraiOnboardingFmt(values.advisor_reply_channel)}`,
        `Fuera de horario: ${miraiOnboardingFmt(values.after_hours_behavior)}`,
      ].join("\n")
    : "Sin derivacion humana en la primera version.";

  return `# Agente de WhatsApp - ${miraiOnboardingFmt(values.agency_name, "Inmobiliaria")}

## Resumen del proyecto
Cliente: ${miraiOnboardingFmt(values.agency_name)}
Contacto: ${miraiOnboardingFmt(values.contact_name_role)}
Zonas: ${miraiOnboardingFmt(values.zones)}
Volumen de leads: ${miraiOnboardingFmt(values.lead_volume)}

## Problemas a resolver
${miraiOnboardingList(miraiOnboardingValueWithOther(values, "pain_points", "pain_points_other"))}

## Habilidades del agente
${miraiOnboardingList(miraiOnboardingValueWithOther(values, "agent_capabilities", "agent_capabilities_other"))}

## Canales
Entrada actual:
${miraiOnboardingList(miraiOnboardingValueWithOther(values, "lead_channels", "lead_channels_other"))}

Primera etapa:
${miraiOnboardingList(miraiOnboardingValueWithOther(values, "channels_to_connect", "channels_to_connect_other"))}
${futureChannelText}

## Flujos conversacionales inferidos
${answers.flows.length ? answers.flows.map((f) => `- ${f.type}: version inicial=${f.first_version}, handoff=${f.ask_before_handoff}, envia propiedades=${f.can_send_properties}`).join("\n") : "- A definir"}

## Datos a capturar
Minimos:
${miraiOnboardingList(values.basic_data)}

Extra por operacion:
${miraiOnboardingList(miraiOnboardingValueWithOther(values, "flow_specific_data", "flow_specific_data_other"))}

## Catalogo de propiedades
Fuente: ${miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "property_source", "property_source_other"))}
Actualizacion: ${miraiOnboardingFmt(values.catalog_freshness)}
Campos disponibles: ${miraiOnboardingFmt(values.property_fields)}

## Reglas de recomendacion
Puede enviar automaticamente: ${miraiOnboardingDerivedCanSendProperties(values)}
Sin match exacto: ${miraiOnboardingNeedsCatalog(values) ? miraiOnboardingFmt(values.no_match_behavior) : "Catalogo no requerido en v1."}
Prioridad: ${miraiOnboardingFmt(values.recommendation_priority)}

## Derivacion humana
${handoffText}

## Entrega de resumenes
Destino: ${miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "lead_summary_delivery", "lead_summary_delivery_other"))}
Contenido: generado automaticamente desde datos capturados y conversacion.

## Tono conversacional
Estilo: ${miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "tone_style", "tone_style_other"))}
Profundidad de respuesta: ${miraiOnboardingFmt(values.response_length)} / 5
Una pregunta por vez: ${miraiOnboardingFmt(answers.tone.one_question_at_time)}
Presentacion: ${miraiOnboardingFmt(values.bot_intro)}
Disclosure IA: ${miraiOnboardingFmt(values.disclose_ai)}
Limites y frases: ${miraiOnboardingFmt(values.tone_limits)}

## Integraciones
Usa CRM: ${miraiOnboardingFmt(values.uses_crm)}
CRM: ${miraiOnboardingFmt(values.crm_name)}
Acepta Google Sheets: ${miraiOnboardingFmt(values.accepts_sheets)}
Crear registros: ${miraiOnboardingFmt(answers.integrations.auto_create_records)}
Historial: ${miraiOnboardingFmt(answers.integrations.save_conversation_history)}
Owner tecnico: ${miraiOnboardingFmt(answers.integrations.technical_owner)}

## Informacion faltante
${miraiOnboardingVisibleValidationIssues(values).length ? miraiOnboardingList(miraiOnboardingVisibleValidationIssues(values)) : "- Sin pendientes requeridos."}

---

# Implementacion Mirai

## Data Schema
\`\`\`json
${JSON.stringify(answers, null, 2)}
\`\`\`

## Conditional Logic
- Catalogo visible si las habilidades o tipos de consulta requieren propiedades.
- Derivacion visible solo si las habilidades incluyen derivar a asesor.
- CRM name visible solo si usa CRM.
- Google Sheets visible solo si no usa CRM.
- Campos Otro visibles solo cuando se selecciona Otro.
- Flujos conversacionales inferidos desde tipos de consulta y habilidades del agente.

## Handoff Rules
${hasHandoff ? miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "handoff_moments", "handoff_moments_other")) : "No aplica en v1."}

## Catalog Rules
${miraiOnboardingNeedsCatalog(values) ? miraiOnboardingFmt(values.no_match_behavior) : "Catalogo no requerido en v1."}

## Prompt Notes
- Mantener tono ${miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "tone_style", "tone_style_other")).toLowerCase()}.
- Respuestas con profundidad ${miraiOnboardingFmt(values.response_length)} / 5.
- Capturar datos de a una pregunta cuando la calificacion sea media o alta.

## Technical Risks
- Confirmar fuente real de propiedades y freshness antes de automatizar recomendaciones.
- Validar permisos de CRM o Google Sheets antes de go-live.
- Revisar reglas de handoff solo si el cliente quiere derivacion humana.
- Revisar canales adicionales si se conectan Instagram, web chat, Facebook u otros.

## Open Questions
${miraiOnboardingVisibleValidationIssues(values).length ? miraiOnboardingList(miraiOnboardingVisibleValidationIssues(values)) : "- Revisar detalles finos de implementacion con el equipo Mirai."}`;
}

function miraiOnboardingBuildInternalMarkdownBusiness(values) {
  const answers = miraiOnboardingCreateAnswers(values, "");
  const hasHandoff = miraiOnboardingHasHandoff(values);
  const futureChannels = miraiOnboardingFutureChannels(values);
  const futureChannelText = futureChannels.length
    ? `Canales adicionales seleccionados: ${futureChannels.join(", ")}. Considerar complejidad adicional o fase futura si el alcance inicial prioriza WhatsApp.`
    : "Sin canales adicionales declarados para fase futura.";
  const handoffText = hasHandoff
    ? [
        `Momentos: ${miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "handoff_moments", "handoff_moments_other"))}`,
        `Asignacion: ${miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "advisor_assignment", "advisor_assignment_other"))}`,
        `Canal de contacto del responsable: ${miraiOnboardingFmt(values.advisor_reply_channel)}`,
        `Fuera de horario: ${miraiOnboardingFmt(values.after_hours_behavior)}`,
      ].join("\n")
    : "Sin derivacion humana en la primera version.";

  return `# Agente de WhatsApp - ${miraiOnboardingFmt(values.agency_name, "Empresa")}

## Resumen del proyecto
Cliente: ${miraiOnboardingFmt(values.agency_name)}
Contacto: ${miraiOnboardingFmt(values.contact_name_role)}
Rubro y alcance: ${miraiOnboardingFmt(values.zones)}
Volumen de leads: ${miraiOnboardingFmt(values.lead_volume)}

## Problemas a resolver
${miraiOnboardingList(miraiOnboardingValueWithOther(values, "pain_points", "pain_points_other"))}

## Habilidades del agente
${miraiOnboardingList(miraiOnboardingValueWithOther(values, "agent_capabilities", "agent_capabilities_other"))}

## Canales
Entrada actual:
${miraiOnboardingList(miraiOnboardingValueWithOther(values, "lead_channels", "lead_channels_other"))}

Primera etapa:
${miraiOnboardingList(miraiOnboardingValueWithOther(values, "channels_to_connect", "channels_to_connect_other"))}
${futureChannelText}

## Flujos conversacionales inferidos
${answers.flows.length ? answers.flows.map((f) => `- ${f.type}: version inicial=${f.first_version}, handoff=${f.ask_before_handoff}, envia catalogo=${f.can_send_properties}`).join("\n") : "- A definir"}

## Datos a capturar
Minimos:
${miraiOnboardingList(values.basic_data)}

Extra por tipo de consulta:
${miraiOnboardingList(miraiOnboardingValueWithOther(values, "flow_specific_data", "flow_specific_data_other"))}

## Catalogo de productos/servicios
Fuente: ${miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "property_source", "property_source_other"))}
Actualizacion: ${miraiOnboardingFmt(values.catalog_freshness)}
Campos disponibles: ${miraiOnboardingFmt(values.property_fields)}

## Reglas de recomendacion
Puede enviar automaticamente: ${miraiOnboardingDerivedCanSendProperties(values)}
Sin match exacto: ${miraiOnboardingNeedsCatalog(values) ? miraiOnboardingFmt(values.no_match_behavior) : "Catalogo no requerido en v1."}
Prioridad: ${miraiOnboardingFmt(values.recommendation_priority)}

## Derivacion humana
${handoffText}

## Entrega de resumenes
Destino: ${miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "lead_summary_delivery", "lead_summary_delivery_other"))}
Contenido: generado automaticamente desde datos capturados y conversacion.

## Tono conversacional
Estilo: ${miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "tone_style", "tone_style_other"))}
Profundidad de respuesta: ${miraiOnboardingFmt(values.response_length)} / 5
Una pregunta por vez: ${miraiOnboardingFmt(answers.tone.one_question_at_time)}
Presentacion: ${miraiOnboardingFmt(values.bot_intro)}
Disclosure IA: ${miraiOnboardingFmt(values.disclose_ai)}
Limites y frases: ${miraiOnboardingFmt(values.tone_limits)}

## Integraciones
Usa CRM: ${miraiOnboardingFmt(values.uses_crm)}
CRM: ${miraiOnboardingFmt(values.crm_name)}
Acepta Google Sheets: ${miraiOnboardingFmt(values.accepts_sheets)}
Crear registros: ${miraiOnboardingFmt(answers.integrations.auto_create_records)}
Historial: ${miraiOnboardingFmt(answers.integrations.save_conversation_history)}
Owner tecnico: ${miraiOnboardingFmt(answers.integrations.technical_owner)}

## Informacion faltante
${miraiOnboardingVisibleValidationIssues(values).length ? miraiOnboardingList(miraiOnboardingVisibleValidationIssues(values)) : "- Sin pendientes requeridos."}

---

# Implementacion Mirai

## Data Schema
\`\`\`json
${JSON.stringify(answers, null, 2)}
\`\`\`

## Conditional Logic
- Catalogo visible si las habilidades o tipos de consulta requieren productos o servicios.
- Derivacion visible solo si las habilidades incluyen derivar a un humano.
- CRM name visible solo si usa CRM.
- Google Sheets visible solo si no usa CRM.
- Campos Otro visibles solo cuando se selecciona Otro.
- Flujos conversacionales inferidos desde tipos de consulta y habilidades del agente.

## Handoff Rules
${hasHandoff ? miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "handoff_moments", "handoff_moments_other")) : "No aplica en v1."}

## Catalog Rules
${miraiOnboardingNeedsCatalog(values) ? miraiOnboardingFmt(values.no_match_behavior) : "Catalogo no requerido en v1."}

## Prompt Notes
- Mantener tono ${miraiOnboardingFmt(miraiOnboardingValueWithOther(values, "tone_style", "tone_style_other")).toLowerCase()}.
- Respuestas con profundidad ${miraiOnboardingFmt(values.response_length)} / 5.
- Capturar datos de a una pregunta cuando la calificacion sea media o alta.

## Technical Risks
- Confirmar fuente real de productos/servicios y freshness antes de automatizar recomendaciones.
- Validar permisos de CRM o Google Sheets antes de go-live.
- Revisar reglas de handoff solo si el cliente quiere derivacion humana.
- Revisar canales adicionales si se conectan Instagram, web chat, Facebook u otros.

## Open Questions
${miraiOnboardingVisibleValidationIssues(values).length ? miraiOnboardingList(miraiOnboardingVisibleValidationIssues(values)) : "- Revisar detalles finos de implementacion con el equipo Mirai."}`;
}

function miraiOnboardingBuildInternalMarkdown(values) {
  return miraiOnboardingIsBusiness(values)
    ? miraiOnboardingBuildInternalMarkdownBusiness(values)
    : miraiOnboardingBuildInternalMarkdownRealEstate(values);
}

function miraiOnboardingBuildPayload(values) {
  const submittedAt = new Date().toISOString();
  const answers = miraiOnboardingCreateAnswers(values, submittedAt);
  const clientPreviewMarkdown = miraiOnboardingBuildClientMarkdown(values);
  const internalBotMarkdown = miraiOnboardingBuildInternalMarkdown(values);
  return { answers, clientPreviewMarkdown, internalBotMarkdown };
}

Object.assign(window, {
  miraiOnboardingBaseAnswers,
  miraiOnboardingIsBusiness,
  miraiOnboardingInitialValues,
  miraiOnboardingIsEmpty,
  miraiOnboardingMatchesRule,
  miraiOnboardingVisibleSections,
  miraiOnboardingVisibleQuestions,
  miraiOnboardingValidateQuestion,
  miraiOnboardingSectionComplete,
  miraiOnboardingSectionErrors,
  miraiOnboardingVisibleRequiredMissing,
  miraiOnboardingCreateAnswers,
  miraiOnboardingBlueprintItems,
  miraiOnboardingBuildClientMarkdown,
  miraiOnboardingBuildInternalMarkdown,
  miraiOnboardingBuildPayload,
});
