'use client';

import { useMutation, useQueryClient } from '@tanstack/react-query';

import { type DetailTab } from '@/components/shared/detail-layout';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { EntityActivityFeed } from '@/components/shared/entity-activity-feed';
import { InlineEditableField } from '@/components/shared/inline-editable-field';
import { InlineTagEditor } from '@/components/shared/inline-tag-editor';
import { apiFetch } from '@/lib/api/client';
import {
  BERTH_ACCESS_OPTIONS,
  BERTH_BOLLARD_CAPACITIES,
  BERTH_BOLLARD_TYPES,
  BERTH_BOW_FACING_OPTIONS,
  BERTH_CLEAT_CAPACITIES,
  BERTH_CLEAT_TYPES,
  BERTH_MOORING_TYPES,
  BERTH_SIDE_PONTOON_OPTIONS,
  toSelectOptions,
} from '@/lib/constants';
import { BerthReservationsTab } from './berth-reservations-tab';
import { BerthInterestsTab } from './berth-interests-tab';
import { BerthInterestPulse } from './berth-interest-pulse';
import { BerthDocumentsTab } from './berth-documents-tab';
import { BerthDealDocumentsTab } from './berth-deal-documents-tab';

type BerthData = {
  id: string;
  mooringNumber: string;
  area: string | null;
  status: string;
  lengthFt: string | null;
  lengthM: string | null;
  widthFt: string | null;
  widthM: string | null;
  draftFt: string | null;
  draftM: string | null;
  widthIsMinimum: boolean | null;
  nominalBoatSize: string | null;
  nominalBoatSizeM: string | null;
  waterDepth: string | null;
  waterDepthM: string | null;
  waterDepthIsMinimum: boolean | null;
  sidePontoon: string | null;
  powerCapacity: string | null;
  voltage: string | null;
  mooringType: string | null;
  cleatType: string | null;
  cleatCapacity: string | null;
  bollardType: string | null;
  bollardCapacity: string | null;
  access: string | null;
  price: string | null;
  priceCurrency: string;
  bowFacing: string | null;
  berthApproved: boolean | null;
  tenureType: string;
  tenureYears: number | null;
  tenureStartDate: string | null;
  tenureEndDate: string | null;
  statusLastChangedReason: string | null;
  statusLastModified: string | null;
  tags: Array<{ id: string; name: string; color: string }>;
};

function SpecRow({ label, value }: { label: string; value: React.ReactNode }) {
  if (!value && value !== 0 && value !== false) return null;
  // Mobile-first: stack vertically with label on top so long values
  // (e.g. "206.69 ft / 62.99 m") never clip at the right edge.
  // From `sm` (>=640px) up: switch to the original two-column layout.
  return (
    <div className="flex flex-col gap-0.5 py-2 text-sm sm:flex-row sm:items-baseline sm:justify-between sm:gap-3">
      <span className="text-muted-foreground">{label}</span>
      <span className="font-medium sm:max-w-[60%] sm:text-right">{value}</span>
    </div>
  );
}

function useBerthPatch(berthId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: async (patch: Record<string, string | number | boolean | null>) =>
      apiFetch(`/api/v1/berths/${berthId}`, {
        method: 'PATCH',
        body: patch,
      }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['berths', berthId] });
      qc.invalidateQueries({ queryKey: ['berths'] });
    },
  });
}

/**
 * Editable spec row. Wraps SpecRow with InlineEditableField for fields
 * the operator commonly tweaks (length, width, draft, side pontoon, etc).
 * Read-only fields (mooringNumber, area) keep using plain SpecRow.
 *
 * Numeric fields are stored as strings in the schema (postgres NUMERIC);
 * the `numeric` flag tells us to parse before sending and display "-" when
 * blank.
 */
