'use client';

import { useState } from 'react';
import { type ColumnDef } from '@tanstack/react-table';
import { MoreHorizontal, Pencil, Activity, RefreshCw } from 'lucide-react';
import { useRouter, useParams } from 'next/navigation';

import { Button } from '@/components/ui/button';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { TagBadge } from '@/components/shared/tag-badge';
import { StatusPill, type StatusPillStatus } from '@/components/ui/status-pill';
import { formatCurrency } from '@/lib/utils/currency';
import { mooringLetterDot } from './mooring-letter-tone';
import { stageBadgeClass, stageLabel } from '@/lib/constants';
import { CatchUpWizard } from '@/components/berths/catch-up-wizard';
import { ActiveInterestsPopover } from '@/components/berths/active-interests-popover';

export type BerthRow = {
  id: string;
  mooringNumber: string;
  area: string | null;
  status: string;
  // Dimensions (both units; row falls back when one is null)
  lengthFt: string | null;
  widthFt: string | null;
  draftFt: string | null;
  lengthM: string | null;
  widthM: string | null;
  draftM: string | null;
  widthIsMinimum: boolean | null;
  // Capacity
  nominalBoatSize: string | null;
  nominalBoatSizeM: string | null;
  waterDepth: string | null;
  waterDepthM: string | null;
  waterDepthIsMinimum: boolean | null;
  // Pontoon details (NocoDB)
  sidePontoon: string | null;
  mooringType: string | null;
  cleatType: string | null;
  cleatCapacity: string | null;
  bollardType: string | null;
  bollardCapacity: string | null;
  access: string | null;
  bowFacing: string | null;
  berthApproved: boolean | null;
  // Power
  powerCapacity: string | null;
  voltage: string | null;
  // Pricing
  price: string | null;
  priceCurrency: string;
  weeklyRateHighUsd: string | null;
  weeklyRateLowUsd: string | null;
  dailyRateHighUsd: string | null;
  dailyRateLowUsd: string | null;
  pricingValidUntil: string | null;
  // Tenure
  tenureType: string;
  tenureYears: number | null;
  tenureStartDate: string | null;
  tenureEndDate: string | null;
  tags: Array<{ id: string; name: string; color: string }>;
  /** Most-advanced pipeline stage among the berth's active interests. Null
   *  when no active interest is linked. Read-only; computed server-side. */
  latestInterestStage?: string | null;
  /** Count of non-terminal, non-archived interests linked to this berth.
   *  Drives the "Active interests" column + the demand sort. */
  activeInterestCount?: number;
  /** #67: source of the last status write. 'manual' when a human set it
   *  via the API; 'automated' when a berth-rule fired; null on rows that
   *  haven't been touched since seed. The reconciliation surface treats
   *  'manual' + no latestInterestStage as a row needing catch-up. */
  statusOverrideMode?: string | null;
};

/**
 * Toggleable columns for the berth list ColumnPicker. Heavy NocoDB
 * fields default to hidden; reps can switch them on per-table-view.
 * `mooringNumber` is intentionally omitted from this list — it's the
 * primary identifier and always visible.
 */
export const BERTH_COLUMN_OPTIONS: Array<{ id: string; label: string }> = [
  { id: 'area', label: 'Area' },
  { id: 'status', label: 'Status' },
  { id: 'latestInterestStage', label: 'Latest deal stage' },
  { id: 'activeInterestCount', label: 'Active interests' },
  { id: 'sidePontoon', label: 'Side / Pontoon' },
  { id: 'dimensions', label: 'Dimensions' },
  { id: 'nominalBoatSize', label: 'Nominal boat size' },
  { id: 'waterDepth', label: 'Water depth' },
  { id: 'mooringType', label: 'Mooring type' },
  { id: 'cleat', label: 'Cleat (type · capacity)' },
  { id: 'bollard', label: 'Bollard (type · capacity)' },
  { id: 'access', label: 'Access' },
  { id: 'bowFacing', label: 'Bow facing' },
  { id: 'berthApproved', label: 'Approved' },
  { id: 'power', label: 'Power (kW · V)' },
  { id: 'price', label: 'Price' },
  { id: 'rates', label: 'Daily / Weekly rates' },
  { id: 'pricingValidUntil', label: 'Pricing valid until' },
  { id: 'tenure', label: 'Tenure' },
  { id: 'tags', label: 'Tags' },
];

/** Hidden by default — power-users turn them on via the picker. */
export const BERTH_DEFAULT_HIDDEN: string[] = [
  'tenure',
  'sidePontoon',
  'nominalBoatSize',
  'waterDepth',
  'mooringType',
  'cleat',
  'bollard',
  'access',
  'bowFacing',
  'berthApproved',
  'power',
  'rates',
  'pricingValidUntil',
];

const BERTH_STATUS_PILL: Record<string, StatusPillStatus> = {
  available: 'available',
  under_offer: 'under_offer',
  sold: 'sold',
};

const BERTH_STATUS_LABELS: Record<string, string> = {
  available: 'Available',
  under_offer: 'Under Offer',
  sold: 'Sold',
};

