"use client";

import React, { useEffect, useMemo, useState } from "react";
import { useAuth } from "@/hooks/useAuth";
import { apiFetch } from "@/lib/api";

// Tiered low-stock threshold — mirrors events/[id]/page.tsx
function lowStockThreshold(stockLimit: number): number {
  let pct: number;
  if (stockLimit <= 50) pct = 0.20;
  else if (stockLimit <= 200) pct = 0.15;
  else if (stockLimit <= 1000) pct = 0.10;
  else pct = 0.05;
  return Math.round(stockLimit * pct);
}

type EarlyBirdTier = { id: string; deadline: string; price: number; stockLimit?: number; order?: number };
type OptionVariant = { id: string; name: string; price: number | null; stockLimit?: number; availableCount?: number; order?: number };
type EventOption = {
  id: string;
  name: string;
  price: number;
  stockLimit?: number;
  availableCount?: number;
  isMainTicket?: boolean;
  earlyBirdTiers?: EarlyBirdTier[];
  variants?: OptionVariant[];
};

type Event = {
  id: string;
  title: string;
  description?: string;
  startDate: string;
  endDate: string;
  registrationDeadline?: string | null;
  price: number;
  picture?: string;
  eventOptions?: EventOption[];
  form?: { isRequired: boolean; fields?: any[] } | null;
  requiresAuth?: boolean;
};

// Key format: "optionId" for no-variant options, "optionId:variantId" for variant options
type QtyMap = Record<string, number>;

function effectiveUnitForOption(opt: EventOption): number {
  const base = opt.price || 0;
  const tiers = Array.isArray(opt.earlyBirdTiers) ? opt.earlyBirdTiers.slice() : [];
  if (tiers.length === 0) return base;
  const now = new Date();
  const applicable = tiers
    .map((t) => ({ ...t, _d: new Date(t.deadline) }))
    .filter((t) => now < t._d && (t.stockLimit === undefined || t.stockLimit === 0 || (t as any).availableCount === undefined || (t as any).availableCount > 0))
    .sort((a, b) => a.price - b.price || a._d.getTime() - b._d.getTime());
  return applicable.length > 0 ? applicable[0].price : base;
}

function effectiveUnitForVariant(opt: EventOption, variant: OptionVariant): number {
  if (variant.price !== null && variant.price !== undefined) return variant.price;
  return effectiveUnitForOption(opt);
}

function nextTierForOption(opt: EventOption): EarlyBirdTier | null {
  const tiers = Array.isArray(opt.earlyBirdTiers) ? opt.earlyBirdTiers.slice() : [];
  if (tiers.length === 0) return null;
  const now = new Date();
  const applicable = tiers
    .map((t) => ({ ...t, _d: new Date(t.deadline) }))
    .filter((t) => now < t._d)
    .sort((a, b) => a.price - b.price || a._d.getTime() - b._d.getTime());
  if (applicable.length === 0) return null;
  return applicable[0];
}

function StockBadge({ stockLimit, availableCount }: { stockLimit?: number; availableCount?: number }) {
  if (!stockLimit || stockLimit === 0) return null;
  if (availableCount === undefined) return null;
  if (availableCount <= 0) {
    return <span className="text-xs font-medium text-red-600 bg-red-50 border border-red-200 rounded px-1.5 py-0.5">Sold out</span>;
  }
  const threshold = lowStockThreshold(stockLimit);
  if (availableCount <= threshold) {
    return <span className="text-xs font-medium text-orange-600 bg-orange-50 border border-orange-200 rounded px-1.5 py-0.5">{availableCount} remaining</span>;
  }
  return null;
}

function QtyControl({
  value,
  onChange,
  disabled,
  max,
}: {
  value: number;
  onChange: (v: number) => void;
  disabled?: boolean;
  max?: number;
}) {
  return (
    <div className="flex items-center gap-1.5">
      <button
        type="button"
        className="w-7 h-7 flex items-center justify-center border rounded text-gray-600 hover:bg-gray-50 disabled:opacity-40"
        onClick={() => onChange(Math.max(0, value - 1))}
        disabled={disabled || value <= 0}
      >
        −
      </button>
      <span className="w-6 text-center text-sm font-medium">{value}</span>
      <button
        type="button"
        className="w-7 h-7 flex items-center justify-center border rounded text-gray-600 hover:bg-gray-50 disabled:opacity-40"
        onClick={() => onChange(value + 1)}
        disabled={disabled || (max !== undefined && max > 0 && value >= max)}
      >
        +
      </button>
    </div>
  );
}

