// Backend content is fetched only when a request arrives.
export const dynamic = 'force-dynamic';

import Link from 'next/link';
import { notFound } from 'next/navigation';
import type { Metadata } from 'next';
import { parseServiceSegment, paths } from '@justice-choice/seo-engine';
import { api } from '@/lib/api';
import { fmtDate, fmtNumber } from '@/lib/format';
import { pageMetadata } from '@/lib/meta';
import { abs } from '@/lib/site';
import type { CityHub, RankingPageData } from '@/lib/types';
import { Breadcrumbs } from '@/components/Breadcrumbs';
import { Faq } from '@/components/Faq';
import { JsonLd } from '@/components/JsonLd';
import { LawyerListItem, RankedRow } from '@/components/LawyerItems';
import { LeadForm } from '@/components/LeadForm';
import { LedgerLegend } from '@/components/ScoreLedger';
import { ReportForm } from '@/components/ReportForm';
import { Section, Stat } from '@/components/Section';
import { Beacon } from '@/components/Beacon';
import { VerificationBadge } from '@/components/Badges';
import { Pagination } from '@/components/Pagination';
import {
  ArrowRightIcon,
  BadgeCheckIcon,
  BookOpenIcon,
  BuildingIcon,
  CalendarIcon,
  ChartIcon,
  ClockIcon,
  ExternalLinkIcon,
  InfoIcon,
  LandmarkIcon,
  LockIcon,
  MapPinIcon,
  PracticeAreaIcon,
  ScaleIcon,
  SearchIcon,
  TrendingUpIcon,
  UsersIcon,
} from '@/components/Icons';

type Props = { params: Promise<{ country: string; city: string; service: string }>; searchParams: Promise<{ page?: string }> };

async function resolve(country: string, city: string, service: string) {
  const practice = parseServiceSegment(service);
  if (practice === undefined) notFound();
  return practice;
}

export async function generateMetadata({ params, searchParams }: Props): Promise<Metadata> {
  const { country, city, service } = await params;
  const { page } = await searchParams;
  const practice = await resolve(country, city, service);
  if (practice === null) {
    const d = await api<CityHub>(`/cities/${encodeURIComponent(city)}?country=${encodeURIComponent(country)}`);
    const meta = pageMetadata(d.seo, { path: paths.city(country, city), title: `Lawyers in ${d.city.name}` });
    // Paginated pages stay crawlable but are not indexed (§20 control pagination)
    if (Number(page) > 1) meta.robots = { index: false, follow: true };
    return meta;
  }
  const d = await api<RankingPageData>(`/rankings/${encodeURIComponent(city)}/${encodeURIComponent(practice)}?country=${encodeURIComponent(country)}`);
  return pageMetadata(d.seo, { path: paths.cityPractice(country, city, practice), title: `Top ${d.practiceArea.name} Lawyers in ${d.city.name}` });
}

export default async function ServicePage({ params, searchParams }: Props) {
  const { country, city, service } = await params;
  const practice = await resolve(country, city, service);
  if (practice === null) return <CityHubView country={country} city={city} page={Math.max(1, Math.floor(Number((await searchParams).page)) || 1)} />;
  return <RankingView country={country} city={city} practice={practice} />;
}

function Resources({ items }: { items: { name: string; url?: string; note?: string }[] }) {
  return (
    <ul className="grid gap-3 sm:grid-cols-2">
      {items.map((r) => (
        <li key={r.name} className="card flex gap-3 p-4">
          <span className="grid h-9 w-9 shrink-0 place-items-center rounded-lg bg-sunken text-muted">
            <LandmarkIcon className="h-4 w-4" />
          </span>
          <div className="min-w-0">
            {r.url ? (
              <a href={r.url} rel="noopener nofollow" target="_blank" className="inline-flex items-center gap-1 font-semibold text-ledger hover:underline">
                {r.name}
                <ExternalLinkIcon className="h-3.5 w-3.5" />
              </a>
            ) : (
              <span className="font-semibold">{r.name}</span>
            )}
            {r.note && <p className="mt-1 text-sm leading-relaxed text-ink-2">{r.note}</p>}
          </div>
        </li>
      ))}
    </ul>
  );
}

