import { useCallback, useMemo, useState } from 'react';

import { useGridPopoverContext } from '../../contexts/GridPopoverContext';
import { TextInputFormatted } from '../../lui/TextInputFormatted';
import { bearingNumberParser, bearingStringValidator } from '../../utils/bearing';
import { GridBaseRow } from '../Grid';
import { CellEditorCommon } from '../GridCell';
import { useGridPopoverHook } from '../GridPopoverHook';

export interface GridFormEditBearingProps<TData extends GridBaseRow> extends CellEditorCommon {
  formatValue?: (value: any) => string;
  placeHolder?: string;
  range?: (value: number | null) => string | null;
  onSave?: (props: { selectedRows: TData[]; value: number | null }) => Promise<boolean>;
}

export const GridFormEditBearing = <TData extends GridBaseRow>(props: GridFormEditBearingProps<TData>) => {
  const { field, value: initialValue } = useGridPopoverContext<TData>();

  // This clears out any scientific precision
  const defaultValue = useMemo(
    () => (initialValue == null ? '' : parseFloat(parseFloat(initialValue).toFixed(10)).toString()),
    [initialValue],
  );

  const [value, setValue] = useState<string>(defaultValue);

  const invalid = useCallback(() => bearingStringValidator(value, props.range), [props.range, value]);

  const save = useCallback(
    async (selectedRows: TData[]): Promise<boolean> => {
      const parsedValue = bearingNumberParser(value);
      // Value didn't change so don't save just cancel
      if (parsedValue === bearingNumberParser(defaultValue)) {
        return true;
      }

      if (props.onSave) {
        return await props.onSave({ selectedRows, value: parsedValue });
      } else {
        if (field == null) {
          console.error('field is not defined in ColDef');
        } else {
          selectedRows.forEach((row) => {
            row[field] = parsedValue as any;
          });
        }
      }
      return true;
    },
    [defaultValue, field, props, value],
  );
  const { popoverWrapper } = useGridPopoverHook({
    className: props.className,
    invalid,
    save,
  });

  return popoverWrapper(
    <div className={'GridFormEditBearing-input'}>
      <TextInputFormatted
        value={defaultValue}
        onChange={(e) => {
          setValue(e.target.value.trim());
        }}
        autoFocus={true}
        placeholder={props.placeHolder}
        formatted={
          bearingStringValidator(value, props.range) || !props.formatValue
            ? '?'
            : props.formatValue(bearingNumberParser(value))
        }
        error={bearingStringValidator(value, props.range)}
        helpText={'Press enter or tab to save'}
      />
    </div>,
  );
};