function OptionCard({
  opt,
  quantities,
  onQtyChange,
}: {
  opt: EventOption;
  quantities: QtyMap;
  onQtyChange: (key: string, val: number) => void;
}) {
  const hasVariants = Array.isArray(opt.variants) && opt.variants.length > 0;
  const isSoldOut = (opt.stockLimit ?? 0) > 0 && opt.availableCount !== undefined && opt.availableCount <= 0;

  if (hasVariants) {
    const variants = opt.variants!.slice().sort((a, b) => (a.order || 0) - (b.order || 0));

    // Compute "From R..." display
    const variantPrices = variants.map((v) => effectiveUnitForVariant(opt, v));
    const minPrice = Math.min(...variantPrices);
    const maxPrice = Math.max(...variantPrices);
    const priceLabel = minPrice === maxPrice ? `R${minPrice.toFixed(2)}` : `From R${minPrice.toFixed(2)}`;

    return (
      <div className="border rounded-lg overflow-hidden bg-white shadow-sm">
        {/* Option header */}
        <div className="flex items-center justify-between px-4 py-3 border-b bg-gray-50">
          <div>
            <div className="font-medium text-sm">{opt.name}</div>
            <div className="text-xs text-gray-500 mt-0.5">{priceLabel}</div>
          </div>
          <div className="flex items-center gap-2">
            {isSoldOut ? (
              <span className="text-xs font-medium text-red-600 bg-red-50 border border-red-200 rounded px-1.5 py-0.5">Sold out</span>
            ) : (
              <StockBadge stockLimit={opt.stockLimit} availableCount={opt.availableCount} />
            )}
          </div>
        </div>

        {/* Variant rows */}
        <div className="divide-y">
          {variants.map((variant) => {
            const key = `${opt.id}:${variant.id}`;
            const qty = quantities[key] || 0;
            const unitPrice = effectiveUnitForVariant(opt, variant);
            const variantSoldOut = (variant.stockLimit ?? 0) > 0 && variant.availableCount !== undefined && variant.availableCount <= 0;
            const maxQty = ((variant.stockLimit ?? 0) > 0 && variant.availableCount !== undefined)
              ? variant.availableCount
              : undefined;

            return (
              <div key={variant.id} className="flex items-center justify-between px-4 py-2.5">
                <div className="flex items-center gap-2 min-w-0">
                  <span className="text-sm">{variant.name}</span>
                  <span className="text-xs text-gray-500">R{unitPrice.toFixed(2)}</span>
                  <StockBadge stockLimit={variant.stockLimit} availableCount={variant.availableCount} />
                </div>
                <QtyControl
                  value={qty}
                  onChange={(v) => onQtyChange(key, v)}
                  disabled={!!(isSoldOut || variantSoldOut)}
                  max={maxQty}
                />
              </div>
            );
          })}
        </div>
      </div>
    );
  }

  // No variants — simple row
  const key = opt.id;
  const qty = quantities[key] || 0;
  const tier = nextTierForOption(opt);
  const price = effectiveUnitForOption(opt);
  const maxQty = ((opt.stockLimit ?? 0) > 0 && opt.availableCount !== undefined)
    ? opt.availableCount
    : undefined;

  return (
    <div className="flex items-center justify-between border rounded-lg p-3 bg-white shadow-sm">
      <div className="min-w-0 flex-1 mr-3">
        <div className="font-medium text-sm">{opt.name}</div>
        <div className="text-xs text-gray-500 mt-0.5 flex items-center gap-2 flex-wrap">
          {tier ? (
            <>
              <span>R{price.toFixed(2)}</span>
              <span className="text-brand-600">
                Early bird — ends {new Date(tier.deadline).toLocaleDateString(undefined, { year: "numeric", month: "short", day: "2-digit" })}
              </span>
            </>
          ) : (
            <span>R{price.toFixed(2)}</span>
          )}
          <StockBadge stockLimit={opt.stockLimit} availableCount={opt.availableCount} />
        </div>
      </div>
      <QtyControl
        value={qty}
        onChange={(v) => onQtyChange(key, v)}
        disabled={!!(isSoldOut)}
        max={maxQty}
      />
    </div>
  );
}

