"use client";
/* eslint-disable @next/next/no-img-element -- Google author photos */

import * as React from "react";
import { motion } from "motion/react";
import { ExternalLink, PenLine, Star } from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import type { Business } from "./showroom-page";

interface Review {
  id: string;
  author: string;
  photo: string | null;
  authorUrl: string | null;
  rating: number;
  text: string;
  when: string;
  url: string | null;
}
type Data = { available: true; rating: number | null; count: number; mapsUrl: string | null; reviews: Review[] } | { available: false; reason?: string };
const ease = [0.16, 1, 0.3, 1] as const;

function Stars({ value, size = "size-4" }: { value: number; size?: string }) {
  return (
    <span className="inline-flex items-center gap-0.5" aria-label={`${value} out of 5`}>
      {[1, 2, 3, 4, 5].map((i) => (
        <Star key={i} className={cn(size, i <= Math.round(value) ? "fill-[#FBBC04] text-[#FBBC04]" : "text-border-strong")} />
      ))}
    </span>
  );
}

function GoogleG({ className }: { className?: string }) {
  return (
    <svg viewBox="0 0 24 24" className={className} aria-hidden>
      <path fill="#4285F4" d="M23.5 12.3c0-.8-.1-1.6-.2-2.3H12v4.4h6.5c-.3 1.5-1.1 2.7-2.4 3.6v3h3.9c2.3-2.1 3.5-5.2 3.5-8.7z" />
      <path fill="#34A853" d="M12 24c3.2 0 6-1.1 7.9-2.9l-3.9-3c-1.1.7-2.4 1.2-4 1.2-3.1 0-5.7-2.1-6.7-4.9H1.3v3.1C3.3 21.4 7.3 24 12 24z" />
      <path fill="#FBBC04" d="M5.3 14.4c-.2-.7-.4-1.5-.4-2.4s.1-1.6.4-2.4V6.5H1.3C.5 8.2 0 10 0 12s.5 3.8 1.3 5.5l4-3.1z" />
      <path fill="#EA4335" d="M12 4.8c1.8 0 3.3.6 4.6 1.8l3.4-3.4C18 1.2 15.2 0 12 0 7.3 0 3.3 2.6 1.3 6.5l4 3.1c1-2.8 3.6-4.8 6.7-4.8z" />
    </svg>
  );
}

/**
 * Google rating and reviews, live from Google when a Place ID and API key
 * are configured, shown exactly as Google returns them (author, stars,
 * text, link back). The "write a review" button is the same for everyone:
 * no incentive, no filtering — that is what Google's policy requires.
 */
export type GoogleReviews = Data | null;

/** Live Google data for the page (rating chip in the hero, cards in the section). */
export function useGoogleReviews(hasPlace: boolean): GoogleReviews {
  const [data, setData] = React.useState<Data | null>(null);
  React.useEffect(() => {
    if (!hasPlace) {
      setData({ available: false, reason: "no-place" });
      return;
    }
    let alive = true;
    fetch("/api/google-reviews")
      .then((r) => r.json())
      .then((d: Data) => alive && setData(d))
      .catch(() => alive && setData({ available: false, reason: "network" }));
    return () => {
      alive = false;
    };
  }, [hasPlace]);
  return data;
}

export function GoogleRatingChip({ data, className }: { data: GoogleReviews; className?: string }) {
  if (!data || !data.available || !data.rating) return null;
  return (
    <a href={data.mapsUrl ?? "#reviews"} target={data.mapsUrl ? "_blank" : undefined} rel="noreferrer" className={cn("inline-flex items-center gap-1.5 rounded-full border border-white/25 bg-white/10 px-2.5 py-1 text-xs font-semibold text-white backdrop-blur transition hover:bg-white/20", className)}>
      <GoogleG className="size-3.5" /> {data.rating.toFixed(1)} <Stars value={data.rating} size="size-3" /> <span className="font-normal text-white/80">{data.count} reviews</span>
    </a>
  );
}

