﻿// Services — LPA banner (always visible, his most requested service) plus a
// category explorer: pick a category on the left, the panel cross-fades to show
// that category's services. Keeps the section short while every service stays
// one click away. window.__openService(catId) lets tiles/nav open a category.
// Card hrefs point at this site's service pages (styled placeholders for now).
const { useState: useStateSv, useRef: useRefSv } = React;

const SERVICE_CATS = [
  {
    id: 'wills',
    label: 'Wills',
    icon: 'fileText',
    hint: 'Make or update your Will',
    blurb: 'Most people start here. However you make your Will, the same careful, plain-English advice runs through it.',
    items: [
      { icon: 'monitor', tone: 'blue', title: 'Online Wills', body: 'Expert one-to-one advice over a video call. Ideal for busy schedules or anyone further afield.', href: 'online-wills.html' },
      { icon: 'home', tone: 'coral', title: 'Home Visit Wills', body: 'We come to you. A relaxed, face-to-face conversation in the comfort of your own home.', href: 'home-visit-wills.html' },
      { icon: 'briefcase', tone: 'blue', title: 'Wills for Business Owners', body: 'Specialist Will advice that protects your company, your family and the legacy you have built.', href: 'wills-for-business-owners.html' },
    ],
  },
  {
    id: 'lpa',
    label: 'Power of Attorney',
    icon: 'heartHandshake',
    hint: 'Choose who can act for you',
    blurb: 'Give the people you trust the legal power to act for you, or for your business, if you ever cannot act yourself.',
    items: [
      { icon: 'heartHandshake', tone: 'blue', title: 'Lasting Power of Attorney', body: 'Full advice and support, in person or online. We handle the paperwork from start to finish.', href: 'lasting-power-of-attorney.html' },
      { icon: 'clock', tone: 'gold', title: 'Fast Track LPA', body: 'A short online appointment and your documents within 48 hours. Reduced price for straightforward cases.', href: 'fast-track-lpa.html' },
      { icon: 'briefcase', tone: 'coral', title: 'Business LPA', body: 'Keep your business running if you lose capacity. Appoint someone you trust to act for the business.', href: 'business-lasting-power-of-attorney.html' },
    ],
  },
  {
    id: 'trusts',
    label: 'Trusts & Tax',
    icon: 'shieldCheck',
    hint: 'Protect your home and assets',
    blurb: 'More control over how your home and savings pass on, during your lifetime and after it, with less lost to tax along the way.',
    items: [
      { icon: 'shieldCheck', tone: 'gold', title: 'Family & Property Trusts', body: 'Protect your home and assets and add flexibility, so loved ones inherit exactly as you intend.', href: 'family-property-trusts.html' },
      { icon: 'home', tone: 'coral', title: 'Property Protection Trusts', body: 'Make sure your home stays in the family, even if life takes an unexpected turn.', href: 'property-protection-trusts.html' },
      { icon: 'landmark', tone: 'blue', title: 'Lifetime Trusts', body: 'A flexible way to protect your home for future generations and avoid the delays of probate.', href: 'lifetime-trusts.html' },
      { icon: 'pound', tone: 'gold', title: 'Inheritance Tax Planning', body: 'Practical, honest advice to help keep more of your estate in the family.', href: 'inheritance-tax-planning.html' },
    ],
  },
  {
    id: 'after',
    label: 'Probate & Storage',
    icon: 'lock',
    hint: 'Help for executors and families',
    blurb: 'Support for the practical side, and safe keeping for the documents that matter most.',
    items: [
      { icon: 'scale', tone: 'blue', title: 'Worry-free Probate', body: 'Fixed-price probate support agreed upfront, from the Grant application to full estate administration.', href: 'probate.html' },
      { icon: 'lock', tone: 'gold', title: 'Will Storage & Updates', body: 'Secure storage and easy updates, so your Will is always safe, current and exactly where it should be.', href: 'will-storage-and-updates.html' },
    ],
  },
];

const TONES = {
  blue: { bg: '#EAF1FA', bgHover: '#D8E6F8', fg: '#4A6FA4' },
  coral: { bg: 'rgba(244,104,95,0.13)', bgHover: 'rgba(244,104,95,0.22)', fg: '#E0564D' },
  gold: { bg: 'rgba(255,204,87,0.22)', bgHover: 'rgba(255,204,87,0.36)', fg: '#C9912A' },
};

