'use client';

/**
 * Sales Performance — 5 detail tables (Report 01 Tables 1-5).
 *
 *   1. Rep performance detail (only when single-rep ⇒ replaces
 *      leaderboard, which auto-hides in the parent)
 *   2. Stalled deals (stage-aware thresholds)
 *   3. Closing this month
 *   4. Recent wins (last 5)
 *   5. Lost-reason breakdown
 *
 * All five share the same Card primitive + table styling so they read
 * as a coherent block. Rep performance detail is rendered conditionally
 * by the parent (only shown for single-rep ports).
 */

import { useState } from 'react';
import Link from 'next/link';
import type { Route } from 'next';
import { ChevronDown, ChevronRight, ArrowRight } from 'lucide-react';

import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { cn } from '@/lib/utils';
import { STAGE_LABELS, type PipelineStage } from '@/lib/constants';
import { useUIStore } from '@/stores/ui-store';
import { formatMoneyCompact as formatMoney } from '@/lib/reports/format-currency';

// ─── Shared types (mirror service shapes) ────────────────────────────────────

interface OpenDealRow {
  id: string;
  clientName: string;
  primaryBerth: string | null;
  stage: PipelineStage;
  stageValue: number;
  stageValueCurrency: string;
  daysInStage: number | null;
  lastContact: string | null;
}

interface RepPerformanceDetailRow {
  userId: string | null;
  displayName: string;
  newDeals: number;
  won: number;
  lost: number;
  inFlight: number;
  pipelineValue: number;
  pipelineValueCurrency: string;
  winRate: number | null;
  medianTimeToCloseDays: number | null;
  openDeals: OpenDealRow[];
}

interface StalledDealRow {
  id: string;
  clientName: string;
  stage: PipelineStage;
  daysSinceLastContact: number | null;
  daysInStage: number | null;
  stageValue: number;
  stageValueCurrency: string;
  rep: string;
  primaryBerth: string | null;
}

interface ClosingThisMonthRow {
  id: string;
  clientName: string;
  stage: PipelineStage;
  stageValue: number;
  stageValueCurrency: string;
  daysInStage: number | null;
  rep: string;
  primaryBerth: string | null;
}

interface RecentWinRow {
  id: string;
  clientName: string;
  primaryBerth: string | null;
  finalValue: number;
  currency: string;
  daysToClose: number | null;
  rep: string;
  outcomeAt: string;
}

interface LostReasonRow {
  outcome: string;
  count: number;
  totalValueLost: number;
  currency: string;
  avgDaysFromFirstContactToLoss: number | null;
}

const LOSS_LABEL: Record<string, string> = {
  lost_other_marina: 'Lost to competitor',
  lost_unqualified: 'Unqualified',
  lost_no_response: 'No response',
  cancelled: 'Cancelled',
};

// ─── Public component bundles the four always-shown tables ───────────────────

interface Props {
  repPerformanceDetail: RepPerformanceDetailRow[];
  stalledDeals: StalledDealRow[];
  closingThisMonth: ClosingThisMonthRow[];
  recentWins: RecentWinRow[];
  lostReasonBreakdown: LostReasonRow[];
  /** When false (multi-rep port), don't show Rep performance detail
   *  (the leaderboard above already handles that audience). */
  showRepPerformanceDetail: boolean;
}

export function SalesDetailTables({
  repPerformanceDetail,
  stalledDeals,
  closingThisMonth,
  recentWins,
  lostReasonBreakdown,
  showRepPerformanceDetail,
}: Props) {
  return (
    <div className="space-y-6">
      {showRepPerformanceDetail ? <RepPerformanceDetailTable rows={repPerformanceDetail} /> : null}
      <StalledDealsTable rows={stalledDeals} />
      <ClosingThisMonthTable rows={closingThisMonth} />
      <RecentWinsTable rows={recentWins} />
      <LostReasonTable rows={lostReasonBreakdown} />
    </div>
  );
}

// ─── 1. Rep performance detail (single-rep collapse) ─────────────────────────

