'use client';

import Link from 'next/link';
import { useParams, usePathname } from 'next/navigation';
import type { Route } from 'next';
import { useQuery } from '@tanstack/react-query';
import { ArrowRight, ChevronRight } from 'lucide-react';
import { formatDistanceToNowStrict } from 'date-fns';

import { apiFetch } from '@/lib/api/client';
import { Skeleton } from '@/components/ui/skeleton';
import { TagBadge } from '@/components/shared/tag-badge';
import { deriveInterestBerthLabel } from '@/lib/templates/interest-berth-label';
import { cn } from '@/lib/utils';
import {
  PIPELINE_STAGES,
  STAGE_BADGE,
  STAGE_DOT,
  STAGE_LABELS,
  STAGE_SHORT_LABELS,
  safeStage,
  type PipelineStage,
} from '@/components/clients/pipeline-constants';

export interface ClientInterestRow {
  id: string;
  pipelineStage: string;
  archivedAt: string | null;
  updatedAt: string;
  dateLastContact: string | null;
  berthMooringNumber?: string | null;
  berthMoorings?: string[];
  yachtName?: string | null;
  /** Requirements surfaced on the Client Overview panel - "Wants L × W × D
   *  · Source" lets reps see what the deal is looking for without drilling
   *  into the Interest detail. Fields are nullable when the rep hasn't
   *  captured constraints yet. */
  desiredLengthFt?: string | null;
  desiredWidthFt?: string | null;
  desiredDraftFt?: string | null;
  source?: string | null;
  /** Tag chips surfaced alongside the StageStepper. Ship by `getInterests`
   *  (list endpoint resolves the join on every row in a single batch). */
  tags?: Array<{ id: string; name: string; color: string }>;
}

interface InterestsResponse {
  data: ClientInterestRow[];
}

export function useClientInterests(clientId: string) {
  return useQuery<InterestsResponse>({
    queryKey: ['interests', { clientId }],
    queryFn: () => apiFetch<InterestsResponse>(`/api/v1/interests?clientId=${clientId}&limit=50`),
  });
}

export function StageStepper({
  current,
  size = 'sm',
}: {
  current: PipelineStage;
  size?: 'xs' | 'sm';
}) {
  const idx = PIPELINE_STAGES.indexOf(current);
  // Segmented progress bar: each stage is a slice of equal width that
  // lights up once the interest has reached it. Reads at-a-glance, scales
  // to any container width, and works with 9 stages without becoming
  // micro-dots that vanish under cramped layouts.
  const height = size === 'xs' ? 'h-1' : 'h-1.5';
  return (
    <div className="flex w-full flex-col gap-1">
      <div
        className={cn('flex w-full overflow-hidden rounded-full bg-muted', height)}
        role="progressbar"
        aria-label="Pipeline progress"
        aria-valuenow={idx + 1}
        aria-valuemin={1}
        aria-valuemax={PIPELINE_STAGES.length}
      >
        {PIPELINE_STAGES.map((stage, i) => {
          const isReached = i <= idx;
          const isCurrent = i === idx;
          return (
            <div
              key={stage}
              title={`${STAGE_LABELS[stage]}${isCurrent ? ' (current)' : ''}`}
              className={cn(
                'flex-1 transition-colors',
                isReached ? STAGE_DOT[stage] : 'bg-transparent',
                i > 0 ? 'border-l border-card' : '',
              )}
            />
          );
        })}
      </div>
      {/* Stage-name row below the bar - surfaces all reached stage names
          inline (compact short-labels) so the bar isn't a mystery without
          hovering. Future stages render in muted text so the rep can still
          see the ladder ahead. The `xs` size variant hides this row to
          keep the cramped table-cell footprint intact. */}
      {size !== 'xs' ? (
        <div className="flex w-full text-xs font-medium uppercase tracking-wide">
          {PIPELINE_STAGES.map((stage, i) => {
            const isReached = i <= idx;
            return (
              <div
                key={stage}
                className={cn(
                  'flex-1 truncate text-center',
                  isReached ? 'text-foreground' : 'text-muted-foreground',
                )}
              >
                {STAGE_SHORT_LABELS[stage]}
              </div>
            );
          })}
        </div>
      ) : null}
    </div>
  );
}

function pickHighest(interests: ClientInterestRow[]): ClientInterestRow | null {
  const active = interests.filter((i) => !i.archivedAt);
  if (active.length === 0) return null;
  return [...active].sort((a, b) => {
    const ai = PIPELINE_STAGES.indexOf(safeStage(a.pipelineStage));
    const bi = PIPELINE_STAGES.indexOf(safeStage(b.pipelineStage));
    if (ai !== bi) return bi - ai;
    return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime();
  })[0]!;
}