function ServiceCard({ s }) {
  const reduced = usePrefersReducedMotion();
  const t = TONES[s.tone];
  return (
    <a
      href={s.href}
      className="group flex h-full flex-col rounded-2xl bg-white p-6 sm:p-7"
      style={{ boxShadow: '0 22px 56px -34px rgba(26,48,102,0.45)', transition: 'transform 320ms ' + EASE + ', box-shadow 320ms ' + EASE }}
      onMouseEnter={(e) => {
        if (!reduced) { e.currentTarget.style.transform = 'translateY(-3px)'; e.currentTarget.style.boxShadow = '0 32px 70px -34px rgba(26,48,102,0.5)'; }
        const b = e.currentTarget.querySelector('[data-badge]'); if (b) b.style.background = t.bgHover;
        const a = e.currentTarget.querySelector('[data-arrow]'); if (a && !reduced) a.style.transform = 'translateX(4px)';
      }}
      onMouseLeave={(e) => {
        e.currentTarget.style.transform = 'translateY(0)'; e.currentTarget.style.boxShadow = '0 22px 56px -34px rgba(26,48,102,0.45)';
        const b = e.currentTarget.querySelector('[data-badge]'); if (b) b.style.background = t.bg;
        const a = e.currentTarget.querySelector('[data-arrow]'); if (a) a.style.transform = 'translateX(0)';
      }}
    >
      <span data-badge className="ico-hover inline-flex items-center justify-center rounded-full" style={{ width: 52, height: 52, background: t.bg, color: t.fg, transition: 'background-color 320ms ' + EASE }}>
        <Icon name={s.icon} size={24} strokeWidth={1.7} />
      </span>
      <h3 className="mt-4 font-display font-normal text-navy" style={{ fontSize: 20, letterSpacing: '-0.01em' }}>{s.title}</h3>
      <p className="mt-2 flex-1 font-sans text-ink" style={{ fontSize: 14, lineHeight: 1.6 }}>{s.body}</p>
      <span className="mt-5 inline-flex items-center gap-1.5 font-sans font-semibold text-gold-deep" style={{ fontSize: 14 }}>
        <span className="fp-underline">Learn more</span>
        <span data-arrow style={{ display: 'inline-flex', transition: 'transform 280ms ' + EASE }}>
          <Icon name="arrowRight" size={16} strokeWidth={2.2} />
        </span>
      </span>
    </a>
  );
}

