import Container from "@/components/ui/Container";
import { ButtonLink } from "@/components/ui/Button";
import DynamicForm from "@/components/forms/DynamicForm";
import ServiceCard from "@/components/cards/ServiceCard";
import StoreProductCard from "@/components/cards/StoreProductCard";
import CustomerReviews from "@/components/store/CustomerReviews";
import {
  getFormSchema,
  getCareServices,
  getAboutStats,
  getCoreValues,
  getJobOpenings,
  getStoreProducts,
  getTestimonials,
  resolveMediaUrl,
  type WebBlock
} from "@/lib/api";

/**
 * Renders a page's block tree (WEB-THEME-DESIGN-CONTEXT.md §2). Implements
 * every type in the v1 catalog — adding a new block type here means adding
 * it to that doc's catalog table first (source of truth for both this
 * renderer and the ABOS admin builder's live preview).
 */
export default function BlockRenderer({ blocks }: { blocks: WebBlock[] }) {
  return (
    <>
      {blocks.map((block) => <BlockNode key={block.id} block={block} />)}
    </>
  );
}

async function BlockNode({ block }: { block: WebBlock }) {
  switch (block.type) {
    case "hero":
      return <HeroBlock props={block.props} />;
    case "richText":
      return <RichTextBlock props={block.props} />;
    case "image":
      return <ImageBlock props={block.props} />;
    case "button":
      return <ButtonBlock props={block.props} />;
    case "columns":
      return <ColumnsBlock props={block.props} children={block.children} />;
    case "spacer":
      return <div style={{ height: Number(block.props.heightPx) || 0 }} />;
    case "productGrid":
      return <ProductGridBlock props={block.props} />;
    case "formEmbed":
      return <FormEmbedBlock props={block.props} />;
    case "testimonial":
      return <TestimonialBlock props={block.props} />;
    case "faqAccordion":
      return <FaqAccordionBlock props={block.props} />;
    case "serviceGrid":
      return <ServiceGridBlock props={block.props} />;
    case "statsGrid":
      return <StatsGridBlock props={block.props} />;
    case "coreValueGrid":
      return <CoreValueGridBlock />;
    case "jobGrid":
      return <JobGridBlock props={block.props} />;
    case "trustBadges":
      return <TrustBadgesBlock props={block.props} />;
    case "testimonialGrid":
      return <TestimonialGridBlock />;
    default:
      // Unknown block type — fail soft rather than crash the page render.
      console.error(`[BlockRenderer] unknown block type: ${block.type}`);
      return null;
  }
}

function HeroBlock({ props }: { props: Record<string, unknown> }) {
  const heading = String(props.heading || "");
  const subheading = props.subheading ? String(props.subheading) : null;
  const imageUrl = props.imageUrl ? resolveMediaUrl(String(props.imageUrl)) : undefined;
  const ctaLabel = props.ctaLabel ? String(props.ctaLabel) : null;
  const ctaHref = props.ctaHref ? String(props.ctaHref) : "#";

  return (
    <section
      className="relative min-h-[340px] flex items-center bg-neutral-800 text-white"
      style={
        imageUrl
          ? {
              backgroundImage: `linear-gradient(rgba(28,25,21,0.55), rgba(28,25,21,0.65)), url(${imageUrl})`,
              backgroundSize: "cover",
              backgroundPosition: "center"
            }
          : undefined
      }
    >
      <Container className="py-16">
        <div className="max-w-2xl">
          <h1 className="font-display text-3xl md:text-5xl leading-tight">{heading}</h1>
          {subheading ? <p className="mt-4 text-neutral-200 leading-relaxed">{subheading}</p> : null}
          {ctaLabel ? (
            <div className="mt-8">
              <ButtonLink href={ctaHref}>{ctaLabel}</ButtonLink>
            </div>
          ) : null}
        </div>
      </Container>
    </section>
  );
}

function RichTextBlock({ props }: { props: Record<string, unknown> }) {
  return (
    <section className="py-10">
      <Container className="max-w-3xl mx-auto">
        <div
          className="prose prose-neutral max-w-none text-neutral-600 leading-relaxed"
          dangerouslySetInnerHTML={{ __html: String(props.html || "") }}
        />
      </Container>
    </section>
  );
}