function EditableSpec({
  label,
  value,
  field,
  patch,
  numeric = false,
  suffix,
  selectOptions,
  linkedUnit,
}: {
  label: string;
  value: string | null;
  field: string;
  patch: ReturnType<typeof useBerthPatch>;
  numeric?: boolean;
  suffix?: string;
  /** When provided, the inline editor uses a `<Select>` constrained to these
   *  values. Mirrors the canonical NocoDB SingleSelect choices for the field. */
  selectOptions?: readonly string[];
  /** When set, saving this numeric field also patches the paired column with
   *  the converted unit (e.g. ft → m via 0.3048). Mirrors the legacy NocoDB
   *  Formula columns; without this the form's two-unit editors stay out of
   *  sync after an inline edit. */
  linkedUnit?: { field: string; multiplier: number };
}) {
  return (
    <div className="flex flex-col gap-0.5 py-2 text-sm sm:flex-row sm:items-baseline sm:justify-between sm:gap-3">
      <span className="text-muted-foreground">{label}</span>
      <span className="font-medium sm:max-w-[60%] sm:text-right">
        {selectOptions ? (
          <InlineEditableField
            variant="select"
            value={value}
            options={toSelectOptions(selectOptions)}
            onSave={async (next) => {
              await patch.mutateAsync({ [field]: next });
            }}
          />
        ) : (
          <InlineEditableField
            value={value}
            onSave={async (next) => {
              if (numeric) {
                if (next === null || next.trim() === '') {
                  const clear = linkedUnit
                    ? { [field]: null, [linkedUnit.field]: null }
                    : { [field]: null };
                  await patch.mutateAsync(clear);
                  return;
                }
                const n = Number.parseFloat(next);
                if (Number.isNaN(n)) throw new Error('Must be a number');
                const body: Record<string, number | null> = { [field]: n };
                if (linkedUnit) {
                  body[linkedUnit.field] = Number((n * linkedUnit.multiplier).toFixed(2));
                }
                await patch.mutateAsync(body);
                return;
              }
              await patch.mutateAsync({ [field]: next });
            }}
            placeholder={suffix ? `e.g. 25${suffix ? ` ${suffix}` : ''}` : undefined}
          />
        )}
      </span>
    </div>
  );
}

