import React, { useEffect, useState } from 'react';

import type { ArticlePromptImpactResponse } from '../../service/visibility/visibility.interface';
import { getArticlePromptImpact } from '../../service/visibility/visibility.service';

import { trendChange } from './PromptTrend';

interface ArticleImpactBadgeProps {
  /** Recomaze client id. */
  clientId: string;
  /** Recomaze JWT. */
  token: string;
  /** Article whose prompt impact to summarise. */
  articleId: string;
}

/** Inline target glyph for the "Targets:" prefix. */
const TargetIcon = ({ size = 12 }: { size?: number }): JSX.Element => (
  <svg
    width={size}
    height={size}
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth={2}
    strokeLinecap="round"
    strokeLinejoin="round"
    aria-hidden="true"
    style={{ flexShrink: 0 }}
  >
    <circle cx="12" cy="12" r="9" />
    <circle cx="12" cy="12" r="5" />
    <circle cx="12" cy="12" r="1" />
  </svg>
);

/** Inline arrow glyph; ``up`` flips the vertical direction. */
const ArrowIcon = ({
  up,
  size = 12,
}: {
  up: boolean;
  size?: number;
}): JSX.Element => (
  <svg
    width={size}
    height={size}
    viewBox="0 0 24 24"
    fill="none"
    stroke="currentColor"
    strokeWidth={2}
    strokeLinecap="round"
    strokeLinejoin="round"
    aria-hidden="true"
  >
    {up ? (
      <>
        <polyline points="22 7 13.5 15.5 8.5 10.5 2 17" />
        <polyline points="16 7 22 7 22 13" />
      </>
    ) : (
      <>
        <polyline points="22 17 13.5 8.5 8.5 13.5 2 7" />
        <polyline points="16 17 22 17 22 11" />
      </>
    )}
  </svg>
);

/**
 * Card-level "from which prompt, and did it grow?" chip. Fetches the article's
 * per-prompt impact and shows the prompt it targets plus the average
 * visibility and the delta since publish, so a merchant scanning the list sees
 * the source and the result without opening it. Renders nothing when the
 * article ties to no prompt or the fetch fails - the card stays clean.
 *
 * @param {ArticleImpactBadgeProps} props - Component props.
 * @returns {JSX.Element | null} The chip, or ``null`` when there's nothing.
 */
export const ArticleImpactBadge = ({
  clientId,
  token,
  articleId,
}: ArticleImpactBadgeProps): JSX.Element | null => {
  const [data, setData] = useState<ArticlePromptImpactResponse | null>(null);

  useEffect(() => {
    let cancelled = false;
    getArticlePromptImpact(clientId, token, articleId)
      .then(result => {
        if (!cancelled) setData(result);
      })
      .catch(() => {
        // Silent: the card just renders without the chip.
      });

    return () => {
      cancelled = true;
    };
  }, [clientId, token, articleId]);

  if (!data || data.prompts.length === 0) return null;

  const entries = data.prompts;
  const label =
    entries.length === 1 ? entries[0].prompt_text : `${entries.length} prompts`;

  const scored = entries
    .filter(entry => entry.tracked && entry.current_score !== null)
    .map(entry => entry.current_score as number);
  const baselines = entries
    .map(entry => entry.baseline_score)
    .filter((score): score is number => score !== null);
  const deltas = entries
    .map(entry => entry.delta_score)
    .filter((delta): delta is number => delta !== null);
  const avg = (values: number[]): number =>
    Math.round(values.reduce((sum, value) => sum + value, 0) / values.length);
  const avgScore = scored.length ? avg(scored) : null;
  const avgBaseline = baselines.length ? avg(baselines) : null;
  const avgDelta = deltas.length ? avg(deltas) : null;
  const change = trendChange(avgBaseline, avgScore, avgDelta);

  const tone =
    change.kind === 'delta' && change.value > 0
      ? 'text-green-600'
      : change.kind === 'delta' && change.value < 0
        ? 'text-red-600'
        : change.kind === 'new'
          ? 'text-green-600'
          : 'text-gray-500';

  return (
    <div className="mt-1 flex flex-wrap items-center gap-x-2 gap-y-1 text-[11px]">
      <span className="inline-flex max-w-full items-center gap-1 text-gray-500">
        <TargetIcon />
        Targets:
        <span className="max-w-[18rem] truncate text-gray-900" title={label}>
          {label}
        </span>
      </span>
      {avgScore !== null ? (
        <span className="inline-flex items-center gap-1.5 rounded-md border border-gray-200 bg-white px-2 py-0.5">
          <span className="text-gray-500">AI visibility</span>
          <span className="font-semibold text-gray-900">{avgScore}</span>
          {change.kind === 'new' && (
            <span className={`font-medium ${tone}`}>New since publish</span>
          )}
          {change.kind === 'delta' && (
            <span
              className={`inline-flex items-center gap-0.5 font-medium ${tone}`}
            >
              <ArrowIcon up={change.value >= 0} />
              {`${change.value > 0 ? '+' : ''}${change.value} since publish`}
            </span>
          )}
        </span>
      ) : (
        <span className="rounded-md border border-gray-200 bg-white px-2 py-0.5 text-gray-500">
          Tracking · stats after the next scan
        </span>
      )}
    </div>
  );
};

export default ArticleImpactBadge;