function ImageBlock({ props }: { props: Record<string, unknown> }) {
  const url = resolveMediaUrl(String(props.url || ""));
  const altText = String(props.altText || "");
  const widthPx = props.widthPx ? Number(props.widthPx) : undefined;
  return (
    <div className="py-4" style={widthPx ? { maxWidth: widthPx, marginInline: "auto" } : undefined}>
      {/* eslint-disable-next-line @next/next/no-img-element */}
      <img src={url} alt={altText} className="w-full h-auto rounded-xl2" />
      {props.caption ? (
        <p className="mt-2 text-center text-xs text-neutral-500">{String(props.caption)}</p>
      ) : null}
    </div>
  );
}

function ButtonBlock({ props }: { props: Record<string, unknown> }) {
  // This site's Button component only implements primary/outline/ghost (no
  // distinct "secondary" brand color exists in LarCare's Tailwind theme yet);
  // map the catalog's "secondary" to "outline" rather than rendering nothing.
  const rawVariant = String(props.variant || "primary");
  const variant = rawVariant === "outline" ? "outline" : rawVariant === "secondary" ? "outline" : "primary";
  return (
    <div className="py-4">
      <ButtonLink href={String(props.href || "#")} variant={variant}>
        {String(props.label || "")}
      </ButtonLink>
    </div>
  );
}

function ColumnsBlock({
  props,
  children
}: {
  props: Record<string, unknown>;
  children: WebBlock[];
}) {
  const columnCount = Number(props.columnCount) || 2;
  const gapPx = Number(props.gapPx) || 24;
  const colsClass = columnCount === 4 ? "lg:grid-cols-4" : columnCount === 3 ? "lg:grid-cols-3" : "md:grid-cols-2";

  return (
    <section className="py-10">
      <Container>
        <div className={`grid grid-cols-1 ${colsClass} items-center`} style={{ gap: gapPx }}>
          {children.map((child) => (
            <BlockNode key={child.id} block={child} />
          ))}
        </div>
      </Container>
    </section>
  );
}

async function ProductGridBlock({ props }: { props: Record<string, unknown> }) {
  const columns = Number(props.columns) || 3;
  const limit = props.limit ? Number(props.limit) : undefined;
  let products = await getStoreProducts();
  if (limit) products = products.slice(0, limit);
  if (products.length === 0) return null;
  const colsClass = columns === 2 ? "sm:grid-cols-2" : columns === 4 ? "sm:grid-cols-2 lg:grid-cols-4" : "sm:grid-cols-2 lg:grid-cols-3";
  return (
    <section className="py-10">
      <Container className={`grid grid-cols-1 ${colsClass} gap-6`}>
        {products.map((p) => (
          <StoreProductCard key={p.slug} product={p} />
        ))}
      </Container>
    </section>
  );
}

async function ServiceGridBlock({ props }: { props: Record<string, unknown> }) {
  const columns = Number(props.columns) || 3;
  const limit = props.limit ? Number(props.limit) : undefined;
  const featuredOnly = Boolean(props.featuredOnly);
  let services = await getCareServices();
  services = [...services].sort((a, b) => a.order - b.order);
  if (featuredOnly) services = services.filter((s) => s.isFeaturedOnHome);
  if (limit) services = services.slice(0, limit);
  if (services.length === 0) return null;
  const colsClass = columns === 2 ? "md:grid-cols-2" : columns === 4 ? "md:grid-cols-2 lg:grid-cols-4" : "md:grid-cols-2 lg:grid-cols-3";
  return (
    <section className="py-10">
      <Container className={`grid grid-cols-1 ${colsClass} gap-6`}>
        {services.map((service) => (
          <ServiceCard key={service.slug} service={service} />
        ))}
      </Container>
    </section>
  );
}

async function StatsGridBlock({ props }: { props: Record<string, unknown> }) {
  const columns = Number(props.columns) || 3;
  const stats = await getAboutStats();
  if (stats.length === 0) return null;
  const colsClass = columns === 2 ? "md:grid-cols-2" : columns === 4 ? "md:grid-cols-2 lg:grid-cols-4" : "md:grid-cols-2 lg:grid-cols-3";
  return (
    <section className="py-10">
      <Container className={`grid grid-cols-1 ${colsClass} gap-6`}>
        {stats.map((stat) => (
          <div key={stat.title} className="rounded-xl2 bg-white border border-neutral-200 p-8 text-center">
            <div className="mx-auto mb-4 h-12 w-12 rounded-full border border-accent-500 flex items-center justify-center text-accent-500">
              ★
            </div>
            <p className="text-neutral-900 font-medium">{stat.title}</p>
          </div>
        ))}
      </Container>
    </section>
  );
}