function StatusBadge({ status }: { status: string }) {
  return (
    <StatusPill status={BERTH_STATUS_PILL[status] ?? 'pending'}>
      {BERTH_STATUS_LABELS[status] ?? status}
    </StatusPill>
  );
}

/**
 * #67 Phase 2: small amber chip beside the status pill flagging rows
 * whose status was set manually and has no backing interest. These are
 * the candidates for the catch-up wizard — the rep flipped a berth to
 * "Under Offer" or "Sold" without ever creating the matching deal.
 */
function ManualBadge() {
  return (
    <span
      className="inline-flex items-center rounded-full border border-amber-300 bg-amber-50 px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-amber-800"
      title="Status set manually with no backing interest — needs catch-up"
    >
      Manual
    </span>
  );
}

function ActionsCell({ row }: { row: { original: BerthRow } }) {
  const router = useRouter();
  const params = useParams<{ portSlug: string }>();
  const berth = row.original;
  const [catchUpOpen, setCatchUpOpen] = useState(false);
  const isManualUnreconciled = berth.statusOverrideMode === 'manual' && !berth.latestInterestStage;

  return (
    <>
      <DropdownMenu>
        <DropdownMenuTrigger asChild>
          <Button
            variant="ghost"
            size="icon"
            className="h-8 w-8"
            aria-label={`Row actions for berth ${berth.mooringNumber ?? ''}`.trim()}
            onClick={(e) => e.stopPropagation()}
          >
            <MoreHorizontal className="h-4 w-4" aria-hidden />
            <span className="sr-only">Open menu</span>
          </Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent align="end">
          <DropdownMenuItem
            onClick={(e) => {
              e.stopPropagation();
              router.push(`/${params.portSlug}/berths/${berth.id}`);
            }}
          >
            <Activity className="mr-2 h-4 w-4" aria-hidden />
            View details
          </DropdownMenuItem>
          <DropdownMenuItem
            onClick={(e) => {
              e.stopPropagation();
              router.push(`/${params.portSlug}/berths/${berth.id}?edit=true`);
            }}
          >
            <Pencil className="mr-2 h-4 w-4" aria-hidden />
            Edit
          </DropdownMenuItem>
          {isManualUnreconciled ? (
            <DropdownMenuItem
              onClick={(e) => {
                e.stopPropagation();
                setCatchUpOpen(true);
              }}
            >
              <RefreshCw className="mr-2 h-4 w-4" aria-hidden />
              Catch up…
            </DropdownMenuItem>
          ) : null}
        </DropdownMenuContent>
      </DropdownMenu>
      {isManualUnreconciled ? (
        <CatchUpWizard
          berthId={catchUpOpen ? berth.id : null}
          open={catchUpOpen}
          onOpenChange={setCatchUpOpen}
        />
      ) : null}
    </>
  );
}

function ActiveInterestsCell({ berthId, count }: { berthId: string; count: number }) {
  const params = useParams<{ portSlug: string }>();
  const portSlug = params?.portSlug ?? '';
  return <ActiveInterestsPopover berthId={berthId} portSlug={portSlug} count={count} />;
}

function joinNonNull(parts: Array<string | null | undefined>, sep = ' · '): string {
  return parts.filter((p): p is string => Boolean(p)).join(sep);
}

function formatMoney(amount: string | null, currency: string): string | null {
  if (!amount) return null;
  return formatCurrency(amount, currency, { maxFractionDigits: 0 });
}

