"use client";

import Link from "next/link";
import { motion, useReducedMotion } from "motion/react";
import { paths } from "@/content/paths";
import { Button } from "@/components/ui/Button";
import { Magnetic } from "@/components/motion/Magnetic";
import { CountUp } from "@/components/motion/CountUp";

interface Stat {
  value: number;
  suffix: string;
  label: string;
}

/**
 * Hero text. Lines rise out of clipped rows on load, the way a heading would
 * appear if it were being knitted course by course.
 */
export function HeroCopy({
  tagline,
  positioning,
  founded,
  markets,
  stats,
}: {
  tagline: string;
  positioning: string;
  founded: number;
  markets: string[];
  stats: Stat[];
}) {
  const reduced = useReducedMotion();

  // Only the timing responds to the motion preference. The variants themselves
  // are always applied, so the server and the client render identical markup.
  const line = {
    hidden: { y: "110%", opacity: 0 },
    shown: {
      y: "0%",
      opacity: 1,
      transition: {
        duration: reduced ? 0 : 1.05,
        ease: [0.16, 1, 0.3, 1] as const,
      },
    },
  };

  const container = {
    hidden: {},
    shown: {
      transition: {
        staggerChildren: reduced ? 0 : 0.09,
        delayChildren: reduced ? 0 : 0.35,
      },
    },
  };

  const words = tagline.split(" ");

  return (
    <motion.div
      className="max-w-4xl"
      variants={container}
      initial="hidden"
      animate="shown"
    >
      <div className="overflow-hidden">
        <motion.p
          variants={line}
          className="eyebrow flex items-center gap-3"
        >
          <span className="h-px w-10 bg-[var(--thread)]" />
          Est. {founded} &middot; Multan and Lahore, Pakistan
        </motion.p>
      </div>

      <h1 className="display-xl mt-6 text-balance text-[var(--cotton)]">
        <span className="sr-only">{tagline}</span>
        <span aria-hidden="true">
          {words.map((word, i) => (
            <span
              key={i}
              className="inline-block overflow-hidden align-bottom"
              style={{ paddingBottom: "0.1em", marginBottom: "-0.1em" }}
            >
              <motion.span
                className="inline-block"
                variants={line}
              >
                {i === words.length - 1 ? (
                  <em className="not-italic text-[var(--thread)]">{word}</em>
                ) : (
                  word
                )}
                {i < words.length - 1 ? " " : ""}
              </motion.span>
            </span>
          ))}
        </span>
      </h1>

      <motion.p
        variants={line}
        className="lede mt-7 max-w-xl text-pretty"
      >
        {positioning}. Spinning, knitting, dyeing and stitching under one roof,
        shipping to {listify(markets)}.
      </motion.p>

      <motion.div
        variants={line}
        className="mt-10 flex flex-wrap items-center gap-3"
      >
        <Magnetic>
          <Button href="/knitwear">Explore the divisions</Button>
        </Magnetic>
        <Magnetic>
          <Button href="/contact" variant="outline">
            Start an enquiry
          </Button>
        </Magnetic>
      </motion.div>

      <motion.dl
        variants={line}
        className="mt-14 grid max-w-2xl grid-cols-2 gap-x-6 gap-y-8 border-t border-[var(--rule)] pt-8 sm:grid-cols-4"
      >
        {stats.map((stat) => (
          <div key={stat.label}>
            <dt className="sr-only">{stat.label}</dt>
            <dd>
              <span className="data block text-2xl text-[var(--cotton)] sm:text-3xl">
                <CountUp
                  to={stat.value}
                  suffix={stat.suffix}
                  separator={stat.value > 1999}
                />
              </span>
              <span className="mt-1.5 block font-mono text-[10px] uppercase tracking-[0.2em] text-[var(--melange)]">
                {stat.label}
              </span>
            </dd>
          </div>
        ))}
      </motion.dl>

      {/* Five routes in, offered quietly. Not everyone arrives for the same
          reason, but a wall of choices before the reader knows anything about
          the mill is asking them to classify themselves too early. */}
      <motion.p
        variants={line}
        className="mt-8 flex flex-wrap items-baseline gap-x-2 gap-y-2 text-sm text-[var(--melange)]"
      >
        <span className="font-mono text-[10px] uppercase tracking-[0.2em]">
          Here for
        </span>
        {paths.map((path, i) => (
          <span key={path.id} className="flex items-baseline gap-2">
            <Link
              href={`/contact?intent=${path.id}`}
              className="text-[var(--cotton)]/80 underline decoration-[var(--rule)] underline-offset-4 transition-colors duration-300 hover:text-[var(--thread)] hover:decoration-[var(--thread)]"
            >
              {path.short}
            </Link>
            {i < paths.length - 1 ? (
              <span aria-hidden="true" className="text-[var(--melange)]/50">
                &middot;
              </span>
            ) : null}
          </span>
        ))}
      </motion.p>
    </motion.div>
  );
}

function listify(items: string[]): string {
  if (items.length <= 1) return items[0] ?? "";
  return `${items.slice(0, -1).join(", ")} and ${items[items.length - 1]}`;
}