function RepPerformanceDetailTable({ rows }: { rows: RepPerformanceDetailRow[] }) {
  const portSlug = useUIStore((s) => s.currentPortSlug) ?? '';
  // Always expand in single-rep mode: there's only one rep so collapsing
  // it would be pointless. Multi-rep gets per-row toggles.
  const [expanded, setExpanded] = useState<Set<string>>(
    () => new Set(rows.length === 1 ? rows.map((r) => r.userId ?? 'unassigned') : []),
  );

  function toggle(key: string) {
    setExpanded((prev) => {
      const next = new Set(prev);
      if (next.has(key)) next.delete(key);
      else next.add(key);
      return next;
    });
  }

  return (
    <Card>
      <CardHeader>
        <CardTitle className="text-base">Rep performance detail</CardTitle>
        <p className="text-xs text-muted-foreground">
          Per-rep summary + their open deals. Click a row to expand the open-deals list.
        </p>
      </CardHeader>
      <CardContent>
        {rows.length === 0 ? (
          <EmptyRow>No rep activity in the period.</EmptyRow>
        ) : (
          <div className="space-y-2">
            {rows.map((row) => {
              const key = row.userId ?? 'unassigned';
              const isOpen = expanded.has(key);
              return (
                <div key={key} className="rounded-md border border-border overflow-hidden">
                  <button
                    type="button"
                    onClick={() => toggle(key)}
                    className="w-full flex items-center gap-3 px-3 py-2.5 text-left hover:bg-muted/40 transition-colors"
                  >
                    {isOpen ? (
                      <ChevronDown className="h-4 w-4 text-muted-foreground shrink-0" aria-hidden />
                    ) : (
                      <ChevronRight
                        className="h-4 w-4 text-muted-foreground shrink-0"
                        aria-hidden
                      />
                    )}
                    <span className="font-medium text-foreground flex-1">{row.displayName}</span>
                    <span className="text-xs text-muted-foreground tabular-nums">
                      {row.newDeals} new · {row.won} won · {row.lost} lost · {row.inFlight} active
                    </span>
                  </button>
                  {isOpen && (
                    <div className="border-t border-border bg-muted/20">
                      {row.openDeals.length === 0 ? (
                        <p className="px-3 py-3 text-xs text-muted-foreground">No active deals.</p>
                      ) : (
                        <table className="w-full text-sm">
                          <thead>
                            <tr className="text-[11px] uppercase tracking-wider text-muted-foreground">
                              <th className="px-3 py-2 text-left font-medium">Client</th>
                              <th className="px-3 py-2 text-left font-medium">Berth</th>
                              <th className="px-3 py-2 text-left font-medium">Stage</th>
                              <th className="px-3 py-2 text-right font-medium">Value</th>
                              <th className="px-3 py-2 text-right font-medium">Days in stage</th>
                            </tr>
                          </thead>
                          <tbody>
                            {row.openDeals.map((d) => (
                              <tr key={d.id} className="border-t border-border">
                                <td className="px-3 py-2">
                                  <Link
                                    href={`/${portSlug}/interests/${d.id}` as Route}
                                    className="text-foreground hover:text-primary transition-colors"
                                  >
                                    {d.clientName}
                                  </Link>
                                </td>
                                <td className="px-3 py-2 text-muted-foreground">
                                  {d.primaryBerth ?? '—'}
                                </td>
                                <td className="px-3 py-2 text-muted-foreground">
                                  {STAGE_LABELS[d.stage]}
                                </td>
                                <td className="px-3 py-2 text-right tabular-nums">
                                  {d.stageValue > 0
                                    ? formatMoney(d.stageValue, row.pipelineValueCurrency)
                                    : '—'}
                                </td>
                                <td className="px-3 py-2 text-right tabular-nums text-muted-foreground">
                                  {d.daysInStage ?? '—'}
                                </td>
                              </tr>
                            ))}
                          </tbody>
                        </table>
                      )}
                    </div>
                  )}
                </div>
              );
            })}
          </div>
        )}
      </CardContent>
    </Card>
  );
}

// ─── 2. Stalled deals ────────────────────────────────────────────────────────