const sticky = 'sticky-panel lead-panel lg:sticky lg:top-[calc(var(--header-h)+1.5rem)] lg:self-start';

// ─────────────────────────────────────────── City + practice ranking (§13)

async function RankingView({ country, city, practice }: { country: string; city: string; practice: string }) {
  const [d, consent] = await Promise.all([
    api<RankingPageData>(`/rankings/${encodeURIComponent(city)}/${encodeURIComponent(practice)}?country=${encodeURIComponent(country)}&limit=25`),
    api<{ text: string }>('/leads/consent-text', { revalidate: 300 }),
  ]);
  const path = paths.cityPractice(country, city, practice);
  const pa = d.practiceArea;
  const year = new Date().getFullYear();
  const verifiedPct = d.stats.professionals ? Math.round((d.stats.verified / d.stats.professionals) * 100) : 0;

  return (
    <div className="mx-auto max-w-6xl px-4 py-8 sm:px-6 sm:py-10">
      <Beacon event="ranking_view" entityType="ranking" />
      <Breadcrumbs
        items={[
          { label: 'Home', href: '/' },
          { label: d.city.country.name, href: paths.country(country) },
          { label: d.city.name, href: paths.city(country, city) },
          { label: `${pa.name} lawyers`, href: path },
        ]}
      />
      <header className="mt-6 grid gap-8 lg:grid-cols-[1fr_20rem] lg:gap-10">
        <div className="max-w-3xl">
          <p className="eyebrow">
            <PracticeAreaIcon slug={pa.slug} className="h-3.5 w-3.5" /> {pa.name} · {d.city.name}
          </p>
          <h1 className="mt-3 font-serif text-[2.25rem] font-semibold leading-[1.1] tracking-tight sm:text-[2.75rem]">
            Top {pa.name} Lawyers in {d.city.name}
          </h1>
          <div className="prose-legal mt-4 text-lg leading-relaxed text-ink-2">
            {d.intro ? (
              <p>{d.intro}</p>
            ) : (
              <p>
                {pa.description} This list compares {fmtNumber(d.stats.professionals)} {pa.name.toLowerCase()} lawyers practising in {d.city.name} on verified licences, years in this area, focus and sourced reputation.
              </p>
            )}
          </div>
          <ul className="mt-5 flex flex-wrap gap-x-5 gap-y-2 text-sm text-muted">
            <li className="inline-flex items-center gap-1.5">
              <CalendarIcon className="h-4 w-4" /> Updated {fmtDate(d.calculatedAt)}
            </li>
            <li className="inline-flex items-center gap-1.5">
              <ChartIcon className="h-4 w-4" /> Ranking <span className="num">{d.rankingVersion ?? '—'}</span>
            </li>
            <li>
              <Link href="/methodology/" className="inline-flex items-center gap-1.5 font-medium text-ledger hover:underline">
                <BookOpenIcon className="h-4 w-4" /> How we rank
              </Link>
            </li>
          </ul>
        </div>
        <dl className="card grid grid-cols-2 gap-5 self-end p-5 lg:grid-cols-1">
          <Stat value={fmtNumber(d.stats.professionals)} label="lawyers considered" icon={<UsersIcon className="h-5 w-5" />} />
          <Stat value={`${verifiedPct}%`} label={`${fmtNumber(d.stats.verified)} verified licences`} icon={<BadgeCheckIcon className="h-5 w-5" />} />
          {d.stats.averageExperience != null && <Stat value={d.stats.averageExperience} label="average years in practice" icon={<ClockIcon className="h-5 w-5" />} />}
        </dl>
      </header>

      <div className="mt-10 grid gap-10 lg:grid-cols-[1fr_20rem]">
        <div className="min-w-0 space-y-14">
          {d.sponsored.length > 0 && (
            <aside aria-label="Sponsored listings" className="rounded-xl border border-dashed border-sponsor/50 bg-sponsor-soft p-5">
              <p className="flex items-center gap-2 text-sm font-semibold text-sponsor">
                <InfoIcon className="h-4 w-4" /> Sponsored
              </p>
              <p className="mt-0.5 text-xs text-ink-2">Paid placement. Not part of the ranking below and does not affect any score.</p>
              <ul className="mt-4 space-y-3">
                {d.sponsored.map((s) => (
                  <li key={s.placementId} className="flex flex-wrap items-center gap-x-3 gap-y-1 rounded-lg bg-surface/70 px-3 py-2.5">
                    {s.lawyer ? (
                      <>
                        <Link href={paths.lawyer(s.lawyer.slug)} className="font-serif text-lg font-semibold hover:underline">
                          {s.lawyer.name}
                        </Link>
                        <VerificationBadge status={s.lawyer.verificationStatus} compact />
                        {s.lawyer.firm && <span className="text-sm text-ink-2">{s.lawyer.firm.name}</span>}
                      </>
                    ) : s.firm ? (
                      <>
                        <Link href={paths.firm(s.firm.slug)} className="inline-flex items-center gap-2 font-serif text-lg font-semibold hover:underline">
                          <BuildingIcon className="h-4 w-4 text-sponsor" />
                          {s.firm.name}
                        </Link>
                        <span className="line-clamp-1 text-sm text-ink-2">{s.firm.description}</span>
                      </>
                    ) : null}
                  </li>
                ))}
              </ul>
            </aside>
          )}

          <section aria-labelledby="ranking-h">
            <div className="flex flex-wrap items-end justify-between gap-2 border-b-2 border-ink/80 pb-3">
              <h2 id="ranking-h" className="flex items-center gap-2.5 font-serif text-2xl font-semibold tracking-tight">
                <TrendingUpIcon className="h-6 w-6 text-brass" /> The ranking
              </h2>
              <span className="text-sm text-muted">Score out of 100</span>
            </div>
            {d.ranked.length ? (
              <ol className="sm:-mx-4">
                {d.ranked.map((l) => (
                  <RankedRow key={l.id} l={l} weights={d.weights} practiceSlug={pa.slug} />
                ))}
              </ol>
            ) : (
              <div className="card mt-6 p-8 text-center">
                <p className="font-semibold">No lawyers meet the ranking criteria here yet.</p>
                <Link href={paths.city(country, city)} className="link mt-2 inline-flex items-center gap-1">
                  Browse all lawyers in {d.city.name} <ArrowRightIcon className="h-4 w-4" />
                </Link>
              </div>
            )}
            {d.stats.professionals > d.ranked.length && (
              <Link href={`/search/?practiceArea=${encodeURIComponent(pa.slug)}&city=${encodeURIComponent(city)}`} className="btn btn-quiet mt-6 w-full sm:w-auto">
                <SearchIcon className="h-4 w-4" />
                Search all {fmtNumber(d.stats.professionals)} {pa.name.toLowerCase()} lawyers in {d.city.name}
              </Link>
            )}
          </section>

          <Section title="How we rank" id="how" icon={<ScaleIcon className="h-4 w-4" />}>
            <p className="max-w-2xl leading-relaxed text-ink-2">
              Each lawyer gets nine component scores from 0 to 100. The bar shows how many of the 100 available points each component contributed. Weights are fixed for every lawyer in this list and published in full; payment plays no part.
            </p>
            <div className="card mt-5 p-5">
              <LedgerLegend weights={d.weights} />
            </div>
          </Section>

          {d.localResources.length > 0 && (
            <Section title={`${d.city.name} legal resources`} id="resources" icon={<LandmarkIcon className="h-4 w-4" />}>
              <Resources items={d.localResources} />
            </Section>
          )}

          {pa.guidance && (
            <Section title={`Choosing a ${pa.name.toLowerCase()} lawyer`} id="choosing" icon={<BookOpenIcon className="h-4 w-4" />}>
              <div className="prose-legal leading-relaxed text-ink-2">
                <p>{pa.guidance}</p>
              </div>
            </Section>
          )}

          <Faq items={d.faqs} />

          <div className="grid gap-10 sm:grid-cols-2">
            {d.relatedPracticeAreas.length > 0 && (
              <Section title="Related practice areas">
                <ul className="space-y-1">
                  {d.relatedPracticeAreas.map((r) => (
                    <li key={r.slug}>
                      <Link href={paths.cityPractice(country, city, r.slug)} className="group flex items-center gap-2.5 rounded-lg px-2 py-2 text-ink-2 hover:bg-surface hover:text-ledger">
                        <PracticeAreaIcon slug={r.slug} className="h-4 w-4 text-muted group-hover:text-ledger" />
                        <span className="flex-1">
                          {r.name} lawyers in {d.city.name}
                        </span>
                        <ArrowRightIcon className="h-4 w-4 opacity-0 transition-opacity group-hover:opacity-100" />
                      </Link>
                    </li>
                  ))}
                </ul>
              </Section>
            )}
            {d.relatedCities.length > 0 && (
              <Section title="Related locations">
                <ul className="space-y-1">
                  {d.relatedCities.map((r) => (
                    <li key={r.slug}>
                      <Link href={paths.cityPractice(country, r.slug, pa.slug)} className="group flex items-center gap-2.5 rounded-lg px-2 py-2 text-ink-2 hover:bg-surface hover:text-ledger">
                        <MapPinIcon className="h-4 w-4 text-muted group-hover:text-ledger" />
                        <span className="flex-1">
                          {pa.name} lawyers in {r.name}
                        </span>
                        <ArrowRightIcon className="h-4 w-4 opacity-0 transition-opacity group-hover:opacity-100" />
                      </Link>
                    </li>
                  ))}
                </ul>
              </Section>
            )}
          </div>

          <footer className="flex flex-wrap items-start justify-between gap-4 border-t border-rule pt-6 text-sm text-muted">
            <span className="inline-flex items-center gap-1.5">
              <CalendarIcon className="h-4 w-4" />
              Last updated {fmtDate(d.calculatedAt)}. Ranking for {year}.
            </span>
            <ReportForm entityType="ranking" entityId={d.city.id} label="Report a problem with this ranking" />
          </footer>
        </div>

        <aside className={`space-y-4 ${sticky}`}>
          <LeadForm
            heading={`Get help from a ${pa.name.toLowerCase()} lawyer`}
            intro={`Describe your situation and we will pass it to up to three verified lawyers in ${d.city.name} who accept enquiries.`}
            countrySlug={country}
            citySlug={city}
            practiceAreaSlug={pa.slug}
            sourcePath={path}
            consentText={consent.text}
          />
          <p className="flex items-start gap-2 px-1 text-xs leading-relaxed text-muted">
            <LockIcon className="mt-0.5 h-3.5 w-3.5" />
            Justice Choice is not a law firm and does not give legal advice. Matching is based on organic fit, not payment.
          </p>
        </aside>
      </div>

      <JsonLd
        data={{
          '@context': 'https://schema.org',
          '@type': 'ItemList',
          name: `Top ${pa.name} Lawyers in ${d.city.name}`,
          itemListOrder: 'https://schema.org/ItemListOrderDescending',
          numberOfItems: d.ranked.length,
          itemListElement: d.ranked.map((l) => ({ '@type': 'ListItem', position: l.rank, url: abs(paths.lawyer(l.slug)), name: l.name })),
        }}
      />
    </div>
  );
}

