import { generatePrefixId } from "@investtal/toolkit"
import type { ColumnDef } from "@tanstack/react-table"
import type React from "react"
import { RowActionsCell } from "../components/RowActionsCell"
import type {
  DataTableColumn,
  DataTableRowAction,
  DataTableRowItemAction,
} from "../DataTable.types"
import { TableCheckbox } from "../Table"
import {
  COLUMN_IDS,
  COLUMN_WIDTHS,
  ID_FIELDS,
  RANDOM_ID_PREFIX,
  STICKY_STYLES,
} from "./tableUtils.const"

function findRowId(row: any): string | undefined {
  for (const field of ID_FIELDS) {
    if (row[field] !== undefined) {
      return String(row[field])
    }
  }
  return undefined
}

function createWidthStyle(width: number | string | undefined): React.CSSProperties {
  if (!width) return {}

  const widthValue = typeof width === "number" ? `${width}px` : width
  return {
    width: widthValue,
    minWidth: widthValue,
  }
}

function createStickyStyle(baseStyle: React.CSSProperties): React.CSSProperties {
  return {
    ...baseStyle,
    position: STICKY_STYLES.POSITION,
    right: STICKY_STYLES.RIGHT,
    zIndex: STICKY_STYLES.Z_INDEX,
    backgroundColor: STICKY_STYLES.BACKGROUND_COLOR,
    filter: STICKY_STYLES.FILTER,
    padding: STICKY_STYLES.PADDING,
  }
}

function createSelectColumn<TData, TValue>(): ColumnDef<TData, TValue> {
  return {
    id: COLUMN_IDS.SELECT,
    header: ({ table }) => (
      <TableCheckbox
        checked={table.getIsAllPageRowsSelected()}
        indeterminate={table.getIsSomePageRowsSelected() && !table.getIsAllPageRowsSelected()}
        onCheckedChange={value => table.toggleAllPageRowsSelected(!!value)}
        aria-label="Select all"
      />
    ),
    cell: ({ row }) => (
      <TableCheckbox
        checked={row.getIsSelected()}
        indeterminate={row.getIsSomeSelected() && !row.getIsSelected()}
        onCheckedChange={value => row.toggleSelected(!!value)}
        aria-label="Select row"
      />
    ),
    enableSorting: false,
    enableHiding: false,
    meta: {
      width: COLUMN_WIDTHS.SELECT,
    },
  }
}

function createActionsColumn<TData, TValue>(
  rowActions: DataTableRowItemAction<TData>[],
): ColumnDef<TData, TValue> {
  return {
    id: COLUMN_IDS.ACTIONS,
    header: "",
    cell: ({ row }) => <RowActionsCell row={row} actions={rowActions} />,
    enableSorting: false,
    enableHiding: false,
    meta: {
      sticky: "right",
      width: COLUMN_WIDTHS.ACTIONS,
    },
  }
}

function processColumns<TData, TValue>(
  columns: DataTableColumn<TData, TValue>[],
): DataTableColumn<TData, TValue>[] {
  return columns.map(column => ({
    ...column,
    enableSorting: column.enableSorting ?? false,
    enableColumnFilter: column.enableColumnFilter ?? true, // Enable filtering by default
  }))
}

// Main exported functions
export function createAllColumns<TData extends Record<string, any>, TValue>(
  columns: DataTableColumn<TData, TValue>[],
  selectedRowActions: DataTableRowAction<TData>[],
  rowActions: DataTableRowItemAction<TData>[],
): ColumnDef<TData, TValue>[] {
  const processedColumns = processColumns(columns)

  // Build base columns with optional select column
  const baseColumns =
    selectedRowActions.length > 0
      ? [createSelectColumn<TData, TValue>(), ...processedColumns]
      : processedColumns

  // Add actions column if row actions are provided
  if (rowActions.length > 0) {
    const actionsColumn = createActionsColumn<TData, TValue>(rowActions)
    return [...baseColumns, actionsColumn]
  }

  return baseColumns
}

export function getRowId(row: any): string {
  const id = findRowId(row)
  return id ?? generatePrefixId(RANDOM_ID_PREFIX)
}

export function getWidthStyle(column: any): React.CSSProperties {
  const isSelectColumn = column.id === COLUMN_IDS.SELECT
  const isActionsColumn = column.id === COLUMN_IDS.ACTIONS

  // Handle select column
  if (isSelectColumn) {
    return createWidthStyle(COLUMN_WIDTHS.SELECT)
  }

  // Handle actions column
  if (isActionsColumn) {
    const width = column.columnDef.meta?.width ?? COLUMN_WIDTHS.ACTIONS
    const baseStyle = createWidthStyle(width)
    return createStickyStyle(baseStyle)
  }

  // Handle data columns
  const columnDef = column.columnDef as DataTableColumn<any, any>
  const width = columnDef?.width
  return createWidthStyle(width)
}
