"use client";

/**
 * ClientBillingGate — wrap your client portal dashboard with this.
 *
 *   <ClientBillingGate>
 *     <PortalDashboard />
 *   </ClientBillingGate>
 *
 * Behaviour (matches the backend gate):
 *   - billing NOT enabled for the company  → renders children (normal access)
 *   - billing enabled AND active           → renders children (they paid / comp / manual)
 *   - billing enabled AND not active        → shows the payment gateway (blocks the app)
 *
 * The "Pay now" button opens Stripe Checkout, where card, Google Pay and Apple
 * Pay all appear automatically. After returning from Stripe we re-check status a
 * few times (the webhook that flips them to "active" is asynchronous).
 */

import React, { useCallback, useEffect, useRef, useState } from "react";
import { billingApi, type BillingStatus } from "@/lib/api/billingApi";

function money(amount: number | null, currency: string | null) {
  if (!amount) return null;
  return `${(amount / 100).toFixed(2)} ${(currency || "AED").toUpperCase()}`;
}

export default function ClientBillingGate({ children }: { children: React.ReactNode }) {
  const [status, setStatus] = useState<BillingStatus | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [paying, setPaying] = useState(false);
  const pollRef = useRef<number | null>(null);

  const load = useCallback(async () => {
    try {
      const res = await billingApi.getStatus();
      setStatus(res.data);
      setError(null);
      return res.data;
    } catch (e: any) {
      setError(e?.message || "Could not load billing status");
      return null;
    } finally {
      setLoading(false);
    }
  }, []);

  // Initial load + handle return from Stripe (?session_id / ?billing=cancel)
  useEffect(() => {
    load();

    const params = new URLSearchParams(window.location.search);
    if (params.get("session_id")) {
      // Webhook is async — poll a few times until active, then clean the URL.
      let tries = 0;
      pollRef.current = window.setInterval(async () => {
        tries += 1;
        const s = await load();
        if ((s && s.access_allowed) || tries >= 6) {
          if (pollRef.current) window.clearInterval(pollRef.current);
          const url = new URL(window.location.href);
          url.searchParams.delete("session_id");
          window.history.replaceState({}, "", url.toString());
        }
      }, 2000);
    }
    return () => {
      if (pollRef.current) window.clearInterval(pollRef.current);
    };
  }, [load]);

  const payNow = async () => {
    setPaying(true);
    try {
      const res = await billingApi.createCheckoutSession();
      if (res?.data?.url) {
        window.location.href = res.data.url; // → Stripe Checkout (card / Google Pay / Apple Pay)
      } else {
        setError("Could not start checkout. Please try again.");
        setPaying(false);
      }
    } catch (e: any) {
      setError(e?.message || "Could not start checkout");
      setPaying(false);
    }
  };

  if (loading) {
    return (
      <div style={wrap}>
        <div style={{ color: "#64748b", fontSize: 14 }}>Loading…</div>
      </div>
    );
  }

  // Fail-open on a status error so a transient API hiccup doesn't lock a paying
  // client out; the backend still enforces the gate on every request.
  if (error && !status) return <>{children}</>;

  if (status && status.access_allowed !== false) {
    return <>{children}</>;
  }

  // ── Paywall ────────────────────────────────────────────────────
  const price =
    money(status?.price_amount ?? null, status?.price_currency ?? null) || "—";
  const interval = status?.price_interval || "year";

  return (
    <div style={wrap}>
      <div style={card}>
        <div style={{ fontSize: 34, marginBottom: 8 }}>🔒</div>
        <h1 style={{ margin: "0 0 6px", fontSize: 20, fontWeight: 800, color: "#0f172a" }}>
          Subscription required
        </h1>
        <p style={{ margin: "0 0 18px", fontSize: 14, color: "#64748b", lineHeight: 1.6 }}>
          Your access to the portal is subscription-based. Complete payment to
          unlock your dashboard on the web and in the app.
        </p>

        <div style={priceBox}>
          <div style={{ fontSize: 12, color: "#64748b", fontWeight: 600 }}>Amount</div>
          <div style={{ fontSize: 28, fontWeight: 800, color: "#0f766e" }}>
            {price} <span style={{ fontSize: 14, color: "#64748b", fontWeight: 600 }}>/ {interval}</span>
          </div>
        </div>

        <button onClick={payNow} disabled={paying} style={payBtn(paying)}>
          {paying ? "Redirecting to secure checkout…" : "Pay now"}
        </button>

        <p style={{ margin: "12px 0 0", fontSize: 12, color: "#94a3b8" }}>
          Card, Google Pay and Apple Pay supported · Secured by Stripe
        </p>

        {error && (
          <p style={{ margin: "12px 0 0", fontSize: 13, color: "#dc2626" }}>{error}</p>
        )}
      </div>
    </div>
  );
}

const wrap: React.CSSProperties = {
  minHeight: "70vh",
  display: "flex",
  alignItems: "center",
  justifyContent: "center",
  padding: 24,
};
const card: React.CSSProperties = {
  width: "min(440px, 95vw)",
  background: "#fff",
  border: "1px solid #e2e8f0",
  borderRadius: 16,
  padding: 28,
  textAlign: "center",
  boxShadow: "0 10px 40px rgba(0,0,0,0.06)",
};
const priceBox: React.CSSProperties = {
  background: "#f0fdfa",
  border: "1px solid #99f6e4",
  borderRadius: 12,
  padding: "14px 16px",
  marginBottom: 18,
};
const payBtn = (disabled: boolean): React.CSSProperties => ({
  width: "100%",
  padding: 13,
  borderRadius: 10,
  border: "none",
  background: "#0f766e",
  color: "#fff",
  fontWeight: 700,
  fontSize: 15,
  cursor: disabled ? "default" : "pointer",
  opacity: disabled ? 0.7 : 1,
});