// Always-visible LPA banner: his most-requested service gets hero billing
// inside the services section.
function FastTrackFeature() {
  const reduced = usePrefersReducedMotion();
  const mag = useMagnetic(3);
  const points = [
    { icon: 'heartHandshake', text: 'Property, finance, health and welfare LPAs' },
    { icon: 'fileText', text: 'Paperwork and registration handled for you' },
    { icon: 'home', text: 'At your home or online, whichever suits' },
  ];
  return (
    <Reveal>
      <div
        id="fast-track"
        className="group relative mt-10 block overflow-hidden rounded-[26px]"
        style={{
          background: 'linear-gradient(120deg, #1A3066 0%, #2C4A8F 78%)',
          boxShadow: '0 30px 70px -34px rgba(26,48,102,0.65)',
          transition: 'transform 320ms ' + EASE + ', box-shadow 320ms ' + EASE,
        }}
        onMouseEnter={(e) => { if (!reduced) { e.currentTarget.style.transform = 'translateY(-3px)'; e.currentTarget.style.boxShadow = '0 40px 80px -34px rgba(26,48,102,0.7)'; } }}
        onMouseLeave={(e) => { e.currentTarget.style.transform = 'translateY(0)'; e.currentTarget.style.boxShadow = '0 30px 70px -34px rgba(26,48,102,0.65)'; }}
        data-dark="true"
      >
        <div aria-hidden="true" style={{ position: 'absolute', top: -120, right: -80, width: 320, height: 320, borderRadius: '50%', background: 'radial-gradient(circle, rgba(255,204,87,0.28), transparent 65%)' }} />
        <div className="relative grid grid-cols-1 items-center gap-6 p-7 sm:p-9 lg:grid-cols-12 lg:gap-8">
          <div className="lg:col-span-8">
            <span className="inline-flex items-center gap-2 rounded-full px-3.5 py-1.5 font-sans font-semibold text-[12px] uppercase text-navy" style={{ background: 'linear-gradient(120deg,#FFCC57,#F0B83C)', letterSpacing: '0.14em' }}>
              <Icon name="sparkles" size={13} strokeWidth={2.2} /> Most requested
            </span>
            <h3 className="mt-4 font-display font-normal text-white" style={{ fontSize: 'clamp(24px,3.2vw,34px)', lineHeight: 1.15, letterSpacing: '-0.01em' }}>
              Lasting Power of Attorney
            </h3>
            <p className="mt-3 font-sans" style={{ fontSize: 16, lineHeight: 1.6, maxWidth: '58ch', color: 'rgba(255,255,255,0.88)' }}>
              Choose the people you trust to make decisions about your finances, health and care if you ever cannot make them yourself. We talk it through in plain English, then handle the documents from start to finish. In a hurry? Ask about our 48-hour Fast Track option.
            </p>
            <ul className="mt-5 flex flex-col gap-2.5 sm:flex-row sm:flex-wrap sm:gap-x-7">
              {points.map((p) => (
                <li key={p.text} className="flex items-center gap-2.5 font-sans text-[14.5px]" style={{ color: 'rgba(255,255,255,0.92)' }}>
                  <span className="inline-flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full" style={{ background: 'rgba(255,204,87,0.2)', color: '#FFCC57' }}>
                    <Icon name={p.icon} size={13} strokeWidth={2.2} />
                  </span>
                  {p.text}
                </li>
              ))}
            </ul>
          </div>
          <div className="flex flex-col items-start gap-3 lg:col-span-4 lg:items-end lg:justify-self-end">
            <a
              ref={mag.ref}
              onMouseMove={mag.onMouseMove}
              onMouseLeave={mag.onMouseLeave}
              href="book-an-appointment.html"
              className="cta-sheen inline-flex items-center gap-2 rounded-full bg-gold px-7 py-4 font-sans font-semibold text-[16px] text-navy hover:bg-gold-deep"
              style={{ boxShadow: '0 14px 30px -12px rgba(240,184,60,0.75)', transition: 'transform 250ms ' + EASE + ', background-color 250ms ' + EASE }}
            >
              Start your LPA
              <span data-arrow style={{ display: 'inline-flex', transition: 'transform 280ms ' + EASE }}>
                <Icon name="arrowRight" size={17} strokeWidth={2.2} />
              </span>
            </a>
            <a
              href="lasting-power-of-attorney.html"
              className="inline-flex items-center gap-1.5 font-sans font-semibold text-[14px]"
              style={{ color: '#FFCC57' }}
            >
              <span className="fp-underline">Learn more about LPAs</span>
              <Icon name="arrowRight" size={14} strokeWidth={2.2} />
            </a>
          </div>
        </div>
      </div>
    </Reveal>
  );
}

function CatButton({ cat, active, flash, onSelect }) {
  return (
    <button
      type="button"
      role="tab"
      aria-selected={active}
      onClick={onSelect}
      className="group flex w-full items-center gap-3.5 rounded-2xl px-4 py-3.5 text-left lg:px-5 lg:py-4"
      style={{
        background: active ? '#fff' : 'transparent',
        boxShadow: active
          ? (flash
              ? '0 18px 44px -26px rgba(26,48,102,0.5), inset 3px 0 0 #F0B83C, 0 0 0 3px rgba(240,184,60,0.5)'
              : '0 18px 44px -26px rgba(26,48,102,0.5), inset 3px 0 0 #F0B83C')
          : 'inset 0 0 0 1px rgba(26,48,102,0.12)',
        transition: 'background-color 260ms ' + EASE + ', box-shadow 600ms ' + EASE,
        flexShrink: 0,
      }}
    >
      <span className="ico-hover inline-flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-full" style={{ background: active ? 'rgba(255,204,87,0.25)' : 'rgba(255,255,255,0.7)', color: active ? '#C9912A' : '#4A6FA4', transition: 'background-color 260ms ' + EASE }}>
        <Icon name={cat.icon} size={20} strokeWidth={1.8} />
      </span>
      <span className="min-w-0">
        <span className="block font-sans font-semibold text-navy" style={{ fontSize: 15, lineHeight: 1.3 }}>{cat.label}</span>
        <span className="hidden font-sans text-stone sm:block" style={{ fontSize: 12.5, lineHeight: 1.35, marginTop: 1 }}>{cat.hint}</span>
      </span>
    </button>
  );
}

