---
/**
 * AffiliateComparisonTable — side-by-side comparison of a few monetised options, each row ending in a CTA. Rows come
 * from the caller; an external row's link is sponsored unless `sponsored: false`. A real table from md up, stacked
 * cards below (exactly one is in the DOM per viewport); with no row carrying a link the CTA column is dropped. The
 * disclosure arrives through the `disclosure` slot, below the table.
 */
import Icon from '../primitives/Icon.astro';
import Badge from '../primitives/Badge.astro';
import type { ComparisonRow, ComparisonTableLabels } from './types';
import { providerFromHref } from './provider';
import { LABELS } from '../internal/labels';

interface Props {
  rows: ComparisonRow[];
  title?: string;
  titleTag?: 'p' | 'h2' | 'h3';
  nameLabel?: string;
  priceLabel?: string;
  featureLabel?: string;
  placement?: string;
  provider?: string;
  labels?: ComparisonTableLabels;
  class?: string;
}

const {
  rows = [],
  title,
  titleTag = 'p',
  nameLabel = LABELS.affiliateComparisonTable.nameLabel,
  priceLabel = LABELS.affiliateComparisonTable.priceLabel,
  featureLabel = LABELS.affiliateComparisonTable.featureLabel,
  placement = 'comparison-table',
  provider,
  labels = {},
  class: className = '',
} = Astro.props;

const {
  caption = LABELS.affiliateComparisonTable.caption,
  ctaColumn = LABELS.affiliateComparisonTable.ctaColumn,
  externalCta = LABELS.affiliateComparisonTable.externalCta,
  internalCta = LABELS.affiliateComparisonTable.internalCta,
  externalAria = LABELS.affiliateComparisonTable.externalAria,
  internalAria = LABELS.affiliateComparisonTable.internalAria,
  rated = LABELS.affiliateComparisonTable.rated,
} = labels;

const captionText = title ?? caption;
const TitleTag = titleTag;
const hasAnyCta = rows.some((row) => row.href);

const ctaBase =
  'inline-flex items-center justify-center gap-2 rounded-lg px-4 py-3 text-sm font-semibold transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent focus-visible:ring-offset-2';
const ctaAffiliate = `${ctaBase} bg-accent-strong text-primary-foreground hover:bg-accent`;
const ctaInternal = `${ctaBase} border border-border bg-muted/40 text-foreground hover:bg-muted/70`;

const defaultCta = (external: boolean) => (external ? externalCta : internalCta);
---

