const form = document.getElementById("yesPathForm");
const goalInput = document.getElementById("goal");
const audienceInput = document.getElementById("audience");
const situationInput = document.getElementById("situation");
const benefitInput = document.getElementById("benefit");
const objectionInput = document.getElementById("objection");
const toneInput = document.getElementById("tone");
const scoreValue = document.getElementById("scoreValue");
const scoreLabel = document.getElementById("scoreLabel");
const scoreHint = document.getElementById("scoreHint");
const scoreRing = document.getElementById("scoreRing");
const generatedMessage = document.getElementById("generatedMessage");
const messageTitle = document.getElementById("messageTitle");
const copyButton = document.getElementById("copyButton");
const copyStatus = document.getElementById("copyStatus");
const errorBanner = document.getElementById("errorBanner");
const objectionSummary = document.getElementById("objectionSummary");
const objectionResponse = document.getElementById("objectionResponse");
const resetButton = document.getElementById("resetForm");

const templates = {
  sales: {
    goal: "I want the prospect to book a quick discovery call.",
    audience: "a potential customer",
    situation: "They showed interest but have not taken the next step yet.",
    benefit: "They get a simple, practical plan without committing to a long process.",
    objection: "They may think they are too busy right now.",
    tone: "sales-focused",
  },
  "follow-up": {
    goal: "I want them to reply with a yes or no on the next step.",
    audience: "a warm lead",
    situation: "We spoke recently and the conversation went quiet.",
    benefit: "They can move forward without losing context or momentum.",
    objection: "They may feel unsure or overwhelmed by timing.",
    tone: "friendly",
  },
  approval: {
    goal: "I want the client to approve the proposal and next milestone.",
    audience: "an existing client",
    situation: "The work is ready for review and I need confirmation to move ahead.",
    benefit: "They can keep the project on schedule and avoid delays.",
    objection: "They may worry about scope or cost.",
    tone: "professional",
  },
  career: {
    goal: "I want my manager to discuss a raise and expanded responsibility.",
    audience: "my manager",
    situation: "I have taken on more impact and want to talk about growth.",
    benefit: "They retain a stronger contributor and support team stability.",
    objection: "They may think timing or budget is difficult.",
    tone: "confident",
  },
  collaboration: {
    goal: "I want them to explore a collaboration together.",
    audience: "a creator or partner",
    situation: "Our audiences and strengths overlap in a useful way.",
    benefit: "We can create something valuable for both audiences with shared effort.",
    objection: "They may be unsure whether it is worth their time.",
    tone: "warm",
  },
};

const toneProfiles = {
  friendly: {
    greeting: (audience) => buildGreeting("Hi", audience),
    empathy: (situation) => `I know ${situation}.`,
    ask: (goal) => `I wanted to reach out with a simple ask: ${capitalize(goal)}.`,
    benefit: (benefit) => `The reason I think this could be helpful is that ${benefit}.`,
    trust: () => "I’d keep it simple and easy from your side.",
    closing: (cta) => cta,
    title: "Friendly Yes Path",
  },
  professional: {
    greeting: (audience) => buildGreeting("Hello", audience),
    empathy: (situation) => `I understand that ${situation}.`,
    ask: (goal) => `I’m reaching out with a clear request: ${capitalize(goal)}.`,
    benefit: (benefit) => `This would be valuable because ${benefit}.`,
    trust: () => "I’m aiming to make the process clear, efficient, and low-friction.",
    closing: (cta) => cta,
    title: "Professional Yes Path",
  },
  confident: {
    greeting: (audience) => buildGreeting("Hi", audience),
    empathy: (situation) => `Given that ${situation}, I wanted to be direct.`,
    ask: (goal) => `I believe the right next step is clear: ${capitalize(goal)}.`,
    benefit: (benefit) => `That creates value because ${benefit}.`,
    trust: () => "There’s a practical way to do this without adding unnecessary complexity.",
    closing: (cta) => cta,
    title: "Confident Yes Path",
  },
  direct: {
    greeting: (audience) => buildGreeting("Hi", audience),
    empathy: (situation) => `I know ${situation}.`,
    ask: (goal) => `My ask is simple: ${capitalize(goal)}.`,
    benefit: (benefit) => `It makes sense because ${benefit}.`,
    trust: () => "We can keep the next step small and clear.",
    closing: (cta) => cta,
    title: "Direct Yes Path",
  },
  warm: {
    greeting: (audience) => buildGreeting("Hi", audience),
    empathy: (situation) => `I appreciate that ${situation}.`,
    ask: (goal) => `With that in mind, here’s the next step I’d love to suggest: ${capitalize(goal)}.`,
    benefit: (benefit) => `I think it could genuinely help because ${benefit}.`,
    trust: () => "I’d want this to feel easy, thoughtful, and worthwhile for you.",
    closing: (cta) => cta,
    title: "Warm Yes Path",
  },
  short: {
    greeting: (audience) => buildGreeting("Hi", audience),
    empathy: (situation) => `I know ${situation}.`,
    ask: (goal) => `Here’s the ask: ${capitalize(goal)}.`,
    benefit: (benefit) => `It helps because ${benefit}.`,
    trust: () => "Happy to keep it simple.",
    closing: (cta) => cta,
    title: "Short Yes Path",
  },
  "sales-focused": {
    greeting: (audience) => buildGreeting("Hi", audience),
    empathy: (situation) => `I understand that ${situation}.`,
    ask: (goal) => `Here’s the next step I’d like to propose: ${capitalize(goal)}.`,
    benefit: (benefit) => `The upside for you is that ${benefit}.`,
    trust: () => "This is designed to be straightforward, low-risk, and useful right away.",
    closing: (cta) => cta,
    title: "Sales-Focused Yes Path",
  },
};

