'use client';

import { useRouter, useParams } from 'next/navigation';
import { Anchor } from 'lucide-react';

import { DataTable } from '@/components/shared/data-table';
import { FilterBar } from '@/components/shared/filter-bar';
import { PageHeader } from '@/components/shared/page-header';
import { SavedViewsDropdown } from '@/components/shared/saved-views-dropdown';
import { ColumnPicker } from '@/components/shared/column-picker';
import { Input } from '@/components/ui/input';
import { EmptyState } from '@/components/shared/empty-state';
import { usePaginatedQuery } from '@/hooks/use-paginated-query';
import { useRealtimeInvalidation } from '@/hooks/use-realtime-invalidation';
import { useTablePreferences } from '@/hooks/use-table-preferences';
import { BerthCard } from './berth-card';
import {
  berthColumns,
  BERTH_COLUMN_OPTIONS,
  BERTH_DEFAULT_HIDDEN,
  type BerthRow,
} from './berth-columns';
import { berthFilterDefinitions } from './berth-filters';
import { mooringLetterTone } from './mooring-letter-tone';

export function BerthList() {
  const router = useRouter();
  const params = useParams<{ portSlug: string }>();

  const {
    data,
    pagination,
    isLoading,
    sort,
    setSort,
    filters,
    setFilter,
    clearFilters,
    setPage,
    setPageSize,
  } = usePaginatedQuery<BerthRow>({
    queryKey: ['berths'],
    endpoint: '/api/v1/berths',
    filterDefinitions: berthFilterDefinitions,
  });

  useRealtimeInvalidation({
    'berth:updated': [['berths']],
    'berth:statusChanged': [['berths']],
  });

  // Persisted column visibility — same pattern as ClientList / InterestList.
  const { hidden, setHidden } = useTablePreferences('berths', BERTH_DEFAULT_HIDDEN);
  const columnVisibility = Object.fromEntries(hidden.map((id) => [id, false]));

  return (
    <div className="space-y-6">
      <PageHeader
        title="Berths"
        description="View and manage berth allocations"
        variant="gradient"
        // No "New" button - berths are import-only
      />

      <div className="flex items-center gap-2 flex-wrap">
        <FilterBar
          // Search is hoisted out of the popover into the inline input
          // below — keeps the daily "find by mooring/area" lookup one
          // tap away instead of buried behind the Filters dropdown.
          filters={berthFilterDefinitions.filter((d) => d.key !== 'search')}
          values={filters}
          onChange={setFilter}
          onClear={clearFilters}
        />
        <Input
          type="search"
          inputMode="search"
          placeholder="Search mooring or area…"
          aria-label="Search berths"
          value={(filters.search as string | undefined) ?? ''}
          onChange={(e) => setFilter('search', e.target.value || undefined)}
          // flex-1 + min-w-0 lets the input expand to fill the row's
          // remaining width on mobile (where space is at a premium).
          // sm:max-w-xs caps it at 320px on desktop so it doesn't grow
          // absurdly wide on a 2k monitor.
          className="h-8 min-w-0 flex-1 sm:max-w-xs"
        />
        <div className="ml-auto flex items-center gap-2">
          <SavedViewsDropdown
            entityType="berths"
            onApplyView={(savedFilters, _savedSort) => {
              clearFilters();
              Object.entries(savedFilters).forEach(([key, value]) => setFilter(key, value));
            }}
          />
          <ColumnPicker columns={BERTH_COLUMN_OPTIONS} hidden={hidden} onChange={setHidden} />
        </div>
      </div>

      <DataTable<BerthRow>
        columns={berthColumns}
        columnVisibility={columnVisibility}
        data={data}
        isLoading={isLoading}
        pagination={{
          page: pagination.page,
          pageSize: pagination.pageSize,
          total: pagination.total,
          totalPages: pagination.totalPages,
        }}
        onPaginationChange={(page, pageSize) => {
          setPage(page);
          setPageSize(pageSize);
        }}
        sort={sort}
        onSortChange={setSort}
        getRowId={(row) => row.id}
        onRowClick={(row) => router.push(`/${params.portSlug}/berths/${row.id}`)}
        getRowClassName={(row) => mooringLetterTone(row.mooringNumber)}
        cardRender={(row) => <BerthCard berth={row.original} />}
        // Group adjacent cards by dock letter (area) on mobile — adds a
        // dim divider + uppercased label above the first card of each
        // group. Data is already sorted by mooringNumber (A1, A2, …, B1,
        // B2, …) so consecutive rows naturally share dock letters.
        mobileGroupBy={(row) => row.area ?? 'Unassigned'}
        emptyState={
          // Distinguish "no data at all" (fresh port, run the importer)
          // from "no rows after filtering" (adjust filters). The original
          // copy implied data existed but was hidden, which misled fresh-
          // port admins for whom there is literally nothing yet.
          Object.values(filters).every((v) => v === undefined || v === '') ? (
            <EmptyState
              icon={Anchor}
              title="No berths yet"
              description="Berths are imported from external sources. Run the importer once the source data is ready: pnpm tsx scripts/import-berths-from-nocodb.ts --apply --port-slug <slug>."
            />
          ) : (
            <EmptyState
              icon={Anchor}
              title="No berths match these filters"
              description="Adjust your filters or clear them to see every berth."
            />
          )
        }
      />
    </div>
  );
}
