import '../../styles/GridTheme.scss';
import '../../styles/index.scss';
import '@linzjs/lui/dist/scss/base.scss';
import '@linzjs/lui/dist/fonts';

import { Meta, StoryFn } from '@storybook/react-vite';
import { useMemo, useState } from 'react';

import {
  ColDefT,
  Grid,
  GridButton,
  GridCell,
  GridContextProvider,
  GridEditBoolean,
  GridPopoverEditDropDown,
  GridUpdatingContextProvider,
  primitiveToSelectOption,
  wait,
} from '../..';
import { expect, userEvent, waitFor } from 'storybook/test';

import { waitForGridReady } from '../../utils/__tests__/storybookTestUtil';
import { IFormTestRow } from './FormTest';

export default {
  title: 'Components / Grids',
  component: Grid,
  decorators: [
    (Story) => (
      <div style={{ width: 1024, height: 400 }}>
        <GridUpdatingContextProvider>
          <GridContextProvider>
            <Story />
          </GridContextProvider>
        </GridUpdatingContextProvider>
      </div>
    ),
  ],
} as Meta<typeof Grid>;

const GridPopoutEditBooleanTemplate: StoryFn<typeof Grid> = () => {
  const [rowData, setRowData] = useState([
    { id: 1000, name: 'IS IS DP12345', nameType: 'IS', numba: 'IX', plan: 'DP 12345', bold: true },
    { id: 1001, name: 'PEG V SD523', nameType: 'PEG', numba: 'V', plan: 'SD 523', bold: false },
  ] as IFormTestRow[]);

  const columnDefs: ColDefT<IFormTestRow>[] = useMemo(
    () => [
      GridCell({
        field: 'id',
        headerName: 'Id',
      }),
      GridButton(
        {
          colId: 'button',
          headerName: 'Button',
        },
        {
          visible: ({ data }) => !!(data.id & 1),
          onClick: ({ selectedRowIds }) => {
            alert('click ' + String(selectedRowIds));
          },
        },
      ),
      GridEditBoolean(
        {
          field: 'bold',
        },
        {
          onClick: async ({ selectedRowIds, checked }) => {
            await wait(1000);
            setRowData((rowData) => {
              // eslint-disable-next-line no-console
              console.log('onchange', selectedRowIds, checked);
              return rowData.map((row) => (selectedRowIds.includes(row.id) ? { ...row, bold: checked } : row));
            });
            return true;
          },
        },
      ),
      GridPopoverEditDropDown(
        {
          field: 'name',
          headerName: 'Name',
        },
        {
          multiEdit: false,
          editorParams: {
            filtered: 'local',
            filterPlaceholder: 'Filter this',
            options: [null, 'Architect', 'Developer', 'Product Owner', 'Scrum Master', 'Tester'].map(
              primitiveToSelectOption,
            ),
          },
        },
      ),
      GridEditBoolean(
        {
          colId: 'bold2',
          field: 'bold',
        },
        {
          onClick: async ({ selectedRowIds, checked }) => {
            setRowData((rowData) => {
              // eslint-disable-next-line no-console
              console.log('onchange', selectedRowIds, checked);
              return rowData.map((row) => (selectedRowIds.includes(row.id) ? { ...row, bold: checked } : row));
            });
            return true;
          },
        },
      ),
    ],
    [],
  );

  return (
    <>
      <Grid
        theme={'ag-theme-step-view-list-default'}
        columnDefs={columnDefs}
        rowData={rowData}
        selectable={false}
        singleClickEdit={true}
        rowSelection="single"
        domLayout={'autoHeight'}
      />
    </>
  );
};

export const _EditBoolean = GridPopoutEditBooleanTemplate.bind({});
_EditBoolean.play = waitForGridReady;

export const _EditBooleanRetainsFocusAfterToggle = GridPopoutEditBooleanTemplate.bind({});
_EditBooleanRetainsFocusAfterToggle.play = async (context) => {
  await waitForGridReady(context);
  const { canvasElement } = context;

  // Use bold2 (no async delay) so the redraw happens immediately
  const getBoolInput = () =>
    canvasElement.querySelector('.ag-cell[col-id="bold2"] input.ag-checkbox-input') as HTMLElement;

  await userEvent.click(canvasElement.querySelector('.ag-cell[col-id="bold2"]') as HTMLElement);
  await waitFor(() => expect(getBoolInput()).toHaveFocus(), { timeout: 500 });

  // Space toggles the checkbox, which triggers redrawRows — ag-grid moves focus from the
  // input to the cell div (role="gridcell"). The shared interval should detect this and restore focus.
  await userEvent.keyboard(' ');

  // Re-query the input each retry since redraw replaces the DOM node
  await waitFor(() => expect(getBoolInput()).toHaveFocus(), { timeout: 500 });
};