export default function RegisterForm({ event }: { event: Event }) {
  const { token, user } = useAuth();
  const eventId = event.id;

  const [quantities, setQuantities] = useState<QtyMap>(() => {
    const initial: QtyMap = {};
    (event.eventOptions || []).forEach((o) => {
      if (Array.isArray(o.variants) && o.variants.length > 0) {
        o.variants.forEach((v) => { initial[`${o.id}:${v.id}`] = 0; });
      } else {
        initial[o.id] = 0;
      }
    });
    return initial;
  });
  const [error, setError] = useState<string | null>(null);
  const [registrationId, setRegistrationId] = useState<string | null>(null);
  const [creatingCheckout, setCreatingCheckout] = useState(false);
  const [creatingRegistration, setCreatingRegistration] = useState(false);

  // Guest details (for unauthenticated free-event registration)
  const [guestName, setGuestName] = useState("");
  const [guestEmail, setGuestEmail] = useState("");
  const [guestPhone, setGuestPhone] = useState("");

  // Event data is server-rendered, but "now" has to be evaluated in the browser (and this page
  // can be served from a up-to-60s-old cache — see revalidate in page.tsx), so still guard against
  // someone loading a link after registration has actually closed.
  useEffect(() => {
    try {
      const now = new Date();
      const end = event.endDate ? new Date(event.endDate) : null;
      const deadline = event.registrationDeadline ? new Date(event.registrationDeadline) : null;
      if ((deadline && now >= deadline) || (end && now >= end)) {
        window.location.replace('/events');
      }
    } catch {}
  }, [event.endDate, event.registrationDeadline]);

  const handleQtyChange = (key: string, val: number) => {
    setQuantities((q) => ({ ...q, [key]: val }));
  };

  const total = useMemo(() => {
    return (event.eventOptions || []).reduce((sum, opt) => {
      const hasVariants = Array.isArray(opt.variants) && opt.variants.length > 0;
      if (hasVariants) {
        return sum + opt.variants!.reduce((vsum, v) => {
          const qty = quantities[`${opt.id}:${v.id}`] || 0;
          return vsum + qty * effectiveUnitForVariant(opt, v);
        }, 0);
      }
      return sum + (quantities[opt.id] || 0) * effectiveUnitForOption(opt);
    }, 0);
  }, [event, quantities]);

  const isGuestEligible = !!(event.requiresAuth === false);
  const isLoggedIn = !!user || !!token;
  const showGuestForm = isGuestEligible && !isLoggedIn;

  const eventSoldOut = useMemo(() => {
    const limitedOpts = (event.eventOptions || []).filter(o => (o.stockLimit ?? 0) > 0);
    return limitedOpts.length > 0 && limitedOpts.every(o => o.availableCount !== undefined && o.availableCount <= 0);
  }, [event]);

  const buildItems = () => {
    const items: { eventOptionId: string; quantity: number; variantId?: string }[] = [];
    Object.entries(quantities).forEach(([key, qty]) => {
      if (qty <= 0) return;
      if (key.includes(":")) {
        const [eventOptionId, variantId] = key.split(":");
        items.push({ eventOptionId, quantity: qty, variantId });
      } else {
        items.push({ eventOptionId: key, quantity: qty });
      }
    });
    return items;
  };

  const submitRegistration = async () => {
    const items = buildItems();
    if (items.length === 0) {
      setError("Select at least one ticket.");
      return;
    }

    if (isLoggedIn) {
      if (!token) {
        setError("Session expired — please log in again.");
        window.location.href = `/login?redirect=/register/${eventId}`;
        return;
      }
      try {
        setError(null);
        setCreatingRegistration(true);
        const res = await apiFetch<{ id: string }>("/api/registrations", {
          method: "POST",
          body: { eventId, options: items },
          authToken: token,
        });
        if (res?.id) {
          const hasForm = !!(event?.form && Array.isArray(event.form.fields) && event.form.fields.length > 0);
          if (hasForm) {
            window.location.href = `/forms?registrationId=${encodeURIComponent(res.id)}`;
          } else {
            window.location.href = `/registration/success?registrationId=${encodeURIComponent(res.id)}&totalDue=${encodeURIComponent((total || 0).toFixed(2))}`;
          }
        }
      } catch (e: any) {
        setError(e?.message || "Registration failed");
      } finally {
        setCreatingRegistration(false);
      }
      return;
    }

    if (!showGuestForm) {
      setError("Please log in to register for this event.");
      window.location.href = `/login?redirect=/register/${eventId}`;
      return;
    }

    if (!guestName.trim()) { setError("Please enter your name."); return; }
    if (!guestEmail.trim() || !guestEmail.includes("@")) { setError("Please enter a valid email address."); return; }

    try {
      setError(null);
      setCreatingRegistration(true);
      const res = await apiFetch<{ id: string }>("/api/registrations", {
        method: "POST",
        body: { eventId, options: items, guestName: guestName.trim(), guestEmail: guestEmail.trim(), guestPhone: guestPhone.trim() || undefined },
      });
      if (res?.id) {
        const hasForm = !!(event?.form && Array.isArray(event.form.fields) && event.form.fields.length > 0);
        if (hasForm) {
          window.location.href = `/forms?registrationId=${encodeURIComponent(res.id)}`;
        } else {
          window.location.href = `/registration/success?registrationId=${encodeURIComponent(res.id)}&totalDue=0.00`;
        }
      }
    } catch (e: any) {
      setError(e?.message || "Registration failed");
    } finally {
      setCreatingRegistration(false);
    }
  };

  const createYocoCheckout = async () => {
    if (!token || !registrationId) return;
    try {
      setCreatingCheckout(true);
      const res = await apiFetch<{ redirectUrl: string }>("/api/payments/yoco-checkout", {
        method: "POST",
        body: {
          registrationId,
          successUrl: window.location.origin + "/payment/success",
          cancelUrl: window.location.origin + "/payment/cancel",
          failureUrl: window.location.origin + "/payment/failure",
        },
        authToken: token,
      });
      window.open(res.redirectUrl, "_blank");
    } catch (e: any) {
      setError(e?.message || "Failed to create checkout");
    } finally {
      setCreatingCheckout(false);
    }
  };

  return (
    <>
      <h1 className="text-2xl font-semibold mb-4">Register for {event.title}</h1>

      {eventSoldOut && (
        <div className="mb-4 p-4 border rounded-lg bg-red-50 border-red-200 text-sm text-red-800 font-medium">
          This event is sold out. Registration is no longer available.
        </div>
      )}

      {!isLoggedIn && !isGuestEligible && (
        <div className="mb-4 p-4 border rounded-lg bg-amber-50 border-amber-200 text-sm text-amber-800">
          You need to <a href={`/login?redirect=/register/${eventId}`} className="font-semibold underline">log in</a> or <a href={`/register?redirect=/register/${eventId}`} className="font-semibold underline">create an account</a> to register for this event.
        </div>
      )}

      {showGuestForm && (
        <div className="mb-6 border rounded-xl p-4 bg-white shadow-sm">
          <div className="text-base font-semibold mb-1">Your details</div>
          <p className="text-sm text-gray-500 mb-3">
            No account needed for this event.{" "}
            <a href={`/login?redirect=/register/${eventId}`} className="text-brand-600 hover:underline">Log in</a> if you already have one.
          </p>
          <div className="space-y-2">
            <input
              className="w-full border rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400"
              placeholder="Full name *"
              value={guestName}
              onChange={e => setGuestName(e.target.value)}
              required
            />
            <input
              type="email"
              className="w-full border rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400"
              placeholder="Email address *"
              value={guestEmail}
              onChange={e => setGuestEmail(e.target.value)}
              required
            />
            <input
              type="tel"
              className="w-full border rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400"
              placeholder="Phone number (optional)"
              value={guestPhone}
              onChange={e => setGuestPhone(e.target.value)}
            />
          </div>
        </div>
      )}

      <div className="space-y-3">
        {(event.eventOptions || []).map((opt) => (
          <OptionCard
            key={opt.id}
            opt={opt}
            quantities={quantities}
            onQtyChange={handleQtyChange}
          />
        ))}
      </div>

      {(() => {
        // Collect all upcoming early-bird tiers across all options
        const now = new Date();
        const upcomingTiers = (event.eventOptions || []).flatMap(opt =>
          (opt.earlyBirdTiers || [])
            .map((t: any) => ({ ...t, deadline: new Date(t.deadline) }))
            .filter((t: any) => t.deadline > now)
        ).sort((a: any, b: any) => a.deadline.getTime() - b.deadline.getTime());
        if (upcomingTiers.length === 0) return null;
        const soonest = upcomingTiers[0].deadline as Date;
        const dateStr = soonest.toLocaleDateString(undefined, { year: "numeric", month: "long", day: "numeric" });
        return (
          <div className="mt-4 p-3 rounded-lg bg-amber-50 border border-amber-200 text-sm text-amber-800">
            <strong>Early bird pricing notice:</strong> Reduced early-bird prices are available until {dateStr}. Prices are subject to deadline and availability — your price is locked at registration but payment must be completed before the deadline to guarantee the early-bird rate.
          </div>
        );
      })()}

      <div className="mt-6 flex items-center justify-between">
        <div className="text-lg font-semibold">Total: R{total.toFixed(2)}</div>
        {!registrationId ? (
          eventSoldOut ? (
            <button disabled className="bg-red-50 text-red-700 border border-red-200 px-4 py-2 rounded cursor-not-allowed">
              Sold Out
            </button>
          ) : (
          <button
            onClick={submitRegistration}
            disabled={creatingRegistration || (!isLoggedIn && !isGuestEligible)}
            className="bg-brand-600 text-white px-4 py-2 rounded hover:bg-brand-700 disabled:opacity-60"
          >
            {creatingRegistration ? "Registering..." : "Register"}
          </button>
          )
        ) : (
          <button
            onClick={createYocoCheckout}
            disabled={creatingCheckout}
            className="bg-green-600 text-white px-4 py-2 rounded disabled:opacity-60"
          >
            {creatingCheckout ? "Creating checkout..." : "Pay with Yoco"}
          </button>
        )}
      </div>

      {error && <p className="text-sm text-red-600 mt-3">{error}</p>}
    </>
  );
}
