import React from 'react';
import type { Field, FieldsSource, PatternsFieldType } from '@wix/bex-core';
import type { DataTableColumnAlign } from '@wix/design-system/dist/types/Table/DataTable';
import { Column } from '../model';
import { FieldCell } from '../components/FieldCell/FieldCell';
import { toFieldType } from '../utils/fieldTypePrefixIcons';

/**
 * Column width and alignment per field type. These match the widths the table
 * used before this builder existed, so columns keep the same layout. Types not
 * listed fall back to DEFAULT_LAYOUT.
 */
const LAYOUT_BY_TYPE: Partial<
  Record<PatternsFieldType, { width: string; align: DataTableColumnAlign }>
> = {
  SHORT_TEXT: { width: '150px', align: 'start' },
  LONG_TEXT: { width: '250px', align: 'start' },
  URL: { width: '250px', align: 'start' },
  DATE: { width: '150px', align: 'center' },
  DATETIME: { width: '200px', align: 'center' },
  NUMBER: { width: '100px', align: 'center' },
  BOOLEAN: { width: '100px', align: 'center' },
  ARRAY: { width: '150px', align: 'start' },
  DOCUMENT: { width: '180px', align: 'start' },
};

const DEFAULT_LAYOUT = {
  width: '200px',
  align: 'start' as DataTableColumnAlign,
};

export interface ColumnOverridesContext {
  /** True on the first push for a source, when every column starts hidden. */
  firstBuild: boolean;
}

/**
 * Builds table columns from a FieldsSource. Each column renders its value with
 * FieldCell by type. A source can replace any column property — including the
 * render function for media types — through columnOverrides.
 */
export function buildFieldColumns(
  source: FieldsSource,
  columnOverrides?: (
    field: Field,
    ctx: ColumnOverridesContext,
  ) => Partial<Column>,
  ctx: ColumnOverridesContext = { firstBuild: false },
): Column[] {
  // align and dataHook aren't on Column but the WDS table reads them, so the
  // callback is left unannotated — annotating the literal as Column would reject
  // them as excess properties. The function still returns Column[].
  return source.fields.map((field) => {
    const id = source.columnIdForField(field);
    const layout = LAYOUT_BY_TYPE[field.type] ?? DEFAULT_LAYOUT;
    return {
      id,
      field,
      dataHook: id,
      name: field.displayName,
      title: field.displayName,
      hideable: true,
      sortable: field.capabilities?.sortable ?? false,
      isPii: field.isPii,
      isSystem: field.isSystem,
      isPrimary: field.isPrimary,
      fieldType: toFieldType(field.type),
      width: layout.width,
      align: layout.align,
      render: (row, rowNum) => (
        <FieldCell
          type={field.type}
          value={source.getCellValue(row, field)}
          fieldId={`${id}-${rowNum}`}
        />
      ),
      ...columnOverrides?.(field, ctx),
    };
  });
}
