import { TrendingUp } from 'lucide-react';

import MetricDelta from '@/Components/Shared/MetricDelta';
import { formatDecimal, formatNumber, formatPercentRaw } from '@/lib/format';
import { cn } from '@/lib/utils';

interface RoiSummaryCardProps {
  summary: {
    /**
     * R17-DASH-01 / ROI-ONE-NUMBER: canonical gains-only headline — the sum of
     * positive-delta significant snapshots (RoiCalculationService::getMeasuredBreakdown).
     * Matches MeasuredImpactCard (proof.measured_clicks_gained) and the PDF ({TOTAL_CLICKS}).
     * The controller sources this from measured_proof.measured_clicks_gained when the
     * measured-proof feature is active; falls back to net total_clicks_lift when not.
     */
    measured_clicks_gained: number;
    /**
     * Net clicks change (gains − losses). Used for the secondary "Net change (incl. losses)"
     * line shown only when total_clicks_lift !== measured_clicks_gained (i.e., at least one
     * tracked page lost clicks). Mirrors the PDF gate: the secondary line is hidden when
     * net == gains (no losses), exactly like RoiProofOfValueService.php:528.
     */
    total_clicks_lift: number;
    avg_ctr_improvement: number;
    pages_improved: number;
    total_recommendations_tracked: number;
  };
  className?: string;
  primaryColor?: string;
  /**
   * `preview` mode: render the metric rows with greyed labels and em-dash
   * values so an empty state still feels populated. The `summary` numbers
   * are ignored in preview mode. Used by Roi/Dashboard's empty state.
   */
  variant?: 'default' | 'preview';
}

interface MetricItemProps {
  label: string;
  value: number;
  format?: 'number' | 'decimal' | 'percent';
  showDelta?: boolean;
}

function MetricItem({ label, value, format = 'number', showDelta = false }: MetricItemProps) {
  const formatValue = (val: number): string => {
    switch (format) {
      case 'decimal':
        return formatDecimal(val, 1);
      case 'percent':
        return formatPercentRaw(val, 1);
      case 'number':
      default:
        return formatNumber(Math.round(val));
    }
  };

  return (
    <div className="flex items-center justify-between py-2">
      <span className="text-sm text-muted-foreground">{label}</span>
      <div className="flex items-center gap-2">
        <span className="text-sm font-medium tabular-nums">{formatValue(value)}</span>
        {showDelta && <MetricDelta value={value} format={format} />}
      </div>
    </div>
  );
}

/* Preview row — same rhythm as MetricItem, but the label is greyed one step
   further and the value is an em-dash. Decorative only (no real data to
   convey), so we mark the row aria-hidden — screen readers skip it and the
   adjacent empty-state heading + checklist carry the meaning. */
function PreviewMetricItem({ label }: { label: string }) {
  return (
    <div
      className="flex items-center justify-between py-2"
      data-testid={`roi-summary-preview-${label.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '')}`}
      aria-hidden="true"
    >
      <span className="text-sm text-muted-foreground/60">{label}</span>
      <span className="text-sm font-medium tabular-nums text-muted-foreground/60">—</span>
    </div>
  );
}

export default function RoiSummaryCard({
  summary,
  className,
  primaryColor,
  variant = 'default',
}: RoiSummaryCardProps) {
  const hasData = summary.total_recommendations_tracked > 0;
  const isPreview = variant === 'preview';

  /*
   * R17-DASH-01 / ROI-ONE-NUMBER: show the secondary "Net change (incl. losses)" line
   * only when net differs from gains-only — mirroring the PDF's gate at
   * RoiProofOfValueService.php:528 ((int)$netChange !== $gainsOnly).
   * When they are equal (no losses), suppress the secondary line entirely.
   */
  const showNetLine =
    Math.round(summary.total_clicks_lift) !== Math.round(summary.measured_clicks_gained);

  return (
    <div className={cn('rounded-lg border bg-card p-4', className)}>
      <div className="flex items-center gap-2 mb-4">
        <TrendingUp
          className="size-5"
          style={primaryColor ? { color: primaryColor } : undefined}
          {...(!primaryColor && { className: 'size-5 text-primary' })}
        />
        <h3 className="text-base font-semibold">ROI Summary</h3>
      </div>

      {isPreview ? (
        <div className="space-y-1 divide-y divide-border" data-testid="roi-summary-preview">
          <PreviewMetricItem label="Measured Clicks Lift" />
          <PreviewMetricItem label="Avg. CTR Improvement" />
          <PreviewMetricItem label="Pages Improved" />
          <PreviewMetricItem label="Recommendations Tracked" />
        </div>
      ) : !hasData ? (
        <div className="py-4">
          <p className="text-sm text-muted-foreground">
            No ROI data available. Mark recommendations as "Applied" to start tracking their impact.
          </p>
        </div>
      ) : (
        <div className="space-y-1 divide-y divide-border">
          {/*
           * R17-DASH-01 / ROI-ONE-NUMBER: headline is the gains-only canonical figure —
           * matches MeasuredImpactCard (proof.measured_clicks_gained) and the PDF so
           * the blogger's dashboard and the client's PDF always show the same number.
           * The controller sources this from measured_proof.measured_clicks_gained.
           */}
          <MetricItem
            label="Measured Clicks Lift"
            value={summary.measured_clicks_gained}
            format="number"
            showDelta
          />
          {/*
           * R17-DASH-01: secondary "Net change" line — shown only when losses exist (i.e.,
           * net total_clicks_lift differs from the gains-only headline). Muted styling
           * so it reads as context, not a competing headline.
           * Gate mirrors RoiProofOfValueService.php:528 exactly.
           */}
          {showNetLine && (
            <div className="flex items-center justify-between py-2">
              <span className="text-xs text-muted-foreground/70">Net change (incl. losses)</span>
              <span className="text-xs tabular-nums text-muted-foreground/70">
                {formatNumber(Math.round(summary.total_clicks_lift))}
              </span>
            </div>
          )}
          <MetricItem
            label="Avg. CTR Improvement"
            value={summary.avg_ctr_improvement}
            format="percent"
            showDelta
          />
          <MetricItem label="Pages Improved" value={summary.pages_improved} format="number" />
          <MetricItem
            label="Recommendations Tracked"
            value={summary.total_recommendations_tracked}
            format="number"
          />
        </div>
      )}
    </div>
  );
}
