import { useCallback, useContext, useState } from 'react'

import { DataGrid, GridCellParams, GridRowId, GridRowModel, GridRowSelectionModel, useGridApiRef } from '@mui/x-data-grid';
import { Box } from '@mui/material';
import { EditorProperties, EditorProperty } from '@iplusplus/y-model';

import { EditorContext } from "../editor-context"
import {
  GridToolbarContainer,
} from '@mui/x-data-grid';
import { checkCanEdit, checkValidValue } from '../convention';





function translateNumberValue(properties: EditorProperties, newRow: GridRowModel, oldRow: GridRowModel) {
  const result = { ...newRow };
  properties.forEach(p => {
    const { isValid, value } = checkValidValue(p, result[p.name]);
    result[p.name] = isValid ? value : oldRow[p.name]
  })
  return result
}

function createProcessRowUpdate(properties: EditorProperties, onRowUpdate: (newData: Record<string, unknown>) => void) {
  return (newRow: GridRowModel, oldRow: GridRowModel) => {
    const newRowCopy = translateNumberValue(properties, newRow, oldRow)
    return new Promise<GridRowModel>(resolve => {  
      resolve(newRowCopy)
      Promise.resolve().then(()=> onRowUpdate(newRowCopy))
      //throw new Error("it's ok")
    })
  }
}


// function createProcessRowUpdate(properties: EditorProperties, onRowUpdate: (newData: Record<string, unknown>) => void) {
//   return async (newRow: GridRowModel, oldRow: GridRowModel) => {

//     const newRowCopy = translateNumberValue(properties, newRow, oldRow)
//     onRowUpdate(newRowCopy)
//     return Promise.resolve(newRowCopy);
//     //throw new Error("it's ok")
//   }
// }


function CustomToolbar2({ extraIcons }: { extraIcons: JSX.Element[] }) {

  return (
    <GridToolbarContainer>

      {extraIcons}

    </GridToolbarContainer>
  );
}


//export type EditorProperties = ReadonlyArray<EditorProperty>;
type EditorProperty2 = EditorProperty & {
  flex?: number
}
type EditorProperties2 = ReadonlyArray<EditorProperty2>;

export function ObjectArrayEditor3({ properties, data, onValueChange, extraIcons, onSelectedChanged, selectedIds }: {
  properties: EditorProperties2,
  data: Record<string, any>[],
  onValueChange: (id: GridRowId, filedName: string, value: any) => void,
  extraIcons?: JSX.Element[],
  onSelectedChanged: (ids: readonly GridRowId[]) => void
  selectedIds: GridRowId[]
}) {
  // const [lastEditField, setLastEditField] = useState("");
  const apiRef = useGridApiRef();
  const context = useContext(EditorContext)

  const [lastEditField, setLastEditField] = useState("")
  const [lastEditId, setLastEditId] = useState<GridRowId>()
  // const onCellEditStop = useCallback((params: GridCellParams)=>{
  //   const { id, field, value } = params;
  //   onValueChange(id,field,value);
  // },[onValueChange])

  const processRowUpdate = createProcessRowUpdate(properties, newRow => {
    if (!lastEditField) return
    const newValue = newRow[lastEditField]
    const id = newRow.id as GridRowId;
    onValueChange(newRow.id as GridRowId, lastEditField, newValue)
    apiRef.current.stopCellEditMode({
      id, field: lastEditField
    })
  })


  const columns = properties.map(p => ({
    field: p.name,
    headerName: p.title,
    editable: checkCanEdit(p),
    //type: 'string',
    sortable: false,
    renderEditCell: context.editCellRenderBuilder(p),
    renderCell: context.cellRenderBuilder(p),
    disableColumnMenu: true,
    flex: p.flex || p.valueType.getAttach("flex") || 1
  }))



  const solt = (extraIcons) ? {
    toolbar: () => <CustomToolbar2 extraIcons={extraIcons} />
  } : undefined;
  return (
    <Box sx={{ height: "100%", width: '100%' }}>
      <DataGrid
        rows={data}
        columns={columns}
        hideFooter={data.length <= 100}
        apiRef={apiRef}
        checkboxSelection={true}
        processRowUpdate={processRowUpdate}
        onCellEditStop={p => {
          setLastEditField(p.field)
          setLastEditId(p.id)
        }}
        disableRowSelectionOnClick
        density="compact"
        showCellVerticalBorder
        slots={solt}
        disableDensitySelector
        disableColumnFilter={true}
        pageSizeOptions={[25, 50, 99, 100]}
        onRowSelectionModelChange={(newRowSelectionModel: GridRowSelectionModel) => {
          onSelectedChanged(newRowSelectionModel)
        }}
        rowSelectionModel={selectedIds}
      />


    </Box>
  )
}
