// Shared checkout state + Stripe wiring.
// Used by both CheckoutC (desktop) and CheckoutCMobile.
// The hook owns: plan, all form fields, the Stripe instance + Elements,
// submit handling, error state. It exposes everything the layouts need.

const RETURN_URLS = {
  "2yr": "https://homesalelegalprotection.com/thank-you-2year/",
  "4yr": "https://homesalelegalprotection.com/thank-you-4-year-home-sale-legal-protection/",
};

const plansData = {
  "2yr": {
    termLong: "2-Year",
    title: "2-Year Plan",
    coverage: 75000,
    price: 32900,
    listPrice: 70000,
    save: 37100,
    badge: { label: "BEST VALUE", tone: "green" },
    bullets: [
      "Up to $75,000 in legal defense covered",
      "Paid expert attorney provided in 24–48 hrs",
      "100% refundable if your home doesn't sell",
    ],
  },
  "4yr": {
    termLong: "4-Year",
    title: "4-Year Plan",
    coverage: 75000,
    price: 102900,
    listPrice: 210000,
    save: 107100,
    badge: { label: "MAX PROTECTION", tone: "dark" },
    bullets: [
      "Up to $75,000 in legal defense covered",
      "Paid expert attorney provided in 24–48 hrs",
      "4 full years of post-sale coverage",
    ],
  },
};

const disputeTypes = [
  { icon: "roof", label: "Roof & structural" },
  { icon: "foundation", label: "Foundation" },
  { icon: "droplet", label: "Flooding & water" },
  { icon: "bolt", label: "Electrical" },
  { icon: "thermostat", label: "HVAC & plumbing" },
  { icon: "mold", label: "Mold & mildew" },
];

const API = () => window.API_BASE || "";

// Validates the buyer-facing form fields. Stripe handles its own validation
// inside PaymentElement.
function validateForm(s) {
  if (!s.firstName.trim())    return "First name is required";
  if (!s.lastName.trim())     return "Last name is required";
  if (!s.email.trim() || !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(s.email)) return "Valid email is required";
  if (!s.propertyLine1.trim()) return "Street address is required";
  if (!s.propertyCity.trim())  return "City is required";
  if (!s.propertyState.trim()) return "State is required";
  if (!/^\d{5}(-\d{4})?$/.test(s.propertyZip.trim())) return "Valid ZIP is required";
  return null;
}

