import { Lock } from 'lucide-react';

import { useEffect } from 'react';

import { Head, Link } from '@inertiajs/react';

import EditorialPageHeader from '@/Components/layout/EditorialPageHeader';
import DashboardLayout from '@/Layouts/DashboardLayout';
import { trackProductEvent } from '@/lib/analytics';
import { CONTENT_HUB_VIEWED } from '@/lib/event-catalog';
import { cn } from '@/lib/utils';
import type { SiteBasic } from '@/types';

import { CONTENT_CELLS } from './content-hub-cells';

interface ContentCounts {
  inventory: number;
  briefs: number;
  drafts_in_flight: number;
}

interface Props {
  site: SiteBasic & { has_gsc: boolean; has_analysis: boolean };
  counts?: ContentCounts;
}

/**
 * Content hub IA (plan R1 + B-03 fix):
 *   Content children = Content Inventory · Content Briefs · Calendar · Recovery Runs · Reports
 *
 * Always-on (work pre-GSC): Inventory, Briefs, Calendar.
 * Analysis-gated:           Recovery Runs, Reports.
 *
 * Editorialize-hubs (2026-05-28): brochure-card layout replaced with a
 * hairline cell-grid. Gated cells render with a Lock overlay on the icon
 * and a `aria-disabled` span (not a disabled Button — that was the
 * pre-existing a11y antipattern fixed in this pass).
 *
 * R7UXB-005: Cell definitions moved to content-hub-cells.ts so ContentHub
 * and RecoverHub share a single source of truth.
 */

/** Count accessor for each CONTENT_CELLS entry (same order). */
function getCount(key: string, c: ContentCounts): number | null {
  switch (key) {
    case 'content-inventory': return c.inventory;
    case 'content-briefs':    return c.briefs;
    case 'calendar':          return null;
    case 'batch-ai':          return c.drafts_in_flight;
    case 'reports':           return null;
    default:                  return null;
  }
}

const ZERO_COUNTS: ContentCounts = {
  inventory: 0,
  briefs: 0,
  drafts_in_flight: 0,
};

export default function ContentHub({ site, counts }: Props) {
  const resolvedCounts = counts ?? ZERO_COUNTS;

  useEffect(() => {
    trackProductEvent(CONTENT_HUB_VIEWED, { site_id: String(site.id) });
  }, [site.id]);

  return (
    <DashboardLayout>
      <Head title={`Content — ${site.name}`} />

      <EditorialPageHeader
        eyebrow={`Content · ${site.name}`}
        title="Content"
        subtitle="What you're shipping"
        readouts={[
          {
            label: 'Inventory',
            value: (
              <span className="tabular-nums">{resolvedCounts.inventory}</span>
            ),
          },
          {
            label: 'Briefs',
            value: (
              <span className="tabular-nums">{resolvedCounts.briefs}</span>
            ),
          },
          {
            label: 'Drafts in flight',
            value: (
              <span className="tabular-nums">
                {resolvedCounts.drafts_in_flight}
              </span>
            ),
          },
        ]}
      />

      <div className="container py-6 space-y-6">
        <div
          data-testid="hub-cell-grid"
          className="grid grid-cols-2 gap-px overflow-hidden rounded-2xl border bg-border lg:grid-cols-4"
        >
          {CONTENT_CELLS.map((cell) => {
            const Icon = cell.icon;
            const gated = cell.gatedBy ? cell.gatedBy(site) : false;
            const count = getCount(cell.key, resolvedCounts);
            const hasSignal = !gated && count !== null && count > 0;

            const description = gated && cell.gatedReason ? cell.gatedReason : cell.description;

            // Cell content — extracted so the gated branch can render a plain
            // <span aria-disabled> rather than wrapping a disabled Button
            // around a <span>, which was the previous a11y antipattern.
            const body = (
              <>
                <div className="flex items-start justify-between gap-2">
                  <div className="relative">
                    <Icon
                      className={cn(
                        'size-4',
                        gated
                          ? 'text-muted-foreground/60'
                          : hasSignal
                            ? 'text-primary'
                            : 'text-muted-foreground/60',
                      )}
                      aria-hidden="true"
                    />
                    {gated && (
                      <Lock
                        className="absolute -bottom-1.5 -right-1.5 size-3 rounded-full bg-background p-[1px] text-muted-foreground"
                        aria-hidden="true"
                      />
                    )}
                  </div>
                  {!gated && (
                    /* UI-007: always visible on mobile (no hover on touch devices);
                       hover-reveal only on sm+ where pointer devices are typical. */
                    <span className="text-[10px] font-semibold uppercase tracking-[0.16em] text-primary transition-opacity sm:opacity-0 sm:group-hover:opacity-100">
                      {cell.ctaLabel} →
                    </span>
                  )}
                  {gated && (
                    <span className="text-[10px] font-semibold uppercase tracking-[0.16em] text-muted-foreground/70">
                      Locked
                    </span>
                  )}
                </div>
                <div>
                  {count !== null && (() => {
                    // R6UXS-010: show em-dash for analysis-gated cells when no
                    // analysis has run — '0' reads as "empty" rather than "not yet run".
                    const showDash = gated && count === 0;
                    return showDash ? (
                      <div className="font-data text-3xl font-semibold tabular-nums tracking-tight text-muted-foreground/40">
                        —
                      </div>
                    ) : (
                      <div
                        className={cn(
                          'font-data text-3xl font-semibold tabular-nums tracking-tight',
                          gated
                            ? 'text-muted-foreground/40'
                            : hasSignal
                              ? 'text-foreground'
                              : 'text-muted-foreground/40',
                        )}
                      >
                        {count}
                      </div>
                    );
                  })()}
                  <p
                    className={cn(
                      'text-xs font-medium',
                      count !== null ? 'mt-1.5' : 'mt-0',
                      gated && 'text-muted-foreground',
                    )}
                  >
                    {cell.title}
                  </p>
                  <p className="text-[11px] text-muted-foreground mt-0.5">
                    {description}
                  </p>
                </div>
              </>
            );

            if (gated) {
              return (
                <span
                  key={cell.key}
                  aria-disabled="true"
                  className="flex flex-col justify-between gap-3 bg-card p-5 min-h-[140px] opacity-70 cursor-not-allowed"
                >
                  {body}
                </span>
              );
            }

            return (
              <Link
                key={cell.key}
                href={route(cell.routeName, site.id)}
                className={cn(
                  'group flex flex-col justify-between gap-3 bg-card p-5 transition-colors min-h-[140px]',
                  hasSignal ? 'hover:bg-accent/30' : 'hover:bg-muted/30',
                )}
                aria-label={`${cell.ctaLabel} — ${cell.title}`}
              >
                {body}
              </Link>
            );
          })}
        </div>
      </div>
    </DashboardLayout>
  );
}