async function CoreValueGridBlock() {
  const values = await getCoreValues();
  if (values.length === 0) return null;
  return (
    <section className="py-10">
      <Container className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-8 divide-y lg:divide-y-0 lg:divide-x divide-neutral-200">
        {values.map((value) => (
          <div key={value.title} className="pt-8 lg:pt-0 lg:px-6 first:pt-0">
            <div className="h-10 w-10 rounded-full border border-accent-500 flex items-center justify-center text-accent-500 mb-3">
              ●
            </div>
            <h3 className="font-medium text-neutral-900">{value.title}</h3>
            <p className="mt-2 text-sm text-neutral-600">{value.description}</p>
          </div>
        ))}
      </Container>
    </section>
  );
}

async function JobGridBlock({ props }: { props: Record<string, unknown> }) {
  const columns = Number(props.columns) || 4;
  const jobs = await getJobOpenings();
  if (jobs.length === 0) return null;
  const colsClass = columns === 2 ? "sm:grid-cols-2" : columns === 3 ? "sm:grid-cols-2 lg:grid-cols-3" : "sm:grid-cols-2 lg:grid-cols-4";
  return (
    <section className="py-10">
      <Container className={`grid grid-cols-1 ${colsClass} gap-6`}>
        {jobs.map((job) => (
          <div key={job.slug} className="rounded-xl2 border border-neutral-200 bg-neutral-100 p-6">
            <h3 className="font-medium text-neutral-900">{job.title}</h3>
            <p className="mt-1 text-xs uppercase tracking-wide text-neutral-500">{job.type}</p>
            <p className="mt-3 text-sm text-neutral-600">{job.summary}</p>
          </div>
        ))}
      </Container>
    </section>
  );
}

async function TestimonialGridBlock() {
  const testimonials = await getTestimonials();
  return (
    <Container>
      <CustomerReviews testimonials={testimonials} />
    </Container>
  );
}

function TrustBadgesBlock({ props }: { props: Record<string, unknown> }) {
  const badges = Array.isArray(props.badges)
    ? (props.badges as { icon: string; title: string; text: string }[])
    : [];
  if (badges.length === 0) return null;
  return (
    <section className="py-10">
      <Container className="grid grid-cols-1 sm:grid-cols-3 gap-8">
        {badges.map((b) => (
          <div key={b.title} className="text-center">
            <div className="mx-auto mb-3 h-12 w-12 rounded-full border border-accent-500 flex items-center justify-center text-2xl">
              {b.icon}
            </div>
            <h4 className="font-medium text-neutral-900">{b.title}</h4>
            <p className="mt-1 text-sm text-neutral-600">{b.text}</p>
          </div>
        ))}
      </Container>
    </section>
  );
}

async function FormEmbedBlock({ props }: { props: Record<string, unknown> }) {
  const formKey = String(props.formKey || "");
  const schema = await getFormSchema(formKey);
  if (!schema) return null;
  return (
    <section className="py-10">
      <Container className="max-w-2xl mx-auto">
        <DynamicForm formKey={schema.formKey} fields={schema.fields} successMessage={schema.successMessage} />
      </Container>
    </section>
  );
}

function TestimonialBlock({ props }: { props: Record<string, unknown> }) {
  const rating = props.rating ? Number(props.rating) : null;
  return (
    <div className="rounded-xl2 border border-neutral-200 bg-white p-6">
      {rating ? <p className="text-accent-500">{"★".repeat(rating)}</p> : null}
      <p className="mt-2 text-neutral-700 italic">&ldquo;{String(props.quote || "")}&rdquo;</p>
      <p className="mt-3 text-sm font-medium text-neutral-900">{String(props.authorName || "")}</p>
    </div>
  );
}

function FaqAccordionBlock({ props }: { props: Record<string, unknown> }) {
  const items = Array.isArray(props.items)
    ? (props.items as { question: string; answer: string }[])
    : [];
  return (
    <section className="py-10">
      <Container className="max-w-2xl mx-auto divide-y divide-neutral-200 border-t border-neutral-200">
        {items.map((item, i) => (
          <details key={i} className="py-4 group">
            <summary className="cursor-pointer font-medium text-neutral-900 list-none flex items-center justify-between">
              {item.question}
              <span aria-hidden className="text-neutral-400 group-open:rotate-45 transition-transform">+</span>
            </summary>
            <p className="mt-2 text-sm text-neutral-600">{item.answer}</p>
          </details>
        ))}
      </Container>
    </section>
  );
}