const ctas = {
  friendly: [
    "Would you be open to a quick 10-minute chat?",
    "Would it help if I sent over a simple next step?",
  ],
  professional: [
    "Would you be open to confirming the next step this week?",
    "Can I send over the simplest option for moving forward?",
  ],
  confident: [
    "Can we move forward with this today?",
    "Would you be open to locking in the next step now?",
  ],
  direct: [
    "Does this sound good to you?",
    "Can I send the next step today?",
  ],
  warm: [
    "Would you be open to exploring this together?",
    "If it feels helpful, can I send the next step?",
  ],
  short: [
    "Open to a quick yes or no?",
    "Can we take the next step?",
  ],
  "sales-focused": [
    "Would you be open to a quick 10-minute call?",
    "Can I send you the best next option today?",
  ],
};

let appState = {
  hasGenerated: false,
  improvements: [],
  lastData: null,
  currentMessage: "",
};

function capitalize(value) {
  if (!value) return value;
  return value.charAt(0).toUpperCase() + value.slice(1);
}

function buildGreeting(starter, audience) {
  if (!audience) return `${starter} there,`;

  const normalized = audience.trim();
  const genericAudiencePattern = /^(a|an|the|my|our|their|this|that)\b/i;
  const rolePattern = /\b(client|customer|manager|lead|partner|prospect|team|audience|creator)\b/i;

  if (genericAudiencePattern.test(normalized) || rolePattern.test(normalized)) {
    return `${starter},`;
  }

  return `${starter} ${normalized},`;
}

function pickCta(tone, variantIndex = 0) {
  const options = ctas[tone] || ctas.professional;
  return options[Math.min(variantIndex, options.length - 1)];
}

function getFormData() {
  return {
    goal: goalInput.value.trim(),
    audience: audienceInput.value.trim(),
    situation: situationInput.value.trim(),
    benefit: benefitInput.value.trim(),
    objection: objectionInput.value.trim(),
    tone: toneInput.value,
  };
}

function validateInputs(data) {
  const errors = [];

  if (!data.goal) errors.push("Add your goal first.");
  if (!data.audience) errors.push("Tell us who you are asking.");
  if (!data.benefit) errors.push("Add one clear benefit.");
  if (!data.tone) errors.push("Choose a tone.");

  return errors;
}

function calculateScore(data) {
  let score = 14;

  if (data.goal) score += 18;
  if (data.audience) score += 14;
  if (data.situation) score += 14;
  if (data.benefit) score += 18;
  if (data.objection) score += 12;
  if (data.tone) score += 12;

  if (data.goal && data.benefit) score += 6;
  if (data.situation && data.objection) score += 6;

  return Math.min(score, 100);
}

function scoreStatus(score) {
  if (score >= 85) {
    return {
      label: "Strong path to yes",
      hint: "You’ve covered the ask, the value, and the likely friction well.",
    };
  }

  if (score >= 65) {
    return {
      label: "Promising path",
      hint: "Good foundation. Add more detail or reduce friction to strengthen it.",
    };
  }

  return {
    label: "Needs a clearer path",
    hint: "Tighten the ask, the benefit, or the objection handling before sending.",
  };
}

