/**
 * AnnotatedScreenshot — wraps a product visual with hand-drawn-style annotations.
 *
 * Differentiator: AI-generated SaaS landing pages tend toward suspiciously
 * symmetrical, sterile mockups. Real teams leave fingerprints — circled
 * details, marginal callouts, scribbled arrows. This component adds those
 * signals on top of any existing mockup or image, without modifying the source.
 *
 * Usage:
 *   <AnnotatedScreenshot
 *     annotations={[
 *       { text: 'real GSC data, not estimates', anchor: 'top-left', offset: { x: -8, y: -6 } },
 *       { text: 'ranked by impact, every time', anchor: 'right', offset: { x: 4, y: 0 } },
 *     ]}
 *   >
 *     <HeroDashboardMockup />
 *   </AnnotatedScreenshot>
 *
 * Annotations only render at md breakpoint and up so mobile stays clean.
 */
import { type PropsWithChildren } from 'react';

import { cn } from '@/lib/utils';

export type AnnotationAnchor =
  | 'top-left'
  | 'top-right'
  | 'right'
  | 'bottom-right'
  | 'bottom-left'
  | 'left';

export interface Annotation {
  text: string;
  anchor: AnnotationAnchor;
  /** Pixel offset applied on top of the anchor position. */
  offset?: { x?: number; y?: number };
  /** Direction the arrow points. Default infers from anchor. */
  arrow?: 'left' | 'right' | 'up' | 'down' | 'none';
  /** Tilt direction (slight rotation) for hand-drawn feel. */
  tilt?: 'left' | 'right';
}

interface AnnotatedScreenshotProps extends PropsWithChildren {
  annotations: Annotation[];
  className?: string;
}

/**
 * Anchor placement is split into (1) Tailwind position classes and (2) a
 * percentage-based transform applied via inline style. We CANNOT mix Tailwind
 * `translate-*` utilities with an inline `transform` style — the inline style
 * would overwrite the utility's transform. Instead we put the % offset and the
 * px offset together in one inline transform string.
 */
const anchorPositions: Record<AnnotationAnchor, string> = {
  'top-left': 'top-0 left-0',
  'top-right': 'top-0 right-0',
  right: 'top-1/2 right-0',
  'bottom-right': 'bottom-0 right-0',
  'bottom-left': 'bottom-0 left-0',
  left: 'top-1/2 left-0',
};

/** Percentage transform that pulls the annotation half-outside its anchor. */
const anchorTranslate: Record<AnnotationAnchor, { x: string; y: string }> = {
  'top-left': { x: '-33%', y: '-50%' },
  'top-right': { x: '33%', y: '-50%' },
  right: { x: '50%', y: '-50%' },
  'bottom-right': { x: '25%', y: '50%' },
  'bottom-left': { x: '-25%', y: '50%' },
  left: { x: '-50%', y: '-50%' },
};

function inferArrow(anchor: AnnotationAnchor): 'left' | 'right' | 'up' | 'down' {
  if (anchor.includes('left')) return 'right';
  if (anchor.includes('right')) return 'left';
  if (anchor === 'top-left' || anchor === 'top-right') return 'down';
  return 'up';
}

function ArrowSvg({ direction }: { direction: 'left' | 'right' | 'up' | 'down' }) {
  // A loose, hand-drawn-feeling arrow. Stroke-only so it inherits color.
  const paths: Record<string, string> = {
    right: 'M 4 18 Q 28 6 56 18 L 50 12 M 56 18 L 50 24',
    left: 'M 60 18 Q 36 6 8 18 L 14 12 M 8 18 L 14 24',
    up: 'M 32 28 Q 18 16 32 4 L 26 10 M 32 4 L 38 10',
    down: 'M 32 4 Q 46 16 32 28 L 26 22 M 32 28 L 38 22',
  };
  return (
    <svg
      viewBox="0 0 64 32"
      className="h-6 w-16 text-primary/70"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.5"
      strokeLinecap="round"
      strokeLinejoin="round"
      aria-hidden="true"
    >
      <path d={paths[direction]} />
    </svg>
  );
}

export function AnnotatedScreenshot({
  children,
  annotations,
  className,
}: AnnotatedScreenshotProps) {
  return (
    <div className={cn('relative', className)}>
      {children}
      {annotations.map((a, i) => {
        const arrowDir = a.arrow === 'none' ? null : a.arrow ?? inferArrow(a.anchor);
        const tilt = a.tilt ?? (i % 2 === 0 ? 'left' : 'right');
        const baseTranslate = anchorTranslate[a.anchor];
        const offsetX = a.offset?.x ?? 0;
        const offsetY = a.offset?.y ?? 0;
        // Combine the percentage anchor offset with the pixel fine-tuning into
        // a single transform — CSS calc() handles the unit mixing.
        const transform = `translate(calc(${baseTranslate.x} + ${offsetX}px), calc(${baseTranslate.y} + ${offsetY}px))`;
        return (
          <div
            key={`${i}-${a.anchor}`}
            // Hidden on small screens — annotations need horizontal space to
            // breathe. Also hidden in print: the cursive Caveat text + gray
            // arrow strokes compete with the product screenshot underneath
            // and don't add information that the printed shot doesn't already
            // convey. Hiding the wrapper keeps the printed PDF clean. (F-PRINT-11)
            className={cn(
              'pointer-events-none absolute z-10 hidden md:flex items-center gap-2 print:!hidden',
              anchorPositions[a.anchor],
            )}
            style={{ transform }}
            aria-hidden="true"
          >
            {(a.anchor.includes('right') || a.anchor === 'right') && arrowDir && (
              <ArrowSvg direction={arrowDir} />
            )}
            <span
              className={cn(
                'annotation whitespace-nowrap rounded-md bg-background/80 px-2 py-0.5 backdrop-blur-sm',
                tilt === 'right' && 'right',
              )}
            >
              {a.text}
            </span>
            {!(a.anchor.includes('right') || a.anchor === 'right') && arrowDir && (
              <ArrowSvg direction={arrowDir} />
            )}
          </div>
        );
      })}
    </div>
  );
}