function OverviewTab({ berth }: { berth: BerthData }) {
  const patch = useBerthPatch(berth.id);
  // Round to at most 2 decimals; trim trailing zeros so "5.00" -> "5".
  const fmt = (v: string | null, fractionDigits = 2): string | null => {
    if (v == null || v === '') return null;
    const n = Number(v);
    if (Number.isNaN(n)) return v;
    return n.toLocaleString('en-US', {
      minimumFractionDigits: 0,
      maximumFractionDigits: fractionDigits,
    });
  };

  // Read-only display helper for the metric column on dimensions —
  // mirrors the pre-edit "X ft / Y m" rendering for fields where only
  // the foot value is editable today.
  const formatNominalBoatSize = (ft: string | null, m: string | null): string | null => {
    const ftFmt = fmt(ft, 0);
    const mFmt = fmt(m);
    const parts: string[] = [];
    if (ftFmt) parts.push(`${ftFmt} ft`);
    if (mFmt) parts.push(`${mFmt} m`);
    return parts.length > 0 ? parts.join(' / ') : null;
  };

  return (
    <div className="space-y-6">
      {/* Sales pulse - top-of-page so reps doing berth-level triage can see
          who's interested + how warm without clicking into the Interests tab. */}
      <BerthInterestPulse berthId={berth.id} />

      <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
        {/* Specifications */}
        <Card>
          <CardHeader className="pb-3">
            <CardTitle className="text-sm font-medium">Specifications</CardTitle>
          </CardHeader>
          <CardContent className="pt-0 divide-y">
            <EditableSpec
              label="Length (ft)"
              value={berth.lengthFt}
              field="lengthFt"
              patch={patch}
              numeric
              suffix="ft"
              linkedUnit={{ field: 'lengthM', multiplier: 0.3048 }}
            />
            <EditableSpec
              label="Width (ft)"
              value={berth.widthFt}
              field="widthFt"
              patch={patch}
              numeric
              suffix="ft"
              linkedUnit={{ field: 'widthM', multiplier: 0.3048 }}
            />
            <EditableSpec
              label="Draft (ft)"
              value={berth.draftFt}
              field="draftFt"
              patch={patch}
              numeric
              suffix="ft"
              linkedUnit={{ field: 'draftM', multiplier: 0.3048 }}
            />
            <EditableSpec
              label="Nominal Boat Size (ft)"
              value={berth.nominalBoatSize}
              field="nominalBoatSize"
              patch={patch}
              numeric
              suffix="ft"
              linkedUnit={{ field: 'nominalBoatSizeM', multiplier: 0.3048 }}
            />
            <SpecRow
              label="Nominal Boat Size (m)"
              value={
                formatNominalBoatSize(berth.nominalBoatSize, berth.nominalBoatSizeM)?.split(
                  ' / ',
                )[1] ?? null
              }
            />
            <EditableSpec
              label="Water Depth (ft)"
              value={berth.waterDepth}
              field="waterDepth"
              patch={patch}
              numeric
              suffix="ft"
              linkedUnit={{ field: 'waterDepthM', multiplier: 0.3048 }}
            />
            <EditableSpec
              label="Mooring Type"
              value={berth.mooringType}
              field="mooringType"
              patch={patch}
              selectOptions={BERTH_MOORING_TYPES}
            />
            <EditableSpec
              label="Side Pontoon"
              value={berth.sidePontoon}
              field="sidePontoon"
              patch={patch}
              selectOptions={BERTH_SIDE_PONTOON_OPTIONS}
            />
            <EditableSpec
              label="Bow Facing"
              value={berth.bowFacing}
              field="bowFacing"
              patch={patch}
              selectOptions={BERTH_BOW_FACING_OPTIONS}
            />
            <EditableSpec
              label="Access"
              value={berth.access}
              field="access"
              patch={patch}
              selectOptions={BERTH_ACCESS_OPTIONS}
            />
            <SpecRow label="Approved" value={berth.berthApproved ? 'Yes' : null} />
          </CardContent>
        </Card>

        {/* Infrastructure & Pricing */}
        <div className="space-y-6">
          <Card>
            <CardHeader className="pb-3">
              <CardTitle className="text-sm font-medium">Infrastructure</CardTitle>
            </CardHeader>
            <CardContent className="pt-0 divide-y">
              <EditableSpec
                label="Power Capacity (kW)"
                value={berth.powerCapacity}
                field="powerCapacity"
                patch={patch}
                numeric
                suffix="kW"
              />
              <EditableSpec
                label="Voltage (V)"
                value={berth.voltage}
                field="voltage"
                patch={patch}
                numeric
                suffix="V"
              />
              <EditableSpec
                label="Cleat Type"
                value={berth.cleatType}
                field="cleatType"
                patch={patch}
                selectOptions={BERTH_CLEAT_TYPES}
              />
              <EditableSpec
                label="Cleat Capacity"
                value={berth.cleatCapacity}
                field="cleatCapacity"
                patch={patch}
                selectOptions={BERTH_CLEAT_CAPACITIES}
              />
              <EditableSpec
                label="Bollard Type"
                value={berth.bollardType}
                field="bollardType"
                patch={patch}
                selectOptions={BERTH_BOLLARD_TYPES}
              />
              <EditableSpec
                label="Bollard Capacity"
                value={berth.bollardCapacity}
                field="bollardCapacity"
                patch={patch}
                selectOptions={BERTH_BOLLARD_CAPACITIES}
              />
            </CardContent>
          </Card>

          <Card>
            <CardHeader className="pb-3">
              <CardTitle className="text-sm font-medium">Tenure & Pricing</CardTitle>
            </CardHeader>
            <CardContent className="pt-0 divide-y">
              {/* Tenure type values are admin-configurable per port (Wave 5).
                  Today the list is the static union from the zod validator. */}
              <EditableSpec
                label="Tenure Type"
                value={berth.tenureType}
                field="tenureType"
                patch={patch}
                selectOptions={['permanent', 'fixed_term'] as const}
              />
              {berth.tenureType === 'fixed_term' && (
                <>
                  <SpecRow label="Years" value={berth.tenureYears} />
                  <SpecRow label="Start Date" value={berth.tenureStartDate} />
                  <SpecRow label="End Date" value={berth.tenureEndDate} />
                </>
              )}
              <EditableSpec
                label={`Price (${berth.priceCurrency || 'USD'})`}
                value={berth.price}
                field="price"
                patch={patch}
                numeric
              />
            </CardContent>
          </Card>

          <Card>
            <CardHeader className="pb-3">
              <CardTitle className="text-sm font-medium">Tags</CardTitle>
            </CardHeader>
            <CardContent className="pt-0">
              <InlineTagEditor
                endpoint={`/api/v1/berths/${berth.id}/tags`}
                currentTags={berth.tags}
                invalidateKey={['berths', berth.id]}
              />
            </CardContent>
          </Card>
        </div>
      </div>
    </div>
  );
}

export function buildBerthTabs(berth: BerthData): DetailTab[] {
  return [
    {
      id: 'overview',
      label: 'Overview',
      content: <OverviewTab berth={berth} />,
    },
    {
      id: 'interests',
      label: 'Interests',
      content: <BerthInterestsTab berthId={berth.id} />,
    },
    {
      id: 'reservations',
      label: 'Reservations',
      content: <BerthReservationsTab berthId={berth.id} />,
    },
    {
      id: 'spec',
      label: 'Spec',
      content: <BerthDocumentsTab berthId={berth.id} />,
    },
    {
      id: 'deal-documents',
      label: 'Deal Documents',
      content: <BerthDealDocumentsTab berthId={berth.id} />,
    },
    // Waiting List + Maintenance Log tabs were stubs ("coming soon")
    // visible to every operator. Hidden here until the
    // berth_waiting_list / berth_maintenance_log feature surfaces ship.
    {
      id: 'activity',
      label: 'Activity',
      content: (
        <EntityActivityFeed
          endpoint={`/api/v1/berths/${berth.id}/activity`}
          emptyText="No activity recorded for this berth yet."
        />
      ),
    },
  ];
}