function handleObjection(objection, benefit, situation) {
  if (!objection) {
    return "If you add a likely objection, we’ll suggest a calmer response that lowers resistance.";
  }

  const normalized = objection.toLowerCase();

  if (normalized.includes("expensive") || normalized.includes("budget") || normalized.includes("price")) {
    return `I understand budget matters. The reason this can still be valuable is that ${benefit || "it reduces wasted time and helps avoid having to redo work later"}.`;
  }

  if (normalized.includes("busy") || normalized.includes("time") || normalized.includes("timing")) {
    return `I understand timing may be tight. That’s why I’m suggesting a simple next step that respects your schedule while still helping with ${situation || "the current situation"}.`;
  }

  if (normalized.includes("trust") || normalized.includes("unsure") || normalized.includes("uncertain")) {
    return "That makes sense. I’m happy to keep the next step small, transparent, and easy to evaluate so you can decide with more confidence.";
  }

  if (normalized.includes("priority") || normalized.includes("later")) {
    return "I understand this may not feel urgent right now. Even a small next step can help keep momentum without creating a heavy commitment.";
  }

  return `That makes sense. I’d frame it this way: I understand the concern about ${objection.toLowerCase()}. The reason it may still be worth considering is that ${benefit || "it creates a practical upside without a complicated next step"}.`;
}

function buildRiskReducer(data) {
  if (!data.objection) {
    return "To make this easy, we can keep the next step simple and low-pressure.";
  }

  const normalized = data.objection.toLowerCase();

  if (normalized.includes("price") || normalized.includes("budget") || normalized.includes("expensive")) {
    return "To reduce risk, we can start with the simplest option before making a bigger commitment.";
  }

  if (normalized.includes("time") || normalized.includes("busy") || normalized.includes("timing")) {
    return "To keep this easy, the next step can be short and fit around your schedule.";
  }

  if (normalized.includes("trust") || normalized.includes("unsure") || normalized.includes("uncertain")) {
    return "To make this easier, I can share a clear outline so you know exactly what to expect.";
  }

  return "To make this easier, we can keep the next step simple and easy to evaluate.";
}

function applyImprovements(message, data, tone) {
  let nextMessage = message;

  if (appState.improvements.includes("shorter")) {
    nextMessage = nextMessage
      .replace(/\n\n/g, "\n")
      .replace("I’m aiming to make the process clear, efficient, and low-friction.\n", "")
      .replace("I’d want this to feel easy, thoughtful, and worthwhile for you.\n", "")
      .replace("This is designed to be straightforward, low-risk, and useful right away.\n", "");
  }

  if (appState.improvements.includes("confident")) {
    nextMessage += "\n\nI’m confident this is the most practical next step.";
  }

  if (appState.improvements.includes("warmer")) {
    nextMessage = nextMessage.replace(/\n\nWould/, "\n\nI appreciate your time and consideration.\n\nWould");
  }

  if (appState.improvements.includes("urgency")) {
    nextMessage += "\n\nIf timing works on your side, moving on this soon would help keep momentum.";
  }

  if (appState.improvements.includes("objection") && data.objection) {
    nextMessage += `\n\nI also understand the concern about ${data.objection.toLowerCase()}, and I believe there’s a practical way to handle that without adding extra pressure.`;
  }

  if (appState.improvements.includes("cta")) {
    nextMessage = nextMessage.replace(pickCta(tone, 0), pickCta(tone, 1));
  }

  return nextMessage;
}

function generateMessage(data = getFormData()) {
  const tone = data.tone || "professional";
  const profile = toneProfiles[tone] || toneProfiles.professional;
  const cta = pickCta(tone, 0);
  const objectionReply = handleObjection(data.objection, data.benefit, data.situation);
  const riskReducer = buildRiskReducer(data);

  const pieces = [
    profile.greeting(data.audience || "there"),
    "",
    profile.empathy(data.situation || "this has a few moving parts"),
    profile.ask(data.goal || "take the next step"),
    profile.benefit(data.benefit || "it creates a clear, useful outcome"),
    profile.trust(),
    riskReducer,
    data.objection ? objectionReply : "",
    "",
    profile.closing(cta),
  ].filter(Boolean);

  let message = pieces.join("\n");
  message = applyImprovements(message, data, tone);

  appState.currentMessage = message;
  appState.lastData = data;
  appState.hasGenerated = true;

  return {
    title: profile.title,
    message,
    objectionReply,
  };
}