{rows.length > 0 && (
  <div class:list={['not-prose my-8', className]}>
    {title && (
      <TitleTag class="mb-4 font-display text-lg font-semibold text-foreground">{title}</TitleTag>
    )}

    {/* md and up: a real table */}
    <div class="hidden overflow-x-auto md:block">
      <table class="w-full border-collapse overflow-hidden rounded-lg border border-border bg-card text-sm">
        <caption class="sr-only">{captionText}</caption>
        <thead>
          <tr class="bg-muted/60">
            <th scope="col" class="border-b border-border px-4 py-3 text-left font-semibold text-foreground">{nameLabel}</th>
            <th scope="col" class="border-b border-border px-4 py-3 text-left font-semibold text-foreground">{priceLabel}</th>
            <th scope="col" class="border-b border-border px-4 py-3 text-left font-semibold text-foreground">{featureLabel}</th>
            {hasAnyCta && (
              <th scope="col" class="border-b border-border px-4 py-3 text-right font-semibold text-foreground">
                <span class="sr-only">{ctaColumn}</span>
              </th>
            )}
          </tr>
        </thead>
        <tbody>
          {rows.map((row, i) => {
            const external = row.external !== false;
            const rel = row.sponsored === false ? 'noopener noreferrer' : 'sponsored noopener noreferrer';
            const cta = row.cta ?? defaultCta(external);
            return (
              <tr class={i % 2 === 1 ? 'bg-muted/20' : ''}>
                <th scope="row" class="border-b border-border px-4 py-3 text-left align-top font-normal last:border-b-0">
                  <span class="block font-display font-semibold text-foreground">{row.name}</span>
                  {row.subtitle && (
                    <span class="mt-0.5 block text-xs text-muted-foreground">{row.subtitle}</span>
                  )}
                  {row.badge && (
                    <Badge tone="accent" size="sm" lines={2} class="mt-1.5 max-w-[26ch]">{row.badge}</Badge>
                  )}
                  {typeof row.rating === 'number' && (
                    <span class="mt-1.5 flex items-center gap-1 text-xs text-muted-foreground" role="img" aria-label={rated(row.rating, row.ratingCount)}>
                      <Icon name="star" filled class="h-3.5 w-3.5 text-accent" />
                      <span class="font-medium text-foreground">{row.rating.toFixed(1)}</span>
                      {row.ratingCount && <span>({row.ratingCount})</span>}
                    </span>
                  )}
                </th>
                <td class="border-b border-border px-4 py-3 align-top text-muted-foreground last:border-b-0">
                  {/* a price can carry a long sourcing caveat */}
                  <span class="line-clamp-3">{row.price}</span>
                </td>
                <td class="border-b border-border px-4 py-3 align-top leading-relaxed text-muted-foreground last:border-b-0">
                  <span class="line-clamp-2">{row.keyFeature}</span>
                </td>
                {hasAnyCta && (
                <td class="border-b border-border px-4 py-3 text-right align-top last:border-b-0">
                  {row.href ? (
                    external ? (
                      <a
                        href={row.href}
                        target="_blank"
                        rel={rel}
                        data-track-event="affiliate_click"
                        data-track-cta-id={row.trackId}
                        data-track-cta-placement={placement}
                        data-track-affiliate-provider={row.provider ?? provider ?? providerFromHref(row.href)}
                        data-track-affiliate-placement={placement}
                        class={ctaAffiliate}
                        aria-label={externalAria(cta, row.name)}
                      >
                        {cta}
                        <Icon name="arrow-up-right" class="h-4 w-4" />
                      </a>
                    ) : (
                      <a href={row.href} class={ctaInternal} aria-label={internalAria(cta, row.name)}>
                        {cta}
                        <Icon name="arrow-right" class="h-4 w-4" />
                      </a>
                    )
                  ) : (
                    <span class="text-muted-foreground" aria-hidden="true">—</span>
                  )}
                </td>
                )}
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>

    {/* below md: stacked cards */}
    <ul class="space-y-4 md:hidden">
      {rows.map((row) => {
        const external = row.external !== false;
        const rel = row.sponsored === false ? 'noopener noreferrer' : 'sponsored noopener noreferrer';
        const cta = row.cta ?? defaultCta(external);
        return (
          <li class="rounded-xl border border-border bg-card p-4">
            {/* the badge gets its own line so a long label never squeezes the name */}
            <div class="min-w-0">
              <p class="font-display font-semibold text-foreground">{row.name}</p>
              {row.subtitle && <p class="mt-0.5 text-sm text-muted-foreground">{row.subtitle}</p>}
            </div>
            {row.badge && (
              <Badge tone="accent" size="sm" lines={2} class="mt-1.5">{row.badge}</Badge>
            )}

            {typeof row.rating === 'number' && (
              <p class="mt-2 flex items-center gap-1 text-xs text-muted-foreground" role="img" aria-label={rated(row.rating, row.ratingCount)}>
                <Icon name="star" filled class="h-3.5 w-3.5 text-accent" />
                <span class="font-medium text-foreground">{row.rating.toFixed(1)}</span>
                {row.ratingCount && <span>({row.ratingCount})</span>}
              </p>
            )}

            <dl class="mt-3 space-y-2 text-sm">
              <div class="flex justify-between gap-4">
                <dt class="shrink-0 text-muted-foreground">{priceLabel}</dt>
                <dd class="min-w-0 text-right font-medium text-foreground line-clamp-3">{row.price}</dd>
              </div>
              <div class="flex justify-between gap-4">
                <dt class="shrink-0 text-muted-foreground">{featureLabel}</dt>
                <dd class="min-w-0 text-right text-foreground line-clamp-2">{row.keyFeature}</dd>
              </div>
            </dl>

            {row.href && (
              <div class="mt-4">
                {external ? (
                  <a
                    href={row.href}
                    target="_blank"
                    rel={rel}
                    data-track-event="affiliate_click"
                    data-track-cta-id={row.trackId}
                    data-track-cta-placement={placement}
                    data-track-affiliate-provider={row.provider ?? provider ?? providerFromHref(row.href)}
                    data-track-affiliate-placement={placement}
                    class={`${ctaAffiliate} w-full`}
                    aria-label={externalAria(cta, row.name)}
                  >
                    {cta}
                    <Icon name="arrow-up-right" class="h-4 w-4" />
                  </a>
                ) : (
                  <a href={row.href} class={`${ctaInternal} w-full`} aria-label={internalAria(cta, row.name)}>
                    {cta}
                    <Icon name="arrow-right" class="h-4 w-4" />
                  </a>
                )}
              </div>
            )}
          </li>
        );
      })}
    </ul>

    <slot name="disclosure" />
  </div>
)}
