// src/components/ZipvanQuote.js
import React, { useEffect, useRef, useState } from "react";

export default function ZipvanQuote() {
    const CONFIG = {
        GOOGLE_MAPS_API_KEY:
            process.env.NEXT_PUBLIC_GOOGLE_MAPS_KEY ||
            "AIzaSyAxWCXjM3_iYRKdWPUceRo79DlvIU9xnZQ",
        CALENDLY_EVENT_URL: "https://calendly.com/zipvan/new-meeting",
        PUBLIC_RATES: { booking_flat: 25, km_rate_under_equal_15: 3, km_rate_over_15: 2 },
        TAX_RATE: 0.13,
        BOUNDS: { SW: { lat: 42.8, lng: -81.0 }, NE: { lat: 44.3, lng: -78.5 } },
    };

    const pickupRef = useRef(null);
    const dropoffRef = useRef(null);
    const mapRef = useRef(null);
    const schedRef = useRef(null);

    const mapObj = useRef(null);
    const dirSvc = useRef(null);
    const dirRenderer = useRef(null);
    const geocoder = useRef(null);
    const markerP = useRef(null);
    const markerD = useRef(null);
    const routeToken = useRef(0);

    const [quote, setQuote] = useState({
        km: 0,
        min: 0,
        subtotal: 0,
        tax: 0,
        grand: 0,
    });
    const [mapsReady, setMapsReady] = useState(false);
    const [mapsError, setMapsError] = useState(null);

    const money = (n) => "$" + Number(n).toFixed(2);
    const q = (p) =>
        Object.entries(p)
            .filter(([, v]) => v !== "" && v != null)
            .map(([k, v]) => encodeURIComponent(k) + "=" + encodeURIComponent(v))
            .join("&");
    const showMapStatus = (m) => {
        const el = document.getElementById("mapStatus");
        if (el) {
            el.style.display = "block";
            el.textContent = m;
        }
    };
    const debounce = (fn, wait = 700) => {
        let t;
        return (...a) => {
            clearTimeout(t);
            t = setTimeout(() => fn(...a), wait);
        };
    };

    function loadGoogleMaps() {
        return new Promise((resolve, reject) => {
            if (window.google && window.google.maps && window.google.maps.places) {
                resolve(window.google);
                return;
            }
            if (document.getElementById("zipvan-google-maps")) {
                const existing = document.getElementById("zipvan-google-maps");
                existing.addEventListener("load", () => {
                    if (window.google) resolve(window.google);
                    else reject(new Error("Google loaded but window.google missing"));
                });
                existing.addEventListener("error", () => reject(new Error("Google Maps script error")));
                return;
            }
            const s = document.createElement("script");
            s.id = "zipvan-google-maps";
            s.src =
                "https://maps.googleapis.com/maps/api/js?key=" +
                encodeURIComponent(CONFIG.GOOGLE_MAPS_API_KEY) +
                "&libraries=places&v=weekly";
            s.async = true;
            s.defer = true;
            s.onload = () => {
                if (window.google) resolve(window.google);
                else reject(new Error("Google Maps loaded but window.google missing"));
            };
            s.onerror = () => reject(new Error("Google Maps failed to load (network or invalid key)"));
            document.head.appendChild(s);
        });
    }

    function calcAndSetTotals({ km, min }) {
        const rate = km <= 15 ? CONFIG.PUBLIC_RATES.km_rate_under_equal_15 : CONFIG.PUBLIC_RATES.km_rate_over_15;
        const distanceCost = km * rate;
        const subtotal = CONFIG.PUBLIC_RATES.booking_flat + distanceCost;
        const tax = +(subtotal * CONFIG.TAX_RATE).toFixed(2);
        const grand = +(subtotal + tax).toFixed(2);

        setQuote({
            km: +km.toFixed(2),
            min: Math.round(min),
            subtotal: +subtotal.toFixed(2),
            tax,
            grand,
        });
    }

    function openCalendly() {
        const url =
            CONFIG.CALENDLY_EVENT_URL +
            "?" +
            q({
                hide_event_type_details: 1,
                background_color: "ffffff",
                text_color: "0a0a0a",
                a1: pickupRef.current ? pickupRef.current.value : "",
                a2: dropoffRef.current ? dropoffRef.current.value : "",
                a3: quote.km ? quote.km.toFixed(1) + " km" : "",
                a4: money(quote.subtotal),
                a5: money(quote.grand),
                _cb: Date.now(),
            });

        const holder = schedRef.current ?? document.getElementById("sched");
        if (!holder) return;
        const existing = document.getElementById("calendly-embed-iframe");
        if (existing) existing.src = url;
        else {
            const ifr = document.createElement("iframe");
            ifr.id = "calendly-embed-iframe";
            ifr.src = url;
            ifr.allow = "payment *; clipboard-write *";
            ifr.style.width = "100%";
            ifr.style.minHeight = "980px";
            ifr.style.border = "0";
            holder.appendChild(ifr);
        }
        holder.scrollIntoView({ behavior: "smooth" });
    }

    function initMap() {
        if (!window.google) {
            setMapsError("Google Maps not available.");
            return;
        }
        if (!mapRef.current) {
            setMapsError("Map container not found.");
            return;
        }

        mapObj.current = new window.google.maps.Map(mapRef.current, {
            center: { lat: 43.65, lng: -79.38 },
            zoom: 10,
            gestureHandling: "greedy",
        });

        dirSvc.current = new window.google.maps.DirectionsService();
        dirRenderer.current = new window.google.maps.DirectionsRenderer({ suppressMarkers: true, preserveViewport: false });
        geocoder.current = new window.google.maps.Geocoder();
        dirRenderer.current.setMap(mapObj.current);

        const biasBounds = new window.google.maps.LatLngBounds(CONFIG.BOUNDS.SW, CONFIG.BOUNDS.NE);

        const acOpts = {
            types: ["address"],
            componentRestrictions: { country: "ca" },
            bounds: biasBounds,
            strictBounds: false,
            fields: ["formatted_address", "geometry"],
        };

        if (pickupRef.current) {
            const acP = new window.google.maps.places.Autocomplete(pickupRef.current, acOpts);
            acP.addListener("place_changed", () => handlePlace(acP, "pickup"));
        }
        if (dropoffRef.current) {
            const acD = new window.google.maps.places.Autocomplete(dropoffRef.current, acOpts);
            acD.addListener("place_changed", () => handlePlace(acD, "dropoff"));
        }

        const onBlurPick = () => geocodeManual("pickup");
        const onBlurDrop = () => geocodeManual("dropoff");
        pickupRef.current && pickupRef.current.addEventListener("blur", onBlurPick);
        dropoffRef.current && dropoffRef.current.addEventListener("blur", onBlurDrop);

        const geocodeDebounced = debounce((which) => {
            const el = which === "pickup" ? pickupRef.current : dropoffRef.current;
            const val = el ? el.value.trim() : "";
            if (!val) return;
            geocoder.current.geocode({ address: val, componentRestrictions: { country: "CA" }, bounds: biasBounds }, (res, st) => {
                if (st === "OK" && res && res[0]) {
                    dropMarker(which, res[0].geometry.location, res[0].formatted_address);
                    requestRoute();
                }
            });
        }, 400);

        function geocodeManual(which) {
            geocodeDebounced(which);
        }

        function handlePlace(ac, which) {
            const p = ac.getPlace();
            if (!p || !p.geometry) {
                geocodeManual(which);
                return;
            }
            dropMarker(which, p.geometry.location, p.formatted_address || (which === "pickup" ? pickupRef.current.value : dropoffRef.current.value));
            requestRoute();
        }

        function dropMarker(which, latlng, label) {
            const L = which === "pickup" ? "P" : "D";
            const opts = {
                position: latlng,
                map: mapObj.current,
                label: { text: L, color: "#fff", fontWeight: "700" },
                title: (which === "pickup" ? "Pick up" : "Drop off") + ": " + label,
            };
            if (which === "pickup") {
                if (markerP.current) markerP.current.setMap(null);
                markerP.current = new window.google.maps.Marker(opts);
            } else {
                if (markerD.current) markerD.current.setMap(null);
                markerD.current = new window.google.maps.Marker(opts);
            }
        }

        function requestRoute() {
            if (!markerP.current || !markerD.current) return;
            const my = ++routeToken.current;
            dirSvc.current.route(
                {
                    origin: markerP.current.getPosition(),
                    destination: markerD.current.getPosition(),
                    travelMode: window.google.maps.TravelMode.DRIVING,
                },
                (res, st) => {
                    if (my !== routeToken.current) return;
                    if (st === "OK" && res?.routes?.[0]?.legs?.[0]) {
                        dirRenderer.current.setDirections(res);
                        const leg = res.routes[0].legs[0];
                        const km = +(leg.distance.value / 1000).toFixed(2);
                        const mins = Math.round(leg.duration.value / 60);
                        const mapStatusEl = document.getElementById("mapStatus");
                        if (mapStatusEl) mapStatusEl.style.display = "none";
                        const b = new window.google.maps.LatLngBounds();
                        b.extend(markerP.current.getPosition());
                        b.extend(markerD.current.getPosition());
                        mapObj.current.fitBounds(b);
                        calcAndSetTotals({ km, min: mins });
                    } else {
                        showMapStatus("Couldn't compute the driving route. Check Ontario addresses.");
                    }
                }
            );
        }

        if (!document.getElementById("zipvan-calendly-script")) {
            const cs = document.createElement("script");
            cs.id = "zipvan-calendly-script";
            cs.src = "https://assets.calendly.com/assets/external/widget.js";
            cs.async = true;
            document.head.appendChild(cs);
        }

        setMapsReady(true);

        initMap._cleanup = () => {
            pickupRef.current && pickupRef.current.removeEventListener("blur", onBlurPick);
            dropoffRef.current && dropoffRef.current.removeEventListener("blur", onBlurDrop);
        };
    }

    useEffect(() => {
        let mounted = true;

        if (!CONFIG.GOOGLE_MAPS_API_KEY) {
            setMapsError("Google Maps API key missing. Put it into CONFIG or NEXT_PUBLIC_GOOGLE_MAPS_KEY.");
            return;
        }

        loadGoogleMaps()
            .then(() => {
                if (!mounted) return;
                initMap();
            })
            .catch((err) => {
                console.error("Google Maps load failed:", err);
                setMapsError("Google Maps failed to load. Check API key, billing and allowed referrers.");
                showMapStatus("Google Maps failed to load. See console for details.");
            });

        return () => {
            mounted = false;
            try {
                if (initMap._cleanup) initMap._cleanup();
                if (markerP.current) markerP.current.setMap(null);
                if (markerD.current) markerD.current.setMap(null);
                if (dirRenderer.current) dirRenderer.current.setMap(null);
            } catch (e) { }
        };
    }, []);

    const canBook = Boolean(quote.km && quote.min);

    return (
        <div className="zip-wrap" style={{ maxWidth: 1100, margin: "0 auto" }}>
            <div className="pd_top_90" />
            <div className="section_title type_four text-center">
                <h4 className="sm_title">Fast Checkout</h4>
                <div className="title_whole">
                    <h2 className="title">See Your All-In Price in 10 Seconds</h2>
                    <p>Enter pickup & drop-off. Your price is locked—no fuel or weekend fees.</p>
                </div>
                <div className="pd_bottom_40" />
            </div>
            <style>{`
:root{
  --zip-orange:#ff6500; --zip-black:#0a0a0a; --ink:#0f1720; --muted:#6b7280;
  --surface:#ffffff; --border:#e6e8eb; --radius:16px;
}
.zip-wrap{max-width:1100px;margin:0 auto;padding:28px}
.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);
  box-shadow:0 10px 28px rgba(15,23,32,.07);overflow:hidden}
.card-head{padding:20px 22px;background:var(--zip-black);color:#fff;display:flex;justify-content:space-between;align-items:center}
.card-head h2{margin:0;font-size:22px}
.card-body{padding:22px}
.addr-row{display:grid;grid-template-columns:1fr 1fr;gap:14px;align-items:start}
@media(max-width:760px){ .addr-row{grid-template-columns:1fr} }
.input{width:100%;padding:12px 14px;border:1px solid var(--border);border-radius:12px;
  font-size:16px;background:#fff;color:var(--ink);min-height:46px;box-sizing:border-box}
.input:focus{outline:0;border-color:#cfd3d8;box-shadow:0 0 0 3px rgba(255,101,0,.12)}
.map{height:390px;border-radius:12px;overflow:hidden;border:1px solid var(--border);
  background:#f6f7f8;display:flex;align-items:center;justify-content:center;margin-top:14px}
.map .err{color:var(--muted);font-size:14px}
.stats{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-top:14px}
.stat{border:1px solid var(--border);border-radius:12px;background:#fff;padding:12px 14px}
.stat label{display:block;font-size:12px;color:var(--muted);margin-bottom:6px}
.stat .value{font-size:16px;font-weight:750;color:var(--ink)}
.totalbar{display:flex;align-items:center;gap:18px;margin-top:16px}
.grand{margin-left:auto;font-size:22px;font-weight:850}
.breakdown{margin-top:12px;border:1px solid var(--border);border-radius:12px;overflow:hidden}
.brow{display:flex;justify-content:space-between;padding:10px 12px;font-size:14px;background:#fff}
.brow:nth-child(odd){background:#fbfbfc}
.brow .lbl{color:#6b7280}
.brow.total{font-weight:800;border-top:1px solid var(--border)}
.hint{font-size:12px;color:#6b7280;margin-top:8px}
.cta{display:flex;justify-content:flex-end;margin-top:16px}
.btn{appearance:none;border:0;background:var(--zip-orange);color:#fff;font-weight:850;letter-spacing:.2px;
  padding:12px 18px;border-radius:999px;font-size:16px;cursor:pointer;transition:.15s transform,.2s opacity}
.btn[disabled]{background:#c9ccd1;cursor:not-allowed;opacity:.85}
.btn:active{transform:translateY(1px)}
#sched{margin-top:26px}
#calendly-embed-iframe{width:100%;min-height:980px;border:0}
      `}</style>

            <div className="card">
                <div className="card-head">
                    <h2 className="text-white">Book a Pickup</h2>
                    <div style={{ opacity: ".9", fontSize: 13 }}>Transparent pricing — distance + booking</div>
                </div>

                <div className="card-body">
                    <div className="addr-row">
                        <input id="pickup" ref={pickupRef} className="input" type="text" placeholder="Pick up address (Canada)" aria-label="Pick up" autoComplete="off" />
                        <input id="dropoff" ref={dropoffRef} className="input" type="text" placeholder="Drop off address (Canada)" aria-label="Drop off" autoComplete="off" />
                    </div>

                    <div id="map" ref={mapRef} className="map">
                        <div className="err" id="mapStatus">Enter Pick up and Drop off to see your route, distance, and price.</div>
                    </div>

                    <div className="stats">
                        <div className="stat">
                            <label>Service</label>
                            <div className="value">Curbside</div>
                        </div>
                        <div className="stat">
                            <label>Crew</label>
                            <div className="value">1 mover</div>
                        </div>
                        <div className="stat">
                            <label>Distance & Time</label>
                            <div className="value">
                                <span id="distanceKm">{quote.km ? quote.km.toFixed(1) : "—"}</span> km • <span id="driveMin">{quote.min ? Math.round(quote.min) : "—"}</span> min
                            </div>
                        </div>
                    </div>

                    <div className="totalbar">
                        <div className="grand">Grand total: <span id="grandTotal">{quote.km ? money(quote.grand) : "—"}</span></div>
                    </div>

                    <div className="breakdown" id="breakdownBox" style={{ display: quote.km ? "block" : "none" }}>
                        <div className="brow"><div className="lbl">Booking fee</div><div id="bkFee">{money(CONFIG.PUBLIC_RATES.booking_flat)}</div></div>
                        <div className="brow"><div className="lbl">Distance (<span id="rateLabel">${quote.km && quote.km <= 15 ? CONFIG.PUBLIC_RATES.km_rate_under_equal_15 : CONFIG.PUBLIC_RATES.km_rate_over_15}</span>/km)</div><div id="distAmt">{quote.km ? money((quote.km) * (quote.km <= 15 ? CONFIG.PUBLIC_RATES.km_rate_under_equal_15 : CONFIG.PUBLIC_RATES.km_rate_over_15)) : money(0)}</div></div>
                        <div className="brow"><div className="lbl">Subtotal</div><div id="subAmt">{quote.km ? money(quote.subtotal) : money(0)}</div></div>
                        <div className="brow"><div className="lbl">HST (13%)</div><div id="taxAmt">{quote.km ? money(quote.tax) : money(0)}</div></div>
                        <div className="brow total"><div>Grand total</div><div id="grandAmt">{quote.km ? money(quote.grand) : money(0)}</div></div>
                    </div>

                    <div className="hint">Final price shown before you pay. Name, phone, and email are collected in the next step.</div>

                    <div className="cta">
                        <button id="bookNow" className="btn" disabled={!canBook} onClick={() => { if (canBook) openCalendly(); }}>
                            Continue to Scheduling
                        </button>
                    </div>
                </div>
            </div>

            <div id="sched" ref={schedRef}></div>

            {mapsError && (
                <div style={{ marginTop: 12, padding: 12, background: "#fff6f6", color: "#b91c1c", borderRadius: 8 }}>
                    <strong>Map error:</strong> {mapsError}
                </div>
            )}
        </div>
    );
}