// ─────────────────────────────────────────── City hub (§5 City page)

async function CityHubView({ country, city, page }: { country: string; city: string; page: number }) {
  const [d, consent] = await Promise.all([
    api<CityHub>(`/cities/${encodeURIComponent(city)}?country=${encodeURIComponent(country)}&page=${page}`),
    api<{ text: string }>('/leads/consent-text', { revalidate: 300 }),
  ]);
  const path = paths.city(country, city);
  return (
    <div className="mx-auto max-w-6xl px-4 py-8 sm:px-6 sm:py-10">
      <Beacon />
      <Breadcrumbs items={[{ label: 'Home', href: '/' }, { label: d.city.country.name, href: paths.country(country) }, { label: d.city.name, href: path }]} />
      <header className="mt-6 grid gap-8 border-b border-rule pb-10 lg:grid-cols-[1.5fr_1fr]">
        <div>
          <p className="eyebrow">
            <MapPinIcon className="h-3.5 w-3.5" /> {d.city.region?.name ? `${d.city.region.name}, ` : ''}
            {d.city.country.name}
          </p>
          <h1 className="mt-3 font-serif text-[2.25rem] font-semibold leading-[1.1] tracking-tight sm:text-[2.75rem]">Lawyers in {d.city.name}</h1>
          <div className="prose-legal mt-4 text-lg leading-relaxed text-ink-2">
            <p>{d.intro ?? `Compare ${fmtNumber(d.stats.professionals)} lawyers practising in ${d.city.name}, ${d.city.country.name}, by practice area.`}</p>
          </div>
        </div>
        <dl className="card grid grid-cols-2 gap-5 self-end p-5">
          <Stat value={fmtNumber(d.stats.professionals)} label="lawyers" icon={<UsersIcon className="h-5 w-5" />} />
          <Stat value={fmtNumber(d.stats.verified)} label="verified licences" icon={<BadgeCheckIcon className="h-5 w-5" />} />
          <Stat value={fmtNumber(d.stats.firms)} label="firms" icon={<BuildingIcon className="h-5 w-5" />} />
          <Stat value={d.stats.averageExperience ?? '—'} label="average years" icon={<ClockIcon className="h-5 w-5" />} />
        </dl>
      </header>

      <div className="mt-10 grid gap-10 lg:grid-cols-[1fr_20rem]">
        <div className="min-w-0 space-y-14">
          <Section title="Rankings by practice area" icon={<TrendingUpIcon className="h-4 w-4" />}>
            <ul className="grid gap-3 sm:grid-cols-2">
              {d.practiceAreas.map((a) => (
                <li key={a.slug}>
                  <Link href={a.path} className="card card-hover group flex h-full items-center gap-3 p-4">
                    <span className="grid h-10 w-10 shrink-0 place-items-center rounded-lg bg-ledger-soft text-ledger transition-colors group-hover:bg-ledger group-hover:text-ledger-ink">
                      <PracticeAreaIcon slug={a.slug} className="h-5 w-5" />
                    </span>
                    <span className="min-w-0 flex-1">
                      <span className="block font-semibold text-ink">{a.name} lawyers</span>
                      <span className="num block text-sm text-muted">
                        {fmtNumber(a.lawyers)} lawyers · {fmtNumber(a.verified)} verified
                      </span>
                    </span>
                    <ArrowRightIcon className="h-4 w-4 text-muted transition-all group-hover:translate-x-0.5 group-hover:text-ledger" />
                  </Link>
                </li>
              ))}
            </ul>
          </Section>

          <Section title={`All lawyers in ${d.city.name}`} id="lawyers" icon={<UsersIcon className="h-4 w-4" />} aside={<span className="text-sm text-muted">Ordered by best ranking position</span>}>
            <ul>
              {d.lawyers.items.map((l) => (
                <LawyerListItem key={l.id} l={l} />
              ))}
            </ul>
            <Pagination page={page} pageCount={d.lawyers.pageCount} href={(p) => (p === 1 ? path : `${path}?page=${p}`)} />
          </Section>

          {d.localResources.length > 0 && (
            <Section title={`${d.city.name} legal resources`} icon={<LandmarkIcon className="h-4 w-4" />}>
              <Resources items={d.localResources} />
            </Section>
          )}
          <Faq items={d.faqs} />

          {d.nearbyCities.length > 0 && (
            <Section title={`Other cities in ${d.city.country.name}`} icon={<MapPinIcon className="h-4 w-4" />}>
              <ul className="flex flex-wrap gap-2">
                {d.nearbyCities.map((c) => (
                  <li key={c.slug}>
                    <Link href={c.path} className="chip">
                      <MapPinIcon className="h-3.5 w-3.5 text-muted" />
                      {c.name}
                      <span className="num text-xs text-muted">{fmtNumber(c.lawyers)}</span>
                    </Link>
                  </li>
                ))}
              </ul>
            </Section>
          )}
        </div>
        <aside className={sticky}>
          <LeadForm
            heading="Tell us what you need"
            intro={`We will pass your enquiry to up to three verified lawyers in ${d.city.name}.`}
            countrySlug={country}
            citySlug={city}
            sourcePath={path}
            consentText={consent.text}
          />
        </aside>
      </div>
    </div>
  );
}