function StalledDealsTable({ rows }: { rows: StalledDealRow[] }) {
  const portSlug = useUIStore((s) => s.currentPortSlug) ?? '';
  return (
    <Card>
      <CardHeader>
        <CardTitle className="text-base">Stalled deals</CardTitle>
        <p className="text-xs text-muted-foreground">
          Active deals not contacted within their stage&apos;s threshold (enquiry 21d · qualified
          14d · nurturing 60d · eoi 10d · reservation 7d · deposit 7d · contract 5d).
        </p>
      </CardHeader>
      <CardContent>
        {rows.length === 0 ? (
          <EmptyRow>Nothing stalled — everything&apos;s being worked.</EmptyRow>
        ) : (
          <TableShell
            headers={['Client', 'Stage', 'Days since contact', 'Days in stage', 'Value', 'Rep']}
            rightAligned={[2, 3, 4]}
          >
            {rows.map((r) => (
              <tr key={r.id} className="border-t border-border hover:bg-muted/40 transition-colors">
                <td className="px-3 py-2">
                  <Link
                    href={`/${portSlug}/interests/${r.id}` as Route}
                    className="text-foreground hover:text-primary transition-colors"
                  >
                    {r.clientName}
                    {r.primaryBerth ? (
                      <span className="text-muted-foreground"> · {r.primaryBerth}</span>
                    ) : null}
                  </Link>
                </td>
                <td className="px-3 py-2 text-muted-foreground">{STAGE_LABELS[r.stage]}</td>
                <td className="px-3 py-2 text-right tabular-nums text-rose-700 font-medium">
                  {r.daysSinceLastContact === null ? 'never' : `${r.daysSinceLastContact}d`}
                </td>
                <td className="px-3 py-2 text-right tabular-nums text-muted-foreground">
                  {r.daysInStage ?? '—'}
                </td>
                <td className="px-3 py-2 text-right tabular-nums">
                  {r.stageValue > 0 ? formatMoney(r.stageValue, r.stageValueCurrency) : '—'}
                </td>
                <td className="px-3 py-2 text-muted-foreground">{r.rep}</td>
              </tr>
            ))}
          </TableShell>
        )}
      </CardContent>
    </Card>
  );
}

// ─── 3. Closing this month ───────────────────────────────────────────────────

function ClosingThisMonthTable({ rows }: { rows: ClosingThisMonthRow[] }) {
  const portSlug = useUIStore((s) => s.currentPortSlug) ?? '';
  return (
    <Card>
      <CardHeader>
        <CardTitle className="text-base">Closing soon</CardTitle>
        <p className="text-xs text-muted-foreground">
          Late-stage active deals (reservation / deposit paid / contract) sorted by value. The
          &quot;don&apos;t drop these&quot; list.
        </p>
      </CardHeader>
      <CardContent>
        {rows.length === 0 ? (
          <EmptyRow>No deals in late stages yet.</EmptyRow>
        ) : (
          <TableShell
            headers={['Client', 'Stage', 'Days in stage', 'Value', 'Rep']}
            rightAligned={[2, 3]}
          >
            {rows.map((r) => (
              <tr key={r.id} className="border-t border-border hover:bg-muted/40 transition-colors">
                <td className="px-3 py-2">
                  <Link
                    href={`/${portSlug}/interests/${r.id}` as Route}
                    className="text-foreground hover:text-primary transition-colors"
                  >
                    {r.clientName}
                    {r.primaryBerth ? (
                      <span className="text-muted-foreground"> · {r.primaryBerth}</span>
                    ) : null}
                  </Link>
                </td>
                <td className="px-3 py-2">
                  <Badge variant="outline" className="text-[11px]">
                    {STAGE_LABELS[r.stage]}
                  </Badge>
                </td>
                <td className="px-3 py-2 text-right tabular-nums text-muted-foreground">
                  {r.daysInStage ?? '—'}
                </td>
                <td className="px-3 py-2 text-right tabular-nums font-medium">
                  {r.stageValue > 0 ? formatMoney(r.stageValue, r.stageValueCurrency) : '—'}
                </td>
                <td className="px-3 py-2 text-muted-foreground">{r.rep}</td>
              </tr>
            ))}
          </TableShell>
        )}
      </CardContent>
    </Card>
  );
}

// ─── 4. Recent wins ──────────────────────────────────────────────────────────

