'use client';

/**
 * Sales Performance — Pipeline funnel (Report 01 Chart 1).
 *
 * Originally rendered as an echarts funnel, which assumes monotonically
 * decreasing counts. Real pipeline data is often non-monotonic (more
 * deals in Contract than in Reservation, etc.) which made the funnel
 * render as a broken bowtie. Replaced with a horizontal-bar list:
 * one row per canonical stage, bar length proportional to the stage's
 * count relative to the max, drop-off vs the prior stage annotated on
 * the right. Same data, far more honest at a glance.
 */

import { ArrowDownRight, ArrowUpRight, Minus } from 'lucide-react';

import { cn } from '@/lib/utils';
import { STAGE_LABELS, type PipelineStage } from '@/lib/constants';

interface PipelineFunnelRow {
  stage: PipelineStage;
  count: number;
  dropoffFromPrior: number | null;
}

interface Props {
  rows: PipelineFunnelRow[];
}

// Brand palette graded across the 7 stages - earlier stages lighter
// (top of funnel = wide / lower-intent), later stages darker brand-blue
// (bottom of funnel = narrow / high-intent). Matches the existing
// STAGE_DOT palette in spirit while sticking to the brand ramp.
const STAGE_BAR_COLOR: Record<PipelineStage, string> = {
  enquiry: 'bg-slate-400',
  qualified: 'bg-brand-300',
  nurturing: 'bg-brand-300/70',
  eoi: 'bg-brand-400',
  reservation: 'bg-brand-500',
  deposit_paid: 'bg-brand-600',
  contract: 'bg-brand-700',
};

export function SalesPipelineFunnel({ rows }: Props) {
  const max = Math.max(1, ...rows.map((r) => r.count));

  return (
    <div className="space-y-2.5">
      {rows.map((row) => {
        const widthPct = (row.count / max) * 100;
        const isZero = row.count === 0;
        return (
          <div
            key={row.stage}
            className="grid items-center gap-3"
            // Inline style guarantees the 3-column track (label | bar |
            // drop-off badge) on Tailwind v4 - the arbitrary
            // `grid-cols-[...]` utility's underscore-to-space
            // conversion was silently dropping the class in some
            // builds, collapsing the row to stacked.
            style={{ gridTemplateColumns: '140px 1fr 120px' }}
          >
            {/* Stage label */}
            <div className="text-sm font-medium text-foreground tabular-nums">
              {STAGE_LABELS[row.stage]}
            </div>

            {/* Bar */}
            <div className="relative h-6 rounded-sm bg-muted/40 overflow-hidden">
              <div
                className={cn(
                  'h-full rounded-sm transition-[width] duration-500 ease-out',
                  STAGE_BAR_COLOR[row.stage],
                  isZero && 'opacity-30',
                )}
                style={{ width: `${Math.max(widthPct, isZero ? 0 : 1.5)}%` }}
                aria-hidden
              />
              <div
                className={cn(
                  'absolute inset-y-0 left-2 flex items-center text-xs font-semibold tabular-nums',
                  // Place the count inside the bar when there's room, else outside (right of bar)
                  widthPct > 15 ? 'text-white' : 'text-foreground',
                )}
                style={widthPct > 15 ? undefined : { left: `calc(${widthPct}% + 8px)` }}
              >
                {row.count}
              </div>
            </div>

            {/* Drop-off vs prior */}
            <DropoffBadge dropoff={row.dropoffFromPrior} />
          </div>
        );
      })}
    </div>
  );
}

function DropoffBadge({ dropoff }: { dropoff: number | null }) {
  if (dropoff === null) {
    return <span className="text-[11px] text-muted-foreground">—</span>;
  }
  const pct = Math.round(dropoff * 100);
  if (pct === 0) {
    return (
      <span className="inline-flex items-center gap-1 text-[11px] text-muted-foreground">
        <Minus className="h-3 w-3" aria-hidden />
        no change
      </span>
    );
  }
  // Negative drop-off (the typical case in a funnel) is shown in slate
  // not red - it's normal for stages to shrink. Positive drop-off
  // (rare; means more in this stage than the prior) gets emerald.
  const isPositive = pct > 0;
  return (
    <span
      className={cn(
        'inline-flex items-center gap-1 text-[11px] font-medium tabular-nums',
        isPositive ? 'text-emerald-700' : 'text-muted-foreground',
      )}
    >
      {isPositive ? (
        <ArrowUpRight className="h-3 w-3" aria-hidden />
      ) : (
        <ArrowDownRight className="h-3 w-3" aria-hidden />
      )}
      {isPositive ? '+' : ''}
      {pct}%
    </span>
  );
}