function Services() {
  const [cat, setCat] = useStateSv('wills');
  const [visible, setVisible] = useStateSv(true);
  const [flash, setFlash] = useStateSv(false);
  // Mobile rail scroll affordances: chevron + fade while more categories are
  // off-screen right; a plain fade once some are off-screen left.
  const [moreRight, setMoreRight] = useStateSv(true);
  const [moreLeft, setMoreLeft] = useStateSv(false);
  const railRef = useRefSv(null);
  const staticRender = useStaticRender();
  const dur = staticRender ? 0 : 240;
  const pendingT = useRefSv(null);
  const flashT = useRefSv(null);

  const updateMoreRight = () => {
    const el = railRef.current;
    if (!el) return;
    setMoreRight(el.scrollWidth - el.clientWidth - el.scrollLeft > 12);
    setMoreLeft(el.scrollLeft > 12);
  };
  React.useLayoutEffect(() => {
    updateMoreRight();
    window.addEventListener('resize', updateMoreRight);
    // ResizeObserver catches layout/size changes resize events miss (font load,
    // emulated viewports, the lg breakpoint flipping the rail orientation).
    let ro;
    if ('ResizeObserver' in window && railRef.current) {
      ro = new ResizeObserver(updateMoreRight);
      ro.observe(railRef.current);
    }
    return () => {
      window.removeEventListener('resize', updateMoreRight);
      if (ro) ro.disconnect();
    };
  }, []);

  // One-time peek bounce: when the rail first scrolls into view on mobile, it
  // slides left ~52px and settles back, physically showing that it scrolls.
  // Driven frame-by-frame (no smooth-scroll API), once only, reduced-motion aware.
  const bounced = useRefSv(false);
  React.useLayoutEffect(() => {
    const rail = railRef.current;
    if (!rail || staticRender) return undefined;
    const reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    if (reduce || !('IntersectionObserver' in window)) return undefined;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((entry) => {
        if (!entry.isIntersecting || bounced.current) return;
        if (rail.scrollWidth - rail.clientWidth < 40 || rail.scrollLeft > 4) { io.disconnect(); return; }
        bounced.current = true;
        io.disconnect();
        const start = performance.now();
        const DUR = 950;
        const tick = (now) => {
          const t = Math.min(1, (now - start) / DUR);
          // sine pulse out-and-back, eased
          rail.scrollLeft = Math.round(Math.sin(t * Math.PI) * 52);
          if (t < 1) requestAnimationFrame(tick);
          else { rail.scrollLeft = 0; updateMoreRight(); }
        };
        requestAnimationFrame(tick);
      });
    }, { threshold: 0.6 });
    io.observe(rail);
    return () => io.disconnect();
  }, [staticRender]);

  const select = (id) => {
    if (id === cat) return;
    clearTimeout(pendingT.current);
    setVisible(false);
    pendingT.current = setTimeout(() => { setCat(id); setVisible(true); }, dur);
  };

  // Quick tiles and the header dropdown use this to open a category directly.
  // Scrolls to the explorer itself (not the section top) so the chosen
  // category's cards are the first thing in view, and pulses the active tab.
  React.useLayoutEffect(() => {
    window.__openService = (id) => {
      if (SERVICE_CATS.some((c) => c.id === id)) select(id);
      const el = document.getElementById('service-explorer');
      if (el) scrollToY(el.getBoundingClientRect().top + window.pageYOffset - 96);
      clearTimeout(flashT.current);
      setFlash(true);
      flashT.current = setTimeout(() => setFlash(false), 1600);
    };
    return () => { delete window.__openService; };
  });

  const active = SERVICE_CATS.find((c) => c.id === cat);
  const panelStyle = staticRender ? {} : {
    opacity: visible ? 1 : 0,
    transform: visible ? 'none' : 'translateY(8px)',
    transition: `opacity ${dur}ms ${EASE}, transform ${dur}ms ${EASE}`,
  };

  return (
    <section id="services" className="relative overflow-hidden bg-blue-light" style={{ paddingTop: 'clamp(52px,7vw,84px)', paddingBottom: 'clamp(52px,7vw,84px)' }}>
      <Grain opacity={0.04} />
      <Blob color="#FFCC57" size={340} opacity={0.16} blur={10} speed={30} rotate={6} style={{ top: '-90px', right: '-80px' }} />
      <Blob color="#F4685F" size={280} opacity={0.12} blur={10} speed={-24} rotate={-5} style={{ bottom: '60px', left: '-110px' }} />

      <div className="relative mx-auto max-w-[1180px] px-5 sm:px-7">
        <Reveal className="max-w-[640px]">
          <p className="font-sans font-semibold uppercase text-gold-deep" style={{ fontSize: 13, letterSpacing: '0.18em' }}>Our services</p>
          <h2 className="mt-3 font-display font-normal text-navy" style={{ fontSize: 'clamp(32px,4.5vw,48px)', lineHeight: 1.12, letterSpacing: '-0.01em' }}>
            More than Wills: full estate planning
          </h2>
          <p className="mt-4 font-sans text-stone" style={{ fontSize: 17, lineHeight: 1.6, maxWidth: '56ch' }}>
            From a simple Will to trusts and Lasting Power of Attorney, our{' '}
            <a href="estate-planning.html" className="font-medium text-navy underline-offset-2 hover:underline">estate planning</a>
            {' '}and{' '}
            <a href="legal-services.html" className="font-medium text-navy underline-offset-2 hover:underline">legal services</a>
            {' '}put the right protections in place for the people and things you care about.
          </p>
          <p className="mt-3 font-sans text-stone" style={{ fontSize: 13, lineHeight: 1.55, maxWidth: '64ch' }}>
            {SWW_DISCLAIMER}
          </p>
        </Reveal>

        <FastTrackFeature />

        {/* Category explorer */}
        <Reveal delay={120} className="mt-9">
          <div id="service-explorer" className="grid grid-cols-1 gap-5 lg:grid-cols-12 lg:gap-8">
            {/* Category rail: vertical on desktop, horizontal scroll on mobile.
                Mobile affordance: tiles sized so the next one always peeks, plus a
                right-edge fade with a tappable chevron that hides at rail end. */}
            <div className="relative lg:col-span-4">
              <div
                ref={railRef}
                onScroll={updateMoreRight}
                role="tablist"
                aria-label="Service categories"
                className="flex gap-2.5 overflow-x-auto pb-1 lg:flex-col lg:gap-3 lg:overflow-visible lg:pb-0"
                style={{ WebkitOverflowScrolling: 'touch' }}
              >
                {SERVICE_CATS.map((c) => (
                  <div key={c.id} className="min-w-[200px] flex-shrink-0 lg:min-w-0">
                    <CatButton cat={c} active={c.id === cat} flash={flash && c.id === cat} onSelect={() => select(c.id)} />
                  </div>
                ))}
              </div>
              {/* Left fade only (no button): signals scrolled-away tiles without clutter */}
              <div
                aria-hidden="true"
                className="pointer-events-none absolute inset-y-0 left-0 lg:hidden"
                style={{
                  width: 36,
                  paddingBottom: 4,
                  background: 'linear-gradient(270deg, rgba(234,241,250,0), #EAF1FA 82%)',
                  opacity: moreLeft ? 1 : 0,
                  transition: 'opacity 280ms ' + EASE,
                }}
              />
              {/* Fade + chevron, mobile only, gone once fully scrolled */}
              <div
                aria-hidden={!moreRight}
                className="absolute inset-y-0 right-0 flex items-center justify-end lg:hidden"
                style={{
                  width: 64,
                  paddingBottom: 4,
                  background: 'linear-gradient(90deg, rgba(234,241,250,0), #EAF1FA 78%)',
                  opacity: moreRight ? 1 : 0,
                  pointerEvents: moreRight ? 'auto' : 'none',
                  transition: 'opacity 280ms ' + EASE,
                }}
              >
                <button
                  type="button"
                  aria-label="Show more service categories"
                  onClick={() => { const el = railRef.current; if (el) el.scrollLeft += 210; setTimeout(updateMoreRight, 60); }}
                  className="mr-0.5 inline-flex h-11 w-11 items-center justify-center"
                  style={{ background: 'transparent', border: 0, padding: 0 }}
                >
                  <span
                    className="inline-flex h-8 w-8 items-center justify-center rounded-full text-navy"
                    style={{ background: 'rgba(255,255,255,0.92)', boxShadow: '0 4px 14px -6px rgba(26,48,102,0.4)', border: '1px solid rgba(26,48,102,0.12)' }}
                  >
                    <span className="rail-nudge inline-flex">
                      <Icon name="chevronDown" size={16} strokeWidth={2} style={{ transform: 'rotate(-90deg)' }} />
                    </span>
                  </span>
                </button>
              </div>
            </div>

            {/* Panel */}
            <div role="tabpanel" className="lg:col-span-8" style={panelStyle}>
              <p className="font-display italic text-blue" style={{ fontSize: 17, lineHeight: 1.5 }}>{active.blurb}</p>
              <div className="mt-4 grid grid-cols-1 items-stretch gap-5 sm:grid-cols-2">
                {active.items.map((s) => <ServiceCard key={s.title} s={s} />)}
              </div>
            </div>
          </div>
        </Reveal>
      </div>
    </section>
  );
}

Object.assign(window, { Services });