function renderResult(data) {
  const score = calculateScore(data);
  const status = scoreStatus(score);
  const { title, message, objectionReply } = generateMessage(data);

  scoreValue.textContent = score;
  scoreRing.style.setProperty("--score-angle", `${(score / 100) * 360}deg`);
  scoreLabel.textContent = `${score} / 100 • ${status.label}`;
  scoreHint.textContent = status.hint;
  messageTitle.textContent = title;
  generatedMessage.textContent = message;
  generatedMessage.classList.remove("empty-state");
  objectionSummary.textContent = data.objection
    ? `Likely objection: ${data.objection}`
    : "No objection provided yet.";
  objectionResponse.textContent = `“${objectionReply}”`;
}

function showErrors(errors) {
  if (!errors.length) {
    errorBanner.hidden = true;
    errorBanner.textContent = "";
    return;
  }

  errorBanner.hidden = false;
  errorBanner.textContent = errors.join(" ");
}

function changeTone(nextTone) {
  toneInput.value = nextTone;
  if (!appState.hasGenerated) return;
  const data = getFormData();
  renderResult(data);
}

function copyMessage() {
  if (!appState.currentMessage) {
    copyStatus.textContent = "Generate a message first so there’s something to copy.";
    return;
  }

  navigator.clipboard
    .writeText(appState.currentMessage)
    .then(() => {
      copyStatus.textContent = "Copied! Your message is ready to send.";
    })
    .catch(() => {
      copyStatus.textContent = "Copy didn’t work here. You can still select the message manually.";
    });
}

function loadTemplate(templateName) {
  const template = templates[templateName];
  if (!template) return;

  goalInput.value = template.goal;
  audienceInput.value = template.audience;
  situationInput.value = template.situation;
  benefitInput.value = template.benefit;
  objectionInput.value = template.objection;
  toneInput.value = template.tone;
  appState.improvements = [];
  copyStatus.textContent = "Template loaded. Adjust anything you want, then generate.";
  showErrors([]);
  renderResult(getFormData());
  document.getElementById("builder").scrollIntoView({ behavior: "smooth", block: "start" });
}

function improveMessage(type) {
  if (!appState.hasGenerated) {
    copyStatus.textContent = "Generate a message first, then use the improvement tools.";
    return;
  }

  if (!appState.improvements.includes(type)) {
    appState.improvements.push(type);
  }

  renderResult(getFormData());
  copyStatus.textContent = `${capitalize(type)} update applied.`;
}

form.addEventListener("submit", (event) => {
  event.preventDefault();
  const data = getFormData();
  const errors = validateInputs(data);

  if (errors.length) {
    showErrors(errors);
    return;
  }

  showErrors([]);
  copyStatus.textContent = "";
  appState.improvements = [];
  renderResult(data);
});

toneInput.addEventListener("change", (event) => {
  if (!event.target.value) return;
  changeTone(event.target.value);
});

copyButton.addEventListener("click", copyMessage);

document.querySelectorAll("[data-template]").forEach((button) => {
  button.addEventListener("click", () => {
    loadTemplate(button.dataset.template);
  });
});

document.querySelectorAll("[data-improve]").forEach((button) => {
  button.addEventListener("click", () => {
    improveMessage(button.dataset.improve);
  });
});

resetButton.addEventListener("click", () => {
  form.reset();
  appState = {
    hasGenerated: false,
    improvements: [],
    lastData: null,
    currentMessage: "",
  };
  showErrors([]);
  copyStatus.textContent = "";
  scoreValue.textContent = "0";
  scoreRing.style.setProperty("--score-angle", "0deg");
  scoreLabel.textContent = "Your Yes Path will appear here.";
  scoreHint.textContent = "Fill in your goal, audience, and benefit to generate a stronger message.";
  messageTitle.textContent = "No message yet";
  generatedMessage.textContent = "Your Yes Path will appear here.";
  generatedMessage.classList.add("empty-state");
  objectionSummary.textContent = "Add an objection in the form and we’ll suggest a respectful response.";
  objectionResponse.textContent =
    "“I understand budget matters. The reason this can still be valuable is that it helps you save time, avoid mistakes, and get a stronger result without needing to redo the work later.”";
});