function RecentWinsTable({ rows }: { rows: RecentWinRow[] }) {
  const portSlug = useUIStore((s) => s.currentPortSlug) ?? '';
  return (
    <Card>
      <CardHeader>
        <CardTitle className="text-base">Recent wins</CardTitle>
        <p className="text-xs text-muted-foreground">
          The 5 most recently closed-won deals — small celebratory strip.
        </p>
      </CardHeader>
      <CardContent>
        {rows.length === 0 ? (
          <EmptyRow>No wins yet. The next one will appear here.</EmptyRow>
        ) : (
          <ul className="divide-y divide-border">
            {rows.map((r) => (
              <li key={r.id} className="py-2.5 flex items-center gap-3">
                <Link
                  href={`/${portSlug}/interests/${r.id}` as Route}
                  className="font-medium text-foreground hover:text-primary transition-colors flex-1 truncate"
                >
                  {r.clientName}
                  {r.primaryBerth ? (
                    <span className="text-muted-foreground font-normal"> · {r.primaryBerth}</span>
                  ) : null}
                </Link>
                <span className="text-sm tabular-nums text-emerald-700 font-medium w-24 text-right">
                  {formatMoney(r.finalValue, r.currency)}
                </span>
                <span className="text-xs text-muted-foreground w-24 text-right tabular-nums">
                  {r.daysToClose !== null ? `${r.daysToClose}d to close` : '—'}
                </span>
                <span className="text-xs text-muted-foreground w-28 text-right hidden sm:inline">
                  {r.rep}
                </span>
                <ArrowRight className="h-3.5 w-3.5 text-muted-foreground" aria-hidden />
              </li>
            ))}
          </ul>
        )}
      </CardContent>
    </Card>
  );
}

// ─── 5. Lost reason breakdown ────────────────────────────────────────────────

function LostReasonTable({ rows }: { rows: LostReasonRow[] }) {
  return (
    <Card>
      <CardHeader>
        <CardTitle className="text-base">Lost reason breakdown</CardTitle>
        <p className="text-xs text-muted-foreground">
          Where the losses went, what they cost us, and how long they took to die. Post-mortem fuel.
        </p>
      </CardHeader>
      <CardContent>
        {rows.length === 0 ? (
          <EmptyRow>No losses in the period.</EmptyRow>
        ) : (
          <TableShell
            headers={['Reason', 'Count', 'Total value lost', 'Avg days to loss']}
            rightAligned={[1, 2, 3]}
          >
            {rows.map((r) => (
              <tr
                key={r.outcome}
                className="border-t border-border hover:bg-muted/40 transition-colors"
              >
                <td className="px-3 py-2 font-medium text-foreground">
                  {LOSS_LABEL[r.outcome] ?? r.outcome}
                </td>
                <td className="px-3 py-2 text-right tabular-nums">{r.count}</td>
                <td className="px-3 py-2 text-right tabular-nums">
                  {r.totalValueLost > 0 ? formatMoney(r.totalValueLost, r.currency) : '—'}
                </td>
                <td className="px-3 py-2 text-right tabular-nums text-muted-foreground">
                  {r.avgDaysFromFirstContactToLoss === null
                    ? '—'
                    : `${r.avgDaysFromFirstContactToLoss.toFixed(0)}d`}
                </td>
              </tr>
            ))}
          </TableShell>
        )}
      </CardContent>
    </Card>
  );
}

// ─── Primitives ──────────────────────────────────────────────────────────────

function TableShell({
  headers,
  rightAligned = [],
  children,
}: {
  headers: string[];
  rightAligned?: number[];
  children: React.ReactNode;
}) {
  return (
    <div className="overflow-x-auto -mx-2">
      <table className="w-full text-sm">
        <thead>
          <tr className="border-b border-border">
            {headers.map((h, i) => (
              <th
                key={h}
                className={cn(
                  'px-3 py-2 text-[11px] font-medium uppercase tracking-wider text-muted-foreground',
                  rightAligned.includes(i) ? 'text-right' : 'text-left',
                )}
              >
                {h}
              </th>
            ))}
          </tr>
        </thead>
        <tbody>{children}</tbody>
      </table>
    </div>
  );
}

function EmptyRow({ children }: { children: React.ReactNode }) {
  return <p className="py-6 text-sm text-muted-foreground text-center">{children}</p>;
}