export function ReviewsSection({ business, data, onAvailable }: { business: Business; data: GoogleReviews; onAvailable?: (ok: boolean) => void }) {
  const ok = !!data && data.available;
  React.useEffect(() => {
    onAvailable?.(!!business.reviewUrl);
  }, [business.reviewUrl, onAvailable]);
  if (!business.reviewUrl && !ok) return null;
  const live = ok ? (data as Extract<Data, { available: true }>) : null;

  return (
    <section id="reviews" className="px-4 py-12 sm:px-8 lg:px-12">
      <div className="mx-auto max-w-6xl">
        <div className="flex flex-wrap items-end justify-between gap-4">
          <div>
            <p className="eyebrow flex items-center gap-2"><GoogleG className="size-3.5" /> Google reviews</p>
            <h2 className="font-display text-3xl font-medium tracking-tight sm:text-4xl">What guests say</h2>
            {live?.rating ? (
              <p className="mt-2 flex items-center gap-2 text-sm">
                <span className="font-display text-3xl font-medium tabular">{live.rating.toFixed(1)}</span>
                <Stars value={live.rating} />
                <span className="text-fg-muted">from {live.count} Google review{live.count === 1 ? "" : "s"}</span>
                {live.mapsUrl ? <a href={live.mapsUrl} target="_blank" rel="noreferrer" className="ml-1 inline-flex items-center gap-1 text-xs font-medium text-primary hover:underline">See all <ExternalLink className="size-3" /></a> : null}
              </p>
            ) : (
              <p className="mt-2 max-w-md text-sm text-fg-muted">Every review is written by a guest on Google, unedited. Stayed with us? Yours helps the next traveller choose.</p>
            )}
          </div>
          {business.reviewUrl ? (
            <Button size="lg" className="rounded-full" asChild>
              <a href={business.reviewUrl} target="_blank" rel="noreferrer">
                <PenLine /> Write a review on Google
              </a>
            </Button>
          ) : null}
        </div>
        {live && live.reviews.length ? (
          <div className="-mx-4 mt-6 flex snap-x snap-mandatory gap-4 overflow-x-auto px-4 pb-2 scrollbar-none sm:mx-0 sm:grid sm:grid-cols-2 sm:overflow-visible sm:px-0 lg:grid-cols-3">
            {live.reviews.slice(0, 6).map((r, i) => (
              <motion.figure key={r.id} initial={{ opacity: 0, y: 18 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true, margin: "-40px" }} transition={{ duration: 0.5, ease, delay: (i % 3) * 0.08 }} className="flex w-[82vw] max-w-[340px] shrink-0 snap-start flex-col rounded-2xl border border-border bg-surface p-4 shadow-xs hairline-top sm:w-auto sm:max-w-none">
                <div className="flex items-center gap-3">
                  {r.photo ? <img src={r.photo} alt="" className="size-10 rounded-full object-cover" loading="lazy" referrerPolicy="no-referrer" /> : <span className="flex size-10 items-center justify-center rounded-full bg-surface-2 text-sm font-semibold">{r.author.slice(0, 1)}</span>}
                  <div className="min-w-0 flex-1">
                    {r.authorUrl ? <a href={r.authorUrl} target="_blank" rel="noreferrer" className="block truncate text-sm font-semibold hover:underline">{r.author}</a> : <p className="truncate text-sm font-semibold">{r.author}</p>}
                    <p className="flex items-center gap-1.5 text-2xs text-fg-muted"><Stars value={r.rating} size="size-3" /> {r.when}</p>
                  </div>
                  <GoogleG className="size-5 shrink-0" />
                </div>
                <blockquote className="mt-3 line-clamp-6 text-sm leading-relaxed text-fg">{r.text}</blockquote>
                {r.url ? <a href={r.url} target="_blank" rel="noreferrer" className="mt-auto pt-3 text-2xs font-medium text-fg-subtle hover:text-fg">Read on Google</a> : null}
              </motion.figure>
            ))}
          </div>
        ) : null}
        <p className="mt-4 text-2xs text-fg-subtle">Reviews are hosted and moderated by Google. We ask every guest the same way and never offer anything in exchange for a review.</p>
      </div>
    </section>
  );
}