function useCheckout() {
  const [plan, setPlan] = React.useState("4yr");
  const [firstName, setFirstName] = React.useState("");
  const [lastName, setLastName] = React.useState("");
  const [email, setEmail] = React.useState("");
  const [phone, setPhone] = React.useState("");
  const [agentEmail, setAgentEmail] = React.useState("");
  const [propertyLine1, setPropertyLine1] = React.useState("");
  const [propertyCity, setPropertyCity] = React.useState("");
  const [propertyState, setPropertyState] = React.useState("");
  const [propertyZip, setPropertyZip] = React.useState("");

  const [paymentIntentId, setPaymentIntentId] = React.useState(null);
  const [paymentReady, setPaymentReady] = React.useState(false);
  const [submitting, setSubmitting] = React.useState(false);
  const [error, setError] = React.useState(null);

  const stripeRef = React.useRef(null);
  const elementsRef = React.useRef(null);
  const mountSelectorRef = React.useRef(null);

  // Init Stripe instance once
  React.useEffect(() => {
    if (!window.Stripe) {
      setError("Stripe.js failed to load");
      return;
    }
    if (!window.STRIPE_PUBLISHABLE_KEY || window.STRIPE_PUBLISHABLE_KEY.includes("REPLACE")) {
      setError("Stripe publishable key not configured (set window.STRIPE_PUBLISHABLE_KEY)");
      return;
    }
    stripeRef.current = window.Stripe(window.STRIPE_PUBLISHABLE_KEY);
  }, []);

  const piIdRef = React.useRef(null);
  const initedRef = React.useRef(false);

  // Create the PaymentIntent + mount the PaymentElement — EXACTLY ONCE.
  // (Stripe allows only one Element of type "payment" per elements instance,
  // so we never create a second one; plan changes re-price via fetchUpdates.)
  React.useEffect(() => {
    if (!stripeRef.current || initedRef.current) return;
    initedRef.current = true;
    let cancelled = false;

    (async () => {
      try {
        setError(null);
        const r = await fetch(`${API()}/api/create-payment-intent`, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ plan }),
        });
        const data = await r.json();
        if (!r.ok) throw new Error(data.error || "Failed to create payment intent");
        if (cancelled) return;

        piIdRef.current = data.paymentIntentId;
        setPaymentIntentId(data.paymentIntentId);

        const elements = stripeRef.current.elements({
          clientSecret: data.clientSecret,
          appearance: {
            theme: "stripe",
            variables: {
              colorPrimary: "#1a3a5c",
              colorBackground: "#ffffff",
              colorText: "#1a2a4a",
              colorDanger: "#c2410c",
              borderRadius: "10px",
              fontFamily: "Inter Tight, -apple-system, BlinkMacSystemFont, sans-serif",
              spacingUnit: "4px",
            },
          },
        });
        elementsRef.current = elements;

        const target = mountSelectorRef.current || "#stripe-payment-element";
        elements.create("payment").mount(target);
        setPaymentReady(true);
      } catch (e) {
        if (!cancelled) { setError(e.message); initedRef.current = false; }
      }
    })();

    return () => { cancelled = true; };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // Re-price the existing PaymentIntent when the plan changes — NO remount.
  React.useEffect(() => {
    if (!piIdRef.current || !elementsRef.current) return; // not initialized yet
    let cancelled = false;
    (async () => {
      try {
        setError(null);
        const r = await fetch(`${API()}/api/update-payment-intent`, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ paymentIntentId: piIdRef.current, plan }),
        });
        const data = await r.json();
        if (!r.ok) throw new Error(data.error || "Failed to update payment intent");
        if (cancelled) return;
        elementsRef.current.fetchUpdates();
      } catch (e) {
        if (!cancelled) setError(e.message);
      }
    })();
    return () => { cancelled = true; };
  }, [plan]);

  const handleSubmit = async () => {
    setError(null);
    const validationError = validateForm({
      firstName, lastName, email,
      propertyLine1, propertyCity, propertyState, propertyZip,
    });
    if (validationError) { setError(validationError); return; }
    if (!stripeRef.current || !elementsRef.current || !paymentIntentId) {
      setError("Payment isn't ready yet — give it a moment and try again.");
      return;
    }

    setSubmitting(true);
    try {
      // Push the latest form values to the PaymentIntent's metadata so the
      // webhook has everything it needs for the Zoho records.
      const updateResp = await fetch(`${API()}/api/update-payment-intent`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          paymentIntentId, plan, email, firstName, lastName, phone, agentEmail,
          propertyAddress: {
            line1: propertyLine1, city: propertyCity,
            state: propertyState, zip: propertyZip,
          },
        }),
      });
      if (!updateResp.ok) {
        const data = await updateResp.json().catch(() => ({}));
        throw new Error(data.error || "Couldn't save your order details");
      }

      const { error: confirmError } = await stripeRef.current.confirmPayment({
        elements: elementsRef.current,
        confirmParams: {
          return_url: RETURN_URLS[plan],
          payment_method_data: {
            billing_details: {
              name: `${firstName} ${lastName}`.trim(),
              email,
              phone: phone || undefined,
              address: {
                line1: propertyLine1,
                city: propertyCity,
                state: propertyState,
                postal_code: propertyZip,
                country: "US",
              },
            },
          },
          receipt_email: email,
        },
      });
      if (confirmError) {
        setError(confirmError.message || "Payment failed. Please try again.");
      }
      // On success Stripe redirects to RETURN_URLS[plan] — nothing more to do here.
    } catch (e) {
      setError(e.message);
    } finally {
      setSubmitting(false);
    }
  };

  // Layouts call this to tell the hook where to mount PaymentElement.
  const setPaymentMountSelector = (sel) => {
    mountSelectorRef.current = sel;
  };

  return {
    // form state
    plan, setPlan,
    firstName, setFirstName, lastName, setLastName,
    email, setEmail, phone, setPhone, agentEmail, setAgentEmail,
    propertyLine1, setPropertyLine1, propertyCity, setPropertyCity,
    propertyState, setPropertyState, propertyZip, setPropertyZip,
    // payment state
    paymentReady, submitting, error,
    setError,
    handleSubmit,
    setPaymentMountSelector,
  };
}

Object.assign(window, {
  plansData,
  disputeTypes,
  RETURN_URLS,
  useCheckout,
});
