'use client';

import { useEffect } from 'react';
import Link from 'next/link';
import { useRouter, useParams } from 'next/navigation';
import { Anchor, Plus, Rows3, Rows4 } from 'lucide-react';

import { useMobileChrome } from '@/components/layout/mobile/mobile-layout-provider';
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 { ExportListPdfButton } from '@/components/reports/export-list-pdf-button';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { EmptyState } from '@/components/shared/empty-state';
import { usePaginatedQuery } from '@/hooks/use-paginated-query';
import { usePermissions } from '@/hooks/use-permissions';
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 }>();
  // M-U14: surface the page title in the mobile topbar.
  const { setChrome } = useMobileChrome();
  useEffect(() => {
    setChrome({ title: 'Berths', showBackButton: false });
    return () => setChrome({ title: null, showBackButton: false });
  }, [setChrome]);
  // F13: bulk-add wizard had no UI entry point. Gate the CTA on
  // `berths.import` (the existing permission used for adding berths)
  // so non-admins don't see a button that 403s on click.
  const { can } = usePermissions();
  const canBulkAdd = can('berths', 'import');

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

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

  // Persisted column visibility + row density — same pattern as
  // ClientList / InterestList; density is new and falls back to
  // 'comfortable' for users who haven't picked yet.
  const { hidden, setHidden, density, setDensity } = 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
      />

      {/* Toolbar — two halves separated by `justify-between` so the
          Columns + Saved-views actions stay pinned to the right edge of
          the row at every width. The previous `ml-auto` trick didn't
          survive flex-wrap on intermediate widths — the actions ended
          up centered. */}
      <div className="flex items-center gap-2 flex-wrap justify-between">
        <div className="flex items-center gap-2 flex-wrap min-w-0 flex-1">
          <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)}
            className="h-8 min-w-0 flex-1 sm:max-w-xs"
          />
        </div>
        <div className="flex items-center gap-2 ml-auto">
          <SavedViewsDropdown
            entityType="berths"
            onApplyView={(savedFilters, _savedSort) => {
              setAllFilters(savedFilters);
            }}
          />
          <Button
            type="button"
            size="sm"
            variant="outline"
            onClick={() => setDensity(density === 'compact' ? 'comfortable' : 'compact')}
            aria-label={
              density === 'compact'
                ? 'Switch to comfortable row spacing'
                : 'Switch to compact row spacing'
            }
            title={density === 'compact' ? 'Comfortable rows' : 'Compact rows'}
          >
            {density === 'compact' ? (
              <Rows3 className="h-4 w-4" aria-hidden />
            ) : (
              <Rows4 className="h-4 w-4" aria-hidden />
            )}
          </Button>
          <ColumnPicker columns={BERTH_COLUMN_OPTIONS} hidden={hidden} onChange={setHidden} />
          <ExportListPdfButton kind="berths" />
          {canBulkAdd && (
            <Button asChild size="sm" variant="default">
              <Link href={`/${params.portSlug}/admin/berths/bulk-add`}>
                <Plus className="h-4 w-4" />
                <span className="hidden sm:inline">Bulk add</span>
              </Link>
            </Button>
          )}
        </div>
      </div>

      <DataTable<BerthRow>
        columns={berthColumns}
        columnVisibility={columnVisibility}
        density={density}
        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>
  );
}
