import { Cell } from '@tanstack/react-table';
import { EditableTableProps, SwitchMetaData } from '../types';
import { Switch } from '../../switch';
import { useEffect, useRef, useState } from 'react';
import { useTableContext } from '../table-context/table-context-provider';
import { useFocusHandler } from '../focus-handler/focus-handler-provider';
import { CellTypes } from '../constants';
import { replaceSpacesWithHyphens } from '../../_utils/utils';

interface EditableSwitchProps<TData> {
  cell: Cell<TData, unknown>;
  isCellDisabled: EditableTableProps<TData>['isCellDisabled'];
}

export default function EditableSwitch<TData>(props: EditableSwitchProps<TData>) {
  const [value, setValue] = useState(false);

  const cellRef = useRef<HTMLDivElement>(null);
  const switchRef = useRef<HTMLDivElement>(null);

  const { updateData, tableRef, tableName, doesRowHeaderExist } = useTableContext<TData>(
    props.cell,
  );
  const { isCurrentCellFocused, focusCurrentCell } = useFocusHandler({
    cellType: CellTypes.dataCell,
    columnIndex: props.cell.column.getIndex(),
    groupId: null,
    rowId: props.cell.row.id,
    rowIndex: props.cell.row.index,
  });

  const metaData = props.cell.column.columnDef.meta as SwitchMetaData<TData>;

  useEffect(() => {
    setValue(props.cell.getValue() as boolean);
  }, []);

  useEffect(() => {
    if (isCurrentCellFocused && tableRef.current?.contains(document.activeElement)) {
      switchRef.current?.focus();
    }
  }, [isCurrentCellFocused]);

  return (
    <div ref={cellRef} className="td-content relative rounded px-2 py-0.5">
      <Switch
        ref={switchRef}
        isToggled={value as boolean}
        onChange={(newValue) => {
          setValue(newValue);
          updateData(newValue);
          focusCurrentCell();
        }}
        tabIndex={isCurrentCellFocused ? 0 : -1}
        isDisabled={
          props.isCellDisabled?.(props.cell.row.original, props.cell.column.columnDef.id) || false
        }
        {...(metaData.label
          ? {
              label: metaData.label(props.cell.row.original),
              labelId: `${replaceSpacesWithHyphens(tableName)}-${props.cell.column.getIndex()}-${props.cell.row.id}`,
            }
          : {
              ariaLabelledby: `${doesRowHeaderExist ? props.cell.row.id : ''} ${replaceSpacesWithHyphens(tableName)}-${props.cell.column.getIndex()}`,
            })}
        activeText={metaData.activeText ?? 'Enabled'}
        inactiveText={metaData.inactiveText ?? 'Disabled'}
        classNames={{ label: 'sr-only' }}
      />
    </div>
  );
}
