/* eslint-disable react-refresh/only-export-components -- column definition files intentionally mix component helpers with factory exports */
import { ColumnDef } from '@tanstack/react-table';
import { ArrowDown, ArrowUp, ArrowUpDown, CheckCircle2, XCircle } from 'lucide-react';

import { Link } from '@inertiajs/react';

import { Badge } from '@/Components/ui/badge';
import { Checkbox } from '@/Components/ui/checkbox';
import { RelativeTime } from '@/Components/ui/relative-time';
import type { AdminSiteRow } from '@/types/admin';

function HealthBadge({ score, status }: { score: string | null; status: string }) {
  if (score === null) {
    return (
      <Badge variant="outline" className="text-muted-foreground">
        Unknown
      </Badge>
    );
  }
  const numScore = parseFloat(score);
  if (numScore < 30) {
    return (
      <Badge variant="destructive">
        {numScore.toFixed(0)} - {status}
      </Badge>
    );
  }
  if (numScore < 60) {
    return (
      <Badge variant="warning">
        {numScore.toFixed(0)} - {status}
      </Badge>
    );
  }
  return (
    <Badge variant="success">
      {numScore.toFixed(0)} - {status}
    </Badge>
  );
}

/** Sortable column header that integrates with TanStack sorting state. */
function SortableHeader({
  label,
  column,
}: {
  label: string;
  column: {
    getIsSorted: () => false | 'asc' | 'desc';
    toggleSorting: (desc?: boolean) => void;
  };
}) {
  const sorted = column.getIsSorted();
  return (
    <button
      type="button"
      className="inline-flex items-center gap-1 cursor-pointer hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 select-none"
      onClick={() => column.toggleSorting(sorted === 'asc')}
      aria-sort={sorted === 'asc' ? 'ascending' : sorted === 'desc' ? 'descending' : 'none'}
    >
      {label}
      {sorted === 'asc' ? (
        <ArrowUp className="size-3" aria-hidden="true" />
      ) : sorted === 'desc' ? (
        <ArrowDown className="size-3" aria-hidden="true" />
      ) : (
        <ArrowUpDown className="size-3 text-muted-foreground" aria-hidden="true" />
      )}
    </button>
  );
}

interface AdminSitesColumnsOptions {
  selectedIds: Set<number>;
  selectableIds: Set<number>;
  allSelectableSelected: boolean;
  onToggle: (id: number) => void;
  onToggleAll: () => void;
}

/**
 * Column definitions for the Admin/Sites DataTable.
 *
 * Accepts selection state as parameters so this module stays pure (no
 * closed-over React state) while the Index page controls selection.
 * Sorting is server-side (manualPagination=true); the `onSortingChange`
 * in Index.tsx drives `handleSort` from `useAdminFilters`.
 */
export function adminSitesColumns({
  selectedIds,
  selectableIds,
  allSelectableSelected,
  onToggle,
  onToggleAll,
}: AdminSitesColumnsOptions): ColumnDef<AdminSiteRow>[] {
  return [
    {
      id: 'select',
      enableSorting: false,
      enableHiding: false,
      header: () => (
        <Checkbox
          checked={allSelectableSelected && selectableIds.size > 0}
          onCheckedChange={onToggleAll}
          aria-label="Select all sites"
          disabled={selectableIds.size === 0}
        />
      ),
      cell: ({ row }) => {
        const site = row.original;
        const isSelectable = !site.deleted_at;
        return isSelectable ? (
          <Checkbox
            checked={selectedIds.has(site.id)}
            onCheckedChange={() => onToggle(site.id)}
            aria-label={`Select ${site.name}`}
          />
        ) : (
          <Checkbox disabled aria-label={`Cannot select ${site.name}`} />
        );
      },
    },
    {
      accessorKey: 'name',
      header: 'Site',
      enableSorting: false,
      cell: ({ row }) => {
        const site = row.original;
        return (
          <div>
            <Link
              href={route('admin.sites.show', site.id)}
              className="font-medium hover:underline"
            >
              {site.name}
            </Link>
            <div className="text-xs text-muted-foreground">{site.domain}</div>
            {site.deleted_at && (
              <Badge variant="destructive" className="mt-1">
                Deleted
              </Badge>
            )}
          </div>
        );
      },
    },
    {
      id: 'user',
      accessorFn: (row) => row.user_name,
      header: 'User',
      enableSorting: false,
      cell: ({ row }) => {
        const site = row.original;
        return (
          <div className="max-w-40" title={`${site.user_name} (${site.user_email})`}>
            <Link
              href={`/admin/users/${site.user_id}`}
              className="font-medium text-sm hover:underline truncate block"
            >
              {site.user_name}
            </Link>
            <div className="text-xs text-muted-foreground truncate">{site.user_email}</div>
          </div>
        );
      },
    },
    {
      accessorKey: 'health_score',
      enableSorting: true,
      header: ({ column }) => <SortableHeader label="Health" column={column} />,
      cell: ({ row }) => (
        <HealthBadge score={row.original.health_score} status={row.original.health_status} />
      ),
    },
    {
      accessorKey: 'last_analysis_at',
      enableSorting: true,
      header: ({ column }) => <SortableHeader label="Last Analysis" column={column} />,
      cell: ({ row }) => (
        <span className="text-sm text-muted-foreground">
          <RelativeTime value={row.original.last_analysis_at} />
        </span>
      ),
    },
    {
      accessorKey: 'has_gsc',
      header: 'GSC',
      enableSorting: false,
      cell: ({ row }) =>
        row.original.has_gsc ? (
          <CheckCircle2 className="size-4 text-success" aria-label="Connected" />
        ) : (
          <XCircle className="size-4 text-muted-foreground" aria-label="Not connected" />
        ),
    },
    {
      accessorKey: 'has_wp',
      header: 'WP',
      enableSorting: false,
      cell: ({ row }) =>
        row.original.has_wp ? (
          <CheckCircle2 className="size-4 text-success" aria-label="Connected" />
        ) : (
          <XCircle className="size-4 text-muted-foreground" aria-label="Not connected" />
        ),
    },
    {
      accessorKey: 'created_at',
      enableSorting: true,
      header: ({ column }) => <SortableHeader label="Created" column={column} />,
      cell: ({ row }) => (
        <span className="text-sm text-muted-foreground">
          <RelativeTime value={row.original.created_at} />
        </span>
      ),
    },
  ];
}