function lastActivityLabel(interests: ClientInterestRow[]): string | null {
  const candidates = interests
    .flatMap((i) => [i.dateLastContact, i.updatedAt])
    .filter((v): v is string => Boolean(v))
    .map((v) => new Date(v).getTime())
    .filter((t) => !Number.isNaN(t));
  if (candidates.length === 0) return null;
  const latest = new Date(Math.max(...candidates));
  return `${formatDistanceToNowStrict(latest)} ago`;
}

interface PipelineSummaryProps {
  clientId: string;
  /**
   * `hero` - single-line pulse for the detail header (highest active stage only).
   * `panel` - compact list of every active interest, for the Overview tab.
   */
  variant?: 'hero' | 'panel';
}

function HeroVariant({ clientId, portSlug }: { clientId: string; portSlug: string }) {
  const pathname = usePathname();
  const { data, isLoading } = useClientInterests(clientId);
  const interests = data?.data ?? [];
  const top = pickHighest(interests);
  const activeCount = interests.filter((i) => !i.archivedAt).length;
  const activity = lastActivityLabel(interests);
  const interestsTabHref = `${pathname}?tab=interests` as Route;

  if (isLoading) {
    return (
      <div className="space-y-2">
        <Skeleton className="h-4 w-40" aria-hidden />
        <Skeleton className="h-2 w-48" aria-hidden />
      </div>
    );
  }

  if (!top) {
    return (
      <div className="flex flex-wrap items-center justify-between gap-2">
        <div>
          <p className="text-sm font-medium text-foreground">No active interests</p>
          <p className="text-xs text-muted-foreground">
            Start one to begin tracking the sales process.
          </p>
        </div>
        <Link
          href={`/${portSlug}/interests/new` as Route}
          className="inline-flex items-center gap-1 text-xs font-medium text-primary hover:underline"
        >
          Start interest <ArrowRight className="size-3" aria-hidden />
        </Link>
      </div>
    );
  }

  const stage = safeStage(top.pipelineStage);
  const topBerthDisplay = deriveInterestBerthLabel(top.berthMoorings) ?? top.berthMooringNumber;
  const berthLabel = topBerthDisplay ? `Berth ${topBerthDisplay}` : 'General interest';
  const detailsHref = `/${portSlug}/interests/${top.id}` as Route;

  return (
    <div className="space-y-2">
      <div className="flex items-center gap-2 flex-wrap">
        <span className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
          Sales pipeline
        </span>
        {activeCount > 1 ? (
          <span className="text-xs font-medium text-muted-foreground">· {activeCount} active</span>
        ) : null}
      </div>

      <Link
        href={detailsHref}
        className="group -m-1 block rounded-lg p-1 transition-colors hover:bg-foreground/5"
      >
        <div className="flex items-center gap-2 flex-wrap">
          <span className="truncate text-sm font-semibold text-foreground">{berthLabel}</span>
          <span
            className={cn(
              'shrink-0 rounded-full px-2 py-0.5 text-xs font-medium',
              STAGE_BADGE[stage],
            )}
          >
            {STAGE_LABELS[stage]}
          </span>
          <ChevronRight
            className="size-3.5 shrink-0 text-muted-foreground transition-transform group-hover:translate-x-0.5"
            aria-hidden
          />
        </div>
        <div className="mt-1.5">
          <StageStepper current={stage} size="xs" />
        </div>
        {top.tags && top.tags.length > 0 ? (
          <div className="mt-1.5 flex flex-wrap gap-1">
            {top.tags.slice(0, 4).map((t) => (
              <TagBadge key={t.id} name={t.name} color={t.color} />
            ))}
            {top.tags.length > 4 ? (
              <span className="text-xs text-muted-foreground">+{top.tags.length - 4} more</span>
            ) : null}
          </div>
        ) : null}
      </Link>

      <div className="flex items-center justify-between gap-2 text-xs text-muted-foreground">
        <span>{activity ? `Last activity ${activity}` : 'No activity recorded'}</span>
        {activeCount > 1 ? (
          <Link
            href={interestsTabHref}
            className="font-medium text-primary hover:underline"
            scroll={false}
          >
            View all {activeCount}
          </Link>
        ) : null}
      </div>
    </div>
  );
}