export const berthColumns: ColumnDef<BerthRow, unknown>[] = [
  {
    accessorKey: 'mooringNumber',
    header: 'Mooring #',
    cell: ({ row }) => {
      const dot = mooringLetterDot(row.original.mooringNumber);
      return (
        <span className="inline-flex items-center gap-2 font-medium">
          {dot && <span className={`inline-block size-2 rounded-full ${dot}`} aria-hidden />}
          {row.original.mooringNumber}
        </span>
      );
    },
  },
  {
    id: 'area',
    accessorKey: 'area',
    header: 'Area',
    cell: ({ row }) => row.original.area ?? '-',
  },
  {
    id: 'status',
    accessorKey: 'status',
    header: 'Status',
    cell: ({ row }) => {
      const r = row.original;
      const isManualUnreconciled = r.statusOverrideMode === 'manual' && !r.latestInterestStage;
      return (
        <div className="inline-flex items-center gap-1.5">
          <StatusBadge status={r.status} />
          {isManualUnreconciled ? <ManualBadge /> : null}
        </div>
      );
    },
  },
  {
    id: 'latestInterestStage',
    header: 'Latest deal stage',
    enableSorting: true,
    cell: ({ row }) => {
      const s = row.original.latestInterestStage;
      if (!s) return <span className="text-muted-foreground">-</span>;
      return (
        <span
          className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${stageBadgeClass(s)}`}
        >
          {stageLabel(s)}
        </span>
      );
    },
  },
  {
    id: 'activeInterestCount',
    accessorKey: 'activeInterestCount',
    header: 'Active interests',
    cell: ({ row }) => (
      <ActiveInterestsCell
        berthId={row.original.id}
        count={row.original.activeInterestCount ?? 0}
      />
    ),
  },
  {
    id: 'sidePontoon',
    header: 'Side / Pontoon',
    enableSorting: false,
    cell: ({ row }) => row.original.sidePontoon ?? '-',
  },
  {
    id: 'dimensions',
    header: 'Dimensions',
    enableSorting: false,
    cell: ({ row }) => {
      const { lengthM, widthM, draftM, widthIsMinimum } = row.original;
      if (!lengthM && !widthM) return '-';
      const widthLabel = widthM ? `${widthIsMinimum ? '≥' : ''}${widthM}m` : '?';
      const base = `${lengthM ?? '?'}m × ${widthLabel}`;
      return draftM ? `${base} (draft ${draftM}m)` : base;
    },
  },
  {
    id: 'nominalBoatSize',
    header: 'Boat size',
    enableSorting: false,
    cell: ({ row }) => {
      const m = row.original.nominalBoatSizeM;
      const ft = row.original.nominalBoatSize;
      if (!m && !ft) return '-';
      return m ? `${m}m` : `${ft}ft`;
    },
  },
  {
    id: 'waterDepth',
    header: 'Water depth',
    enableSorting: false,
    cell: ({ row }) => {
      const { waterDepthM, waterDepthIsMinimum } = row.original;
      if (!waterDepthM) return '-';
      return `${waterDepthIsMinimum ? '≥' : ''}${waterDepthM}m`;
    },
  },
  {
    id: 'mooringType',
    header: 'Mooring type',
    enableSorting: false,
    cell: ({ row }) => row.original.mooringType ?? '-',
  },
  {
    id: 'cleat',
    header: 'Cleat',
    enableSorting: false,
    cell: ({ row }) => joinNonNull([row.original.cleatType, row.original.cleatCapacity]) || '-',
  },
  {
    id: 'bollard',
    header: 'Bollard',
    enableSorting: false,
    cell: ({ row }) => joinNonNull([row.original.bollardType, row.original.bollardCapacity]) || '-',
  },
  {
    id: 'access',
    header: 'Access',
    enableSorting: false,
    cell: ({ row }) => row.original.access ?? '-',
  },
  {
    id: 'bowFacing',
    header: 'Bow facing',
    enableSorting: false,
    cell: ({ row }) => row.original.bowFacing ?? '-',
  },
  {
    id: 'berthApproved',
    header: 'Approved',
    enableSorting: false,
    cell: ({ row }) => (row.original.berthApproved ? 'Yes' : 'No'),
  },
  {
    id: 'power',
    header: 'Power',
    enableSorting: false,
    cell: ({ row }) => {
      const kw = row.original.powerCapacity;
      const v = row.original.voltage;
      if (!kw && !v) return '-';
      return joinNonNull([kw ? `${kw}kW` : null, v ? `${v}V` : null]);
    },
  },
  {
    id: 'price',
    accessorKey: 'price',
    header: 'Price',
    cell: ({ row }) => formatMoney(row.original.price, row.original.priceCurrency) ?? '-',
  },
  {
    id: 'rates',
    header: 'Rates (USD)',
    enableSorting: false,
    cell: ({ row }) => {
      const { dailyRateLowUsd, dailyRateHighUsd, weeklyRateLowUsd, weeklyRateHighUsd } =
        row.original;
      const daily =
        dailyRateLowUsd && dailyRateHighUsd
          ? `${dailyRateLowUsd}–${dailyRateHighUsd}/d`
          : dailyRateLowUsd
            ? `${dailyRateLowUsd}/d`
            : null;
      const weekly =
        weeklyRateLowUsd && weeklyRateHighUsd
          ? `${weeklyRateLowUsd}–${weeklyRateHighUsd}/wk`
          : weeklyRateLowUsd
            ? `${weeklyRateLowUsd}/wk`
            : null;
      return joinNonNull([daily, weekly]) || '-';
    },
  },
  {
    id: 'pricingValidUntil',
    header: 'Pricing valid',
    enableSorting: false,
    cell: ({ row }) => row.original.pricingValidUntil ?? '-',
  },
  {
    id: 'tenure',
    accessorKey: 'tenureType',
    header: 'Tenure',
    cell: ({ row }) => (row.original.tenureType === 'permanent' ? 'Permanent' : 'Fixed Term'),
  },
  {
    id: 'tags',
    header: 'Tags',
    enableSorting: false,
    cell: ({ row }) => {
      const { tags } = row.original;
      if (!tags || tags.length === 0) return null;
      return (
        <div className="flex flex-wrap gap-1">
          {tags.slice(0, 3).map((tag) => (
            <TagBadge key={tag.id} name={tag.name} color={tag.color} />
          ))}
          {tags.length > 3 && (
            <span className="text-xs text-muted-foreground">+{tags.length - 3}</span>
          )}
        </div>
      );
    },
  },
  {
    id: 'actions',
    header: '',
    enableSorting: false,
    size: 48,
    cell: ({ row }) => <ActionsCell row={row} />,
  },
];