function PanelVariant({ clientId, portSlug }: { clientId: string; portSlug: string }) {
  const pathname = usePathname();
  const { data, isLoading } = useClientInterests(clientId);
  const interests = (data?.data ?? []).filter((i) => !i.archivedAt);
  const interestsTabHref = `${pathname}?tab=interests` as Route;

  if (isLoading) {
    return (
      <div className="space-y-2">
        <Skeleton className="h-4 w-40" aria-hidden />
        <Skeleton className="h-2 w-48" aria-hidden />
      </div>
    );
  }

  if (interests.length === 0) {
    return (
      <div className="flex flex-wrap items-center justify-between gap-2">
        <div>
          <p className="text-sm font-medium text-foreground">No active interests</p>
          <p className="text-xs text-muted-foreground">
            Start one to begin tracking the sales process.
          </p>
        </div>
        <Link
          href={`/${portSlug}/interests/new` as Route}
          className="inline-flex items-center gap-1 text-xs font-medium text-primary hover:underline"
        >
          Start interest <ArrowRight className="size-3" aria-hidden />
        </Link>
      </div>
    );
  }

  const sorted = [...interests].sort(
    (a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime(),
  );

  return (
    <div className="space-y-3">
      <div className="flex items-center justify-between gap-2">
        <span className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
          Sales pipeline · {interests.length} active
        </span>
        <Link
          href={interestsTabHref}
          className="text-xs font-medium text-primary hover:underline"
          scroll={false}
        >
          Manage
        </Link>
      </div>

      <ul className="space-y-2">
        {sorted.map((i) => {
          const stage = safeStage(i.pipelineStage);
          const rowBerthDisplay = deriveInterestBerthLabel(i.berthMoorings) ?? i.berthMooringNumber;
          const berthLabel = rowBerthDisplay ? `Berth ${rowBerthDisplay}` : 'General interest';
          const href = `/${portSlug}/interests/${i.id}` as Route;
          return (
            <li key={i.id}>
              <Link
                href={href}
                className="group flex items-center gap-3 rounded-lg p-2 -m-2 transition-colors hover:bg-foreground/5"
              >
                <div className="min-w-0 flex-1">
                  <div className="flex items-center gap-2 flex-wrap">
                    <span className="truncate text-sm font-medium text-foreground">
                      {berthLabel}
                    </span>
                    <span
                      className={cn(
                        'shrink-0 rounded-full px-2 py-0.5 text-xs font-medium',
                        STAGE_BADGE[stage],
                      )}
                    >
                      {STAGE_LABELS[stage]}
                    </span>
                  </div>
                  {/* Requirements one-liner: "Wants 50ft × 18ft × 8ft · Referral".
                      Hidden when the rep hasn't captured any constraints yet -
                      noise reduction over empty placeholders. */}
                  {(() => {
                    const dims = [i.desiredLengthFt, i.desiredWidthFt, i.desiredDraftFt]
                      .filter((v): v is string => Boolean(v))
                      .map((v) => `${Number(v).toFixed(0)}ft`);
                    const summary: string[] = [];
                    if (dims.length > 0) summary.push(`Wants ${dims.join(' × ')}`);
                    if (i.source) summary.push(i.source);
                    return summary.length > 0 ? (
                      <div className="mt-0.5 truncate text-xs text-muted-foreground">
                        {summary.join(' · ')}
                      </div>
                    ) : null;
                  })()}
                  <div className="mt-1">
                    <StageStepper current={stage} size="xs" />
                  </div>
                  {i.tags && i.tags.length > 0 ? (
                    <div className="mt-1 flex flex-wrap gap-1">
                      {i.tags.slice(0, 3).map((t) => (
                        <TagBadge key={t.id} name={t.name} color={t.color} />
                      ))}
                      {i.tags.length > 3 ? (
                        <span className="text-xs text-muted-foreground">+{i.tags.length - 3}</span>
                      ) : null}
                    </div>
                  ) : null}
                </div>
                <ChevronRight
                  className="size-3.5 shrink-0 text-muted-foreground transition-transform group-hover:translate-x-0.5"
                  aria-hidden
                />
              </Link>
            </li>
          );
        })}
      </ul>
    </div>
  );
}

export function ClientPipelineSummary({ clientId, variant = 'panel' }: PipelineSummaryProps) {
  const routeParams = useParams<{ portSlug: string }>();
  const portSlug = routeParams?.portSlug ?? '';

  return variant === 'hero' ? (
    <HeroVariant clientId={clientId} portSlug={portSlug} />
  ) : (
    <PanelVariant clientId={clientId} portSlug={portSlug} />
  );
}
