// import React, { useRef, useState, useEffect } from 'react'
// import { HotTable } from '@handsontable/react'
// import 'handsontable/dist/handsontable.full.min.css'
// import Handsontable from 'handsontable'
// import {
//   registerControl,
//   RegisterControlProps,
//   RegisteredControlProperties,
// } from '../hoc/registerControl'
// import { CustomContentRenderer } from './utils/customButtonRenderer'
// import { hyperformulaInstance, sheetId } from './utils/hyperformulaConfig'
// import { reformatDate, reformatCurrency } from './utils/formatters'
// import { SpreadsheetProperties } from '@components/features/FormBuilder/FormBuilderFieldProperties/Spreadsheet/types'
// import { registerAllCellTypes } from 'handsontable/cellTypes'
// import { registerAllPlugins } from 'handsontable/plugins'
// import { useFormBuilderWorksheetGrid } from '../../hooks/useFormBuilderWorksheetGrid'
// import { createSpreadsheetDefaultValue } from '../../FormBuilderFieldProperties/Spreadsheet/constants'
// import { useFormBuilder } from '../../hooks/useFormBuilder'
// import { useFormService } from '../../hooks/useFormService'

// registerAllCellTypes()
// registerAllPlugins()

// type Properties = RegisteredControlProperties &
//   SpreadsheetProperties & {
//     externalVariables?: {
//       [key: string]: {
//         propertyName?: string
//         defaultValue?: number
//       }
//     }
//   }

// const SpreadsheetControl: React.FC<RegisterControlProps<Properties>> = (
//   props
// ) => {
//   const hotTableRef = useRef<any>(null)
//   const containerRef = useRef<HTMLDivElement>(null)

//   const { rows = 1, columns = 1 } = props.properties || {}

//   const DEFAULT_COLUMN_WIDTH = 100
//   const DEFAULT_ROW_HEIGHT = 25

//   const defaultMeta = {
//     data: createSpreadsheetDefaultValue(rows, columns),
//     cellFormats: {} as { [key: string]: 'date' | 'currency' | undefined },
//     mergeCellsConfig: [],
//   }

//   const meta = props.properties?.meta || defaultMeta
//   const { actions: formBuilderWorksheetActions } = useFormBuilderWorksheetGrid()
//   const { actions, data: formBuilderData } = useFormBuilder()
//   const { watch } = useFormService()
//   const formData = watch()

//   if (!actions || !actions.getAllFields) {
//   }

//   const [data, setData] = useState(() => JSON.parse(JSON.stringify(meta.data)))
//   const [cellFormats, setCellFormats] = useState(meta.cellFormats)
//   const [mergeCellsConfig, setMergeCellsConfig] = useState(
//     meta.mergeCellsConfig
//   )

//   useEffect(() => {
//     if (formBuilderData?.fields) {
//       const existingExpressions = hyperformulaInstance.listNamedExpressions()

//       formBuilderData.fields.forEach((field) => {
//         const propertyName = field.properties?.propertyName
//         const defaultValue = Number(field.properties?.defaultValue || 0)

//         if (propertyName) {
//           if (!existingExpressions.includes(propertyName)) {
//             hyperformulaInstance.addNamedExpression(propertyName, defaultValue)
//           } else {
//             hyperformulaInstance.changeNamedExpression(
//               propertyName,
//               defaultValue
//             )
//           }
//         }
//       })

//       hyperformulaInstance.rebuildAndRecalculate()
//     }
//   }, [formBuilderData])

//   useEffect(() => {
//     if (props.externalVariables) {
//       const existingExpressions = new Set(
//         hyperformulaInstance.listNamedExpressions()
//       )

//       Object.entries(props.externalVariables).forEach(([key, property]) => {
//         const typedProperty = property as {
//           propertyName?: string
//           defaultValue?: number
//         }

//         const variableName = typedProperty.propertyName || key
//         const value = Number(typedProperty.defaultValue || 0)

//         if (!existingExpressions.has(variableName)) {
//           try {
//             hyperformulaInstance.addNamedExpression(
//               variableName,
//               value,
//               sheetId
//             )
//             existingExpressions.add(variableName)
//           } catch (error) {
//             console.error(
//               `Error adding named expression ${variableName}:`,
//               error
//             )
//           }
//         } else {
//           try {
//             hyperformulaInstance.changeNamedExpression(
//               variableName,
//               value,
//               sheetId
//             )
//           } catch (error) {
//             console.error(
//               `Error updating named expression ${variableName}:`,
//               error
//             )
//           }
//         }
//       })

//       try {
//         hyperformulaInstance.rebuildAndRecalculate()
//       } catch (error) {
//         console.error(
//           'Error during HyperFormula rebuild and recalculation:',
//           error
//         )
//       }
//     }
//   }, [props.externalVariables])

//   useEffect(() => {
//     if (formBuilderData) {
//       const existingExpressions = hyperformulaInstance.listNamedExpressions()

//       Object.entries(formBuilderData).forEach(([key, value]) => {
//         const numericValue = Number(value) || 0

//         if (!existingExpressions.includes(key)) {
//           hyperformulaInstance.addNamedExpression(key, numericValue)
//         } else {
//           hyperformulaInstance.changeNamedExpression(key, numericValue)
//         }
//       })

//       hyperformulaInstance.rebuildAndRecalculate()
//     }
//   }, [formBuilderData])

//   useEffect(() => {
//     if (formBuilderData?.fields) {
//       const existingExpressions = new Set(
//         hyperformulaInstance.listNamedExpressions()
//       )

//       formBuilderData.fields.forEach((field) => {
//         const propertyName = field.properties?.propertyName
//         const defaultValue = Number(field.properties?.defaultValue || 0)

//         if (propertyName && !existingExpressions.has(propertyName)) {
//           try {
//             hyperformulaInstance.addNamedExpression(propertyName, defaultValue)
//             existingExpressions.add(propertyName)
//           } catch (error) {
//             console.error(
//               `Error adding named expression for ${propertyName}: ${error}`
//             )
//           }
//         } else if (propertyName) {
//           try {
//             hyperformulaInstance.changeNamedExpression(
//               propertyName,
//               defaultValue
//             )
//           } catch (error) {
//             console.error(
//               `Error updating named expression for ${propertyName}: ${error}`
//             )
//           }
//         }
//       })

//       try {
//         hyperformulaInstance.rebuildAndRecalculate()
//       } catch (error) {
//         console.error(
//           'Error during HyperFormula rebuild and recalculation:',
//           error
//         )
//       }
//     }
//   }, [formBuilderData?.fields])

//   useEffect(() => {
//     if (formData && Object.keys(formData).length > 0) {
//       const existingExpressions = hyperformulaInstance.listNamedExpressions()

//       Object.entries(formData).forEach(([key, value]) => {
//         if (!existingExpressions.includes(key)) {
//           hyperformulaInstance.addNamedExpression(key, Number(value) || 0)
//         } else {
//           hyperformulaInstance.changeNamedExpression(key, Number(value) || 0)
//         }
//       })

//       try {
//         hyperformulaInstance.rebuildAndRecalculate()
//       } catch (error) {}
//     }
//   }, [formData])

//   useEffect(() => {
//     const adjustedData = adjustDataDimensions(data, rows, columns)
//     if (JSON.stringify(data) !== JSON.stringify(adjustedData)) {
//       setData(adjustedData)
//     }
//   }, [rows, columns])

//   const adjustDataDimensions = (
//     currentData: any[][],
//     rows: number,
//     columns: number
//   ) => {
//     const newData = currentData.map((row) => [...row])
//     if (newData.length < rows) {
//       for (let i = newData.length; i < rows; i++) {
//         newData.push(Array(columns).fill(null))
//       }
//     } else if (newData.length > rows) {
//       newData.length = rows
//     }
//     newData.forEach((row) => {
//       if (row.length < columns) {
//         row.push(...Array(columns - row.length).fill(null))
//       } else if (row.length > columns) {
//         row.length = columns
//       }
//     })
//     return newData
//   }

//   const handleAfterChange = (changes: any, source: string) => {
//     if (!changes || source === 'loadData') return

//     const validSheetId = sheetId ?? 0

//     changes.forEach(([row, col, oldValue, newValue]: any) => {
//       if (
//         newValue &&
//         typeof newValue === 'string' &&
//         newValue.startsWith('=')
//       ) {
//         try {
//           hyperformulaInstance.setCellContents(
//             { sheet: validSheetId, row, col },
//             [[newValue]]
//           )
//         } catch (error) {
//           console.error('Error setting formula:', error)
//         }
//       }
//     })

//     const updatedData = hotTableRef.current?.hotInstance?.getData()
//     if (JSON.stringify(data) !== JSON.stringify(updatedData)) {
//       setData(updatedData)
//       updateFieldProperties({ data: updatedData })
//     }
//   }

//   const handleMergeCells = () => {
//     const hotInstance = hotTableRef.current?.hotInstance
//     const selected = hotInstance?.getSelected()
//     if (selected) {
//       const [startRow, startCol, endRow, endCol] = selected[0]
//       const newMerge = {
//         row: startRow,
//         col: startCol,
//         rowspan: endRow - startRow + 1,
//         colspan: endCol - startCol + 1,
//       }

//       const updatedMergeCellsConfig = [...mergeCellsConfig, newMerge]
//       hotInstance.updateSettings({ mergeCells: updatedMergeCellsConfig })
//       setMergeCellsConfig(updatedMergeCellsConfig)

//       updateFieldProperties({
//         data,
//         cellFormats,
//         mergeCellsConfig: updatedMergeCellsConfig,
//       })
//     }
//   }

//   const handleUnmergeCells = () => {
//     const hotInstance = hotTableRef.current?.hotInstance
//     const selected = hotInstance?.getSelected()
//     if (selected) {
//       const [startRow, startCol] = selected[0]
//       const mergeCellsPlugin = hotInstance.getPlugin('mergeCells')
//       mergeCellsPlugin.unmerge(startRow, startCol)

//       const updatedMergeCellsConfig = mergeCellsConfig.filter(
//         (cell) => cell.row !== startRow || cell.col !== startCol
//       )
//       hotInstance.updateSettings({ mergeCells: updatedMergeCellsConfig })
//       setMergeCellsConfig(updatedMergeCellsConfig)

//       updateFieldProperties({
//         data,
//         cellFormats,
//         mergeCellsConfig: updatedMergeCellsConfig,
//       })
//     }
//   }

//   const handleSetAsDate = () => {
//     const selected = hotTableRef.current?.hotInstance.getSelected()
//     if (selected) {
//       const [row, col] = selected[0]
//       const newFormats = { ...cellFormats, [`${row}-${col}`]: 'date' as const }
//       setCellFormats(newFormats)
//       updateFieldProperties({ data, cellFormats: newFormats, mergeCellsConfig })
//     }
//   }

//   const handleSetAsCurrency = () => {
//     const selected = hotTableRef.current?.hotInstance.getSelected()
//     if (selected) {
//       const [row, col] = selected[0]
//       const newFormats = {
//         ...cellFormats,
//         [`${row}-${col}`]: 'currency' as const,
//       }
//       setCellFormats(newFormats)
//       updateFieldProperties({ data, cellFormats: newFormats, mergeCellsConfig })
//     }
//   }

//   const updateFieldProperties = (
//     updatedMeta: Partial<SpreadsheetProperties['meta']>
//   ) => {
//     if (!props?.runtime) {
//       const safeData = data ?? []

//       formBuilderWorksheetActions?.setFieldConfigProperty(props.config?.id!, {
//         meta: {
//           data: [...safeData.map((row: any) => (row ? [...row] : []))],
//           cellFormats: { ...cellFormats },
//           mergeCellsConfig: [...mergeCellsConfig],
//           ...updatedMeta,
//         },
//       } as Properties)
//     }
//   }

//   const cellsHandler = (row: number, col: number) => {
//     const cellProperties = {} as Handsontable.CellProperties
//     cellProperties.width = DEFAULT_COLUMN_WIDTH
//     cellProperties.height = DEFAULT_ROW_HEIGHT

//     // Check if the cell format exists, or default to undefined
//     const format = cellFormats?.[`${row}-${col}`]

//     if (format === 'date') {
//       cellProperties.renderer = (
//         instance,
//         td,
//         row,
//         col,
//         prop,
//         value,
//         cellProperties
//       ) =>
//         CustomContentRenderer(instance, td, row, col, () => {
//           const span = document.createElement('span')
//           span.innerText = reformatDate(
//             instance.getDataAtCell(row, col) as string
//           )
//           return span
//         })
//     } else if (format === 'currency') {
//       cellProperties.renderer = (
//         instance,
//         td,
//         row,
//         col,
//         prop,
//         value,
//         cellProperties
//       ) =>
//         CustomContentRenderer(instance, td, row, col, () => {
//           const span = document.createElement('span')
//           span.innerText = reformatCurrency(
//             instance.getDataAtCell(row, col) as string
//           )
//           return span
//         })
//     }

//     return cellProperties
//   }

//   return (
//     <div
//       ref={containerRef}
//       className="h-[400px] w-1/2 resize-x overflow-auto border md:w-full"
//       style={{ minWidth: '50%', maxWidth: '100%', resize: 'horizontal' }}
//       onMouseDown={(e) => e.stopPropagation()}
//     >
//       <HotTable
//         id="mySpreadsheet"
//         data={data}
//         colHeaders={true}
//         rowHeaders={true}
//         width="100%"
//         height="100%"
//         selectionMode="multiple"
//         copyPaste={true}
//         contextMenu={{
//           items: {
//             row_above: {},
//             row_below: {},
//             col_left: {},
//             col_right: {},
//             remove_row: {},
//             remove_col: {},
//             clear_column: {},
//             mergeCells: { name: 'Merge Cells', callback: handleMergeCells },
//             unmergeCells: {
//               name: 'Unmerge Cells',
//               callback: handleUnmergeCells,
//             },
//             set_as_date: { name: 'Set as Date', callback: handleSetAsDate },
//             set_as_currency: {
//               name: 'Set as Currency',
//               callback: handleSetAsCurrency,
//             },
//           },
//         }}
//         ref={hotTableRef}
//         afterChange={handleAfterChange}
//         persistentState={true}
//         licenseKey="non-commercial-and-evaluation"
//         manualColumnResize={false}
//         manualRowResize={false}
//         autoColumnSize={false}
//         autoRowSize={false}
//         stretchH="all"
//         mergeCells={mergeCellsConfig}
//         formulas={{ engine: hyperformulaInstance }}
//         cells={cellsHandler}
//         colWidths={DEFAULT_COLUMN_WIDTH}
//         rowHeights={DEFAULT_ROW_HEIGHT}
//       />
//     </div>
//   )
// }

// export default registerControl<Properties>(SpreadsheetControl, {
//   noDisplayLabel: true,
// })

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// import React, { useRef, useState, useEffect } from 'react'
// import { HotTable } from '@handsontable/react'
// import 'handsontable/dist/handsontable.full.min.css'
// import Handsontable from 'handsontable'
// import {
//   registerControl,
//   RegisterControlProps,
//   RegisteredControlProperties,
// } from '../hoc/registerControl'
// import { CustomContentRenderer } from './utils/customButtonRenderer'
// import { hyperformulaInstance, sheetId } from './utils/hyperformulaConfig'
// import { reformatDate, reformatCurrency } from './utils/formatters'
// import { SpreadsheetProperties } from '@components/features/FormBuilder/FormBuilderFieldProperties/Spreadsheet/types'
// import { registerAllCellTypes } from 'handsontable/cellTypes'
// import { registerAllPlugins } from 'handsontable/plugins'
// import { useFormBuilderWorksheetGrid } from '../../hooks/useFormBuilderWorksheetGrid'
// import { createSpreadsheetDefaultValue } from '../../FormBuilderFieldProperties/Spreadsheet/constants'
// import { useFormBuilder } from '../../hooks/useFormBuilder'
// import { useFormService } from '../../hooks/useFormService'

// registerAllCellTypes()
// registerAllPlugins()

// type Properties = RegisteredControlProperties &
//   SpreadsheetProperties & {
//     externalVariables?: {
//       [key: string]: {
//         propertyName?: string
//         defaultValue?: number
//       }
//     }
//   }

// const SpreadsheetControl: React.FC<RegisterControlProps<Properties>> = (
//   props
// ) => {
//   const hotTableRef = useRef<any>(null)
//   const containerRef = useRef<HTMLDivElement>(null)

//   const { rows = 1, columns = 1 } = props.properties || {}

//   const DEFAULT_COLUMN_WIDTH = 100
//   const DEFAULT_ROW_HEIGHT = 25

//   const defaultMeta = {
//     data: createSpreadsheetDefaultValue(rows, columns),
//     cellFormats: {} as { [key: string]: 'date' | 'currency' | undefined },
//     mergeCellsConfig: [],
//   }

//   const meta = props.properties?.meta || defaultMeta
//   const { actions: formBuilderWorksheetActions } = useFormBuilderWorksheetGrid()
//   const { actions, data: formBuilderData } = useFormBuilder()
//   const { watch } = useFormService()
//   const formData = watch()

//   if (!actions || !actions.getAllFields) {
//   }

//   const [data, setData] = useState(() => JSON.parse(JSON.stringify(meta.data)))
//   const [cellFormats, setCellFormats] = useState(meta.cellFormats)
//   const [mergeCellsConfig, setMergeCellsConfig] = useState(
//     meta.mergeCellsConfig
//   )

//   useEffect(() => {
//     console.log('Initializing meta from props:', props.properties?.meta)
//     const initialMeta = props.properties?.meta || defaultMeta
//     setData(JSON.parse(JSON.stringify(initialMeta.data)))
//     setCellFormats(initialMeta.cellFormats)
//     setMergeCellsConfig(initialMeta.mergeCellsConfig)
//   }, [props.properties?.meta])

//   useEffect(() => {
//     console.log('Data updated:', data)
//   }, [data])

//   useEffect(() => {
//     console.log('Cell formats updated:', cellFormats)
//   }, [cellFormats])

//   useEffect(() => {
//     console.log('Merge cells configuration updated:', mergeCellsConfig)
//   }, [mergeCellsConfig])

//   useEffect(() => {
//     if (formBuilderData?.fields) {
//       const existingExpressions = hyperformulaInstance.listNamedExpressions()

//       formBuilderData.fields.forEach((field) => {
//         const propertyName = field.properties?.propertyName
//         const defaultValue = Number(field.properties?.defaultValue || 0)

//         if (propertyName) {
//           if (!existingExpressions.includes(propertyName)) {
//             hyperformulaInstance.addNamedExpression(propertyName, defaultValue)
//           } else {
//             hyperformulaInstance.changeNamedExpression(
//               propertyName,
//               defaultValue
//             )
//           }
//         }
//       })

//       hyperformulaInstance.rebuildAndRecalculate()
//     }
//   }, [formBuilderData])

//   useEffect(() => {
//     if (props.externalVariables) {
//       const existingExpressions = new Set(
//         hyperformulaInstance.listNamedExpressions()
//       )

//       Object.entries(props.externalVariables).forEach(([key, variable]) => {
//         const typedVariable = variable as {
//           propertyName?: string
//           defaultValue?: number
//         }

//         const variableName = typedVariable.propertyName || key
//         const value = Number(typedVariable.defaultValue || 0)

//         if (!existingExpressions.has(variableName)) {
//           hyperformulaInstance.addNamedExpression(variableName, value, sheetId)
//         } else {
//           hyperformulaInstance.changeNamedExpression(
//             variableName,
//             value,
//             sheetId
//           )
//         }
//       })

//       hyperformulaInstance.rebuildAndRecalculate()
//       syncSpreadsheetWithEngine()
//     }
//   }, [props.externalVariables])

//   useEffect(() => {
//     if (formBuilderData) {
//       const existingExpressions = hyperformulaInstance.listNamedExpressions()

//       Object.entries(formBuilderData).forEach(([key, value]) => {
//         const numericValue = Number(value) || 0

//         if (!existingExpressions.includes(key)) {
//           hyperformulaInstance.addNamedExpression(key, numericValue)
//         } else {
//           hyperformulaInstance.changeNamedExpression(key, numericValue)
//         }
//       })

//       hyperformulaInstance.rebuildAndRecalculate()
//     }
//   }, [formBuilderData])

//   useEffect(() => {
//     if (formBuilderData?.fields) {
//       const existingExpressions = new Set(
//         hyperformulaInstance.listNamedExpressions()
//       )

//       formBuilderData.fields.forEach((field) => {
//         const propertyName = field.properties?.propertyName
//         const defaultValue = Number(field.properties?.defaultValue || 0)

//         if (propertyName && !existingExpressions.has(propertyName)) {
//           try {
//             hyperformulaInstance.addNamedExpression(propertyName, defaultValue)
//             existingExpressions.add(propertyName)
//           } catch (error) {
//             console.error(
//               `Error adding named expression for ${propertyName}: ${error}`
//             )
//           }
//         } else if (propertyName) {
//           try {
//             hyperformulaInstance.changeNamedExpression(
//               propertyName,
//               defaultValue
//             )
//           } catch (error) {
//             console.error(
//               `Error updating named expression for ${propertyName}: ${error}`
//             )
//           }
//         }
//       })

//       try {
//         hyperformulaInstance.rebuildAndRecalculate()
//       } catch (error) {
//         console.error(
//           'Error during HyperFormula rebuild and recalculation:',
//           error
//         )
//       }
//     }
//   }, [formBuilderData?.fields])

//   useEffect(() => {
//     if (formData && Object.keys(formData).length > 0) {
//       const existingExpressions = hyperformulaInstance.listNamedExpressions()

//       Object.entries(formData).forEach(([key, value]) => {
//         if (!existingExpressions.includes(key)) {
//           hyperformulaInstance.addNamedExpression(key, Number(value) || 0)
//         } else {
//           hyperformulaInstance.changeNamedExpression(key, Number(value) || 0)
//         }
//       })

//       try {
//         hyperformulaInstance.rebuildAndRecalculate()
//       } catch (error) {}
//     }
//   }, [formData])

//   useEffect(() => {
//     const adjustedData = adjustDataDimensions(data, rows, columns)
//     if (JSON.stringify(data) !== JSON.stringify(adjustedData)) {
//       setData(adjustedData)
//       updateFieldProperties({ data: adjustedData })
//     }
//   }, [rows, columns])

//   const adjustDataDimensions = (
//     currentData: any[][],
//     rows: number,
//     columns: number
//   ) => {
//     const newData = currentData.map((row) => [...row])
//     if (newData.length < rows) {
//       for (let i = newData.length; i < rows; i++) {
//         newData.push(Array(columns).fill(null))
//       }
//     } else if (newData.length > rows) {
//       newData.length = rows
//     }
//     newData.forEach((row) => {
//       if (row.length < columns) {
//         row.push(...Array(columns - row.length).fill(null))
//       } else if (row.length > columns) {
//         row.length = columns
//       }
//     })
//     return newData
//   }
//   const syncSpreadsheetWithEngine = () => {
//     if (hotTableRef.current?.hotInstance) {
//       const updatedData = hyperformulaInstance.getSheetValues(sheetId)
//       console.log('Syncing spreadsheet with engine. Updated Data:', updatedData)
//       hotTableRef.current.hotInstance.loadData(updatedData)
//     }
//   }

//   const handleAfterChange = (changes: any, source: string) => {
//     console.log('After Change Triggered. Source:', source)
//     console.log('Changes:', changes)

//     if (!changes || source === 'loadData') return

//     const validSheetId = sheetId ?? 0

//     changes.forEach(([row, col, oldValue, newValue]: any) => {
//       console.log(
//         `Updating cell [${row}, ${col}] from ${oldValue} to ${newValue}`
//       )
//       if (
//         newValue &&
//         typeof newValue === 'string' &&
//         newValue.startsWith('=')
//       ) {
//         hyperformulaInstance.setCellContents(
//           { sheet: validSheetId, row, col },
//           [[newValue]]
//         )
//       } else {
//         hyperformulaInstance.setCellContents(
//           { sheet: validSheetId, row, col },
//           [[newValue || null]]
//         )
//       }
//     })

//     // Recalculate and sync data
//     hyperformulaInstance.rebuildAndRecalculate()
//     console.log(
//       'Recalculated HyperFormula Instance:',
//       hyperformulaInstance.getSheetValues(sheetId)
//     )
//     syncSpreadsheetWithEngine()
//   }

//   const handleMergeCells = () => {
//     const hotInstance = hotTableRef.current?.hotInstance
//     const selected = hotInstance?.getSelected()
//     if (selected) {
//       const [startRow, startCol, endRow, endCol] = selected[0]
//       const newMerge = {
//         row: startRow,
//         col: startCol,
//         rowspan: endRow - startRow + 1,
//         colspan: endCol - startCol + 1,
//       }

//       const updatedMergeCellsConfig = [...mergeCellsConfig, newMerge]
//       hotInstance.updateSettings({ mergeCells: updatedMergeCellsConfig })
//       setMergeCellsConfig(updatedMergeCellsConfig)

//       updateFieldProperties({
//         data,
//         cellFormats,
//         mergeCellsConfig: updatedMergeCellsConfig,
//       })
//     }
//   }

//   const handleUnmergeCells = () => {
//     const hotInstance = hotTableRef.current?.hotInstance
//     const selected = hotInstance?.getSelected()
//     if (selected) {
//       const [startRow, startCol] = selected[0]
//       const mergeCellsPlugin = hotInstance.getPlugin('mergeCells')
//       mergeCellsPlugin.unmerge(startRow, startCol)

//       const updatedMergeCellsConfig = mergeCellsConfig.filter(
//         (cell) => cell.row !== startRow || cell.col !== startCol
//       )
//       hotInstance.updateSettings({ mergeCells: updatedMergeCellsConfig })
//       setMergeCellsConfig(updatedMergeCellsConfig)

//       updateFieldProperties({
//         data,
//         cellFormats,
//         mergeCellsConfig: updatedMergeCellsConfig,
//       })
//     }
//   }

//   const handleSetAsDate = () => {
//     const selected = hotTableRef.current?.hotInstance.getSelected()
//     if (selected) {
//       const [row, col] = selected[0]
//       const newFormats = { ...cellFormats, [`${row}-${col}`]: 'date' as const }
//       setCellFormats(newFormats)
//       updateFieldProperties({ data, cellFormats: newFormats, mergeCellsConfig })
//     }
//   }

//   const handleSetAsCurrency = () => {
//     const selected = hotTableRef.current?.hotInstance.getSelected()
//     if (selected) {
//       const [row, col] = selected[0]
//       const newFormats = {
//         ...cellFormats,
//         [`${row}-${col}`]: 'currency' as const,
//       }
//       setCellFormats(newFormats)
//       updateFieldProperties({ data, cellFormats: newFormats, mergeCellsConfig })
//     }
//   }
//   const updateFieldProperties = (
//     updatedMeta: Partial<SpreadsheetProperties['meta']>
//   ) => {
//     console.log('Updating field properties with meta:', updatedMeta)
//     console.log('Current data:', data)
//     if (!props.runtime) {
//       formBuilderWorksheetActions?.setFieldConfigProperty(props.config?.id!, {
//         meta: {
//           data: [...data.map((row: any) => (row ? [...row] : []))],
//           cellFormats: { ...cellFormats },
//           mergeCellsConfig: [...mergeCellsConfig],
//           ...updatedMeta,
//         },
//       } as Properties)
//     }
//   }

//   const cellsHandler = (row: number, col: number) => {
//     const cellProperties = {} as Handsontable.CellProperties
//     cellProperties.width = DEFAULT_COLUMN_WIDTH
//     cellProperties.height = DEFAULT_ROW_HEIGHT

//     // Check if the cell format exists, or default to undefined
//     const format = cellFormats?.[`${row}-${col}`]

//     if (format === 'date') {
//       cellProperties.renderer = (
//         instance,
//         td,
//         row,
//         col,
//         prop,
//         value,
//         cellProperties
//       ) =>
//         CustomContentRenderer(instance, td, row, col, () => {
//           const span = document.createElement('span')
//           span.innerText = reformatDate(
//             instance.getDataAtCell(row, col) as string
//           )
//           return span
//         })
//     } else if (format === 'currency') {
//       cellProperties.renderer = (
//         instance,
//         td,
//         row,
//         col,
//         prop,
//         value,
//         cellProperties
//       ) =>
//         CustomContentRenderer(instance, td, row, col, () => {
//           const span = document.createElement('span')
//           span.innerText = reformatCurrency(
//             instance.getDataAtCell(row, col) as string
//           )
//           return span
//         })
//     }

//     return cellProperties
//   }

//   return (
//     <div
//       ref={containerRef}
//       className="h-[400px] w-1/2 resize-x overflow-auto border md:w-full"
//       style={{ minWidth: '50%', maxWidth: '100%', resize: 'horizontal' }}
//       onMouseDown={(e) => e.stopPropagation()}
//     >
//       <HotTable
//         id="mySpreadsheet"
//         data={data}
//         colHeaders={true}
//         rowHeaders={true}
//         width="100%"
//         height="100%"
//         selectionMode="multiple"
//         copyPaste={true}
//         contextMenu={{
//           items: {
//             row_above: {},
//             row_below: {},
//             col_left: {},
//             col_right: {},
//             remove_row: {},
//             remove_col: {},
//             clear_column: {},
//             mergeCells: { name: 'Merge Cells', callback: handleMergeCells },
//             unmergeCells: {
//               name: 'Unmerge Cells',
//               callback: handleUnmergeCells,
//             },
//             set_as_date: { name: 'Set as Date', callback: handleSetAsDate },
//             set_as_currency: {
//               name: 'Set as Currency',
//               callback: handleSetAsCurrency,
//             },
//           },
//         }}
//         ref={hotTableRef}
//         afterChange={handleAfterChange}
//         persistentState={true}
//         licenseKey="non-commercial-and-evaluation"
//         manualColumnResize={false}
//         manualRowResize={false}
//         autoColumnSize={false}
//         autoRowSize={false}
//         stretchH="all"
//         mergeCells={mergeCellsConfig}
//         formulas={{ engine: hyperformulaInstance }}
//         cells={cellsHandler}
//         colWidths={DEFAULT_COLUMN_WIDTH}
//         rowHeights={DEFAULT_ROW_HEIGHT}
//       />
//     </div>
//   )
// }

// export default registerControl<Properties>(SpreadsheetControl, {
//   noDisplayLabel: true,
// })

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

import React, { useRef, useState, useEffect } from 'react'
import { HotTable } from '@handsontable/react'
import 'handsontable/dist/handsontable.full.min.css'
import Handsontable from 'handsontable'
import {
  registerControl,
  RegisterControlProps,
  RegisteredControlProperties,
} from '../hoc/registerControl'
import { CustomContentRenderer } from './utils/customButtonRenderer'
import { hyperformulaInstance, sheetId } from './utils/hyperformulaConfig'
import { reformatDate, reformatCurrency } from './utils/formatters'
import { SpreadsheetProperties } from '@components/features/FormBuilder/FormBuilderFieldProperties/Spreadsheet/types'
import { registerAllCellTypes } from 'handsontable/cellTypes'
import { registerAllPlugins } from 'handsontable/plugins'
import { useFormBuilderWorksheetGrid } from '../../hooks/useFormBuilderWorksheetGrid'
import { createSpreadsheetDefaultValue } from '../../FormBuilderFieldProperties/Spreadsheet/constants'
import { useFormBuilder } from '../../hooks/useFormBuilder'
import { useFormService } from '../../hooks/useFormService'

registerAllCellTypes()
registerAllPlugins()

type Properties = RegisteredControlProperties &
  SpreadsheetProperties & {
    externalVariables?: {
      [key: string]: {
        propertyName?: string
        defaultValue?: number
      }
    }
  }

const SpreadsheetControl: React.FC<RegisterControlProps<Properties>> = (
  props
) => {
  const hotTableRef = useRef<any>(null)
  const containerRef = useRef<HTMLDivElement>(null)

  const { rows = 1, columns = 1 } = props.properties || {}

  const DEFAULT_COLUMN_WIDTH = 100
  const DEFAULT_ROW_HEIGHT = 25

  const defaultMeta = {
    data: createSpreadsheetDefaultValue(rows, columns),
    cellFormats: {} as { [key: string]: 'date' | 'currency' | undefined },
    mergeCellsConfig: [],
  }

  const meta = props.properties?.meta || defaultMeta
  const { actions: formBuilderWorksheetActions } = useFormBuilderWorksheetGrid()
  const { actions, data: formBuilderData } = useFormBuilder()
  const { watch } = useFormService()
  const formData = watch()

  if (!actions || !actions.getAllFields) {
  }

  const [data, setData] = useState(() => JSON.parse(JSON.stringify(meta.data)))
  const [cellFormats, setCellFormats] = useState(meta.cellFormats)
  const [mergeCellsConfig, setMergeCellsConfig] = useState(
    meta.mergeCellsConfig
  )

  useEffect(() => {
    if (props.externalVariables) {
      const existingExpressions = new Set(
        hyperformulaInstance.listNamedExpressions()
      )

      Object.entries(props.externalVariables).forEach(([key, property]) => {
        const typedProperty = property as {
          propertyName?: string
          defaultValue?: number
        }

        const variableName = typedProperty.propertyName || key
        const value = Number(typedProperty.defaultValue || 0)

        if (!existingExpressions.has(variableName)) {
          try {
            hyperformulaInstance.addNamedExpression(
              variableName,
              value,
              sheetId
            )
            existingExpressions.add(variableName)
          } catch (error) {
            console.error(
              `Error adding named expression ${variableName}:`,
              error
            )
          }
        } else {
          try {
            hyperformulaInstance.changeNamedExpression(
              variableName,
              value,
              sheetId
            )
          } catch (error) {
            console.error(
              `Error updating named expression ${variableName}:`,
              error
            )
          }
        }
      })

      try {
        hyperformulaInstance.rebuildAndRecalculate()
        syncSpreadsheetWithEngine()
      } catch (error) {
        console.error(
          'Error during HyperFormula rebuild and recalculation:',
          error
        )
      }
    }
  }, [props.externalVariables])

  const syncSpreadsheetWithEngine = () => {
    if (hotTableRef.current?.hotInstance) {
      const updatedData = hyperformulaInstance.getSheetValues(sheetId)
      console.log('Syncing spreadsheet with engine. Updated Data:', updatedData)
      hotTableRef.current.hotInstance.loadData(updatedData)
    }
  }

  useEffect(() => {
    const syncSpreadsheetWithEngine = () => {
      if (hotTableRef.current?.hotInstance) {
        const updatedData = hyperformulaInstance.getSheetValues(sheetId)
        console.log(
          'Syncing spreadsheet with engine. Updated Data:',
          updatedData
        )
        hotTableRef.current.hotInstance.loadData(updatedData)
      }
    }

    if (formBuilderData) {
      const existingExpressions = hyperformulaInstance.listNamedExpressions()

      Object.entries(formBuilderData).forEach(([key, value]) => {
        const numericValue = Number(value) || 0

        if (!existingExpressions.includes(key)) {
          hyperformulaInstance.addNamedExpression(key, numericValue)
        } else {
          hyperformulaInstance.changeNamedExpression(key, numericValue)
        }
      })

      hyperformulaInstance.rebuildAndRecalculate()
      syncSpreadsheetWithEngine()
    }
  }, [formBuilderData])

  useEffect(() => {
    if (formBuilderData?.fields) {
      const existingExpressions = new Set(
        hyperformulaInstance.listNamedExpressions()
      )

      formBuilderData.fields.forEach((field) => {
        const propertyName = field.properties?.propertyName
        const defaultValue = Number(field.properties?.defaultValue || 0)

        if (propertyName && !existingExpressions.has(propertyName)) {
          try {
            hyperformulaInstance.addNamedExpression(propertyName, defaultValue)
            existingExpressions.add(propertyName)
          } catch (error) {
            console.error(
              `Error adding named expression for ${propertyName}: ${error}`
            )
          }
        } else if (propertyName) {
          try {
            hyperformulaInstance.changeNamedExpression(
              propertyName,
              defaultValue
            )
          } catch (error) {
            console.error(
              `Error updating named expression for ${propertyName}: ${error}`
            )
          }
        }
      })

      try {
        hyperformulaInstance.rebuildAndRecalculate()
      } catch (error) {
        console.error(
          'Error during HyperFormula rebuild and recalculation:',
          error
        )
      }
    }
  }, [formBuilderData?.fields])

  useEffect(() => {
    if (formData && Object.keys(formData).length > 0) {
      const existingExpressions = hyperformulaInstance.listNamedExpressions()

      Object.entries(formData).forEach(([key, value]) => {
        if (!existingExpressions.includes(key)) {
          hyperformulaInstance.addNamedExpression(key, Number(value) || 0)
        } else {
          hyperformulaInstance.changeNamedExpression(key, Number(value) || 0)
        }
      })

      try {
        hyperformulaInstance.rebuildAndRecalculate()
      } catch (error) {}
    }
  }, [formData])

  useEffect(() => {
    const adjustedData = adjustDataDimensions(data, rows, columns)
    if (JSON.stringify(data) !== JSON.stringify(adjustedData)) {
      setData(adjustedData)
    }
  }, [rows, columns])

  const adjustDataDimensions = (
    currentData: any[][],
    rows: number,
    columns: number
  ) => {
    const newData = currentData.map((row) => [...row])
    if (newData.length < rows) {
      for (let i = newData.length; i < rows; i++) {
        newData.push(Array(columns).fill(null))
      }
    } else if (newData.length > rows) {
      newData.length = rows
    }
    newData.forEach((row) => {
      if (row.length < columns) {
        row.push(...Array(columns - row.length).fill(null))
      } else if (row.length > columns) {
        row.length = columns
      }
    })
    return newData
  }

  const handleAfterChange = (changes: any, source: string) => {
    if (!changes || source === 'loadData') return

    const validSheetId = sheetId ?? 0

    changes.forEach(([row, col, oldValue, newValue]: any) => {
      if (
        newValue &&
        typeof newValue === 'string' &&
        newValue.startsWith('=')
      ) {
        try {
          hyperformulaInstance.setCellContents(
            { sheet: validSheetId, row, col },
            [[newValue]]
          )
        } catch (error) {
          console.error('Error setting formula:', error)
        }
      }
    })

    try {
      hyperformulaInstance.rebuildAndRecalculate()
      syncSpreadsheetWithEngine() // Ensure the spreadsheet reflects changes
    } catch (error) {
      console.error('Error recalculating formulas:', error)
    }
  }

  const handleMergeCells = () => {
    const hotInstance = hotTableRef.current?.hotInstance
    const selected = hotInstance?.getSelected()
    if (selected) {
      const [startRow, startCol, endRow, endCol] = selected[0]
      const newMerge = {
        row: startRow,
        col: startCol,
        rowspan: endRow - startRow + 1,
        colspan: endCol - startCol + 1,
      }

      const updatedMergeCellsConfig = [...mergeCellsConfig, newMerge]
      hotInstance.updateSettings({ mergeCells: updatedMergeCellsConfig })
      setMergeCellsConfig(updatedMergeCellsConfig)

      updateFieldProperties({
        data,
        cellFormats,
        mergeCellsConfig: updatedMergeCellsConfig,
      })
    }
  }

  const handleUnmergeCells = () => {
    const hotInstance = hotTableRef.current?.hotInstance
    const selected = hotInstance?.getSelected()
    if (selected) {
      const [startRow, startCol] = selected[0]
      const mergeCellsPlugin = hotInstance.getPlugin('mergeCells')
      mergeCellsPlugin.unmerge(startRow, startCol)

      const updatedMergeCellsConfig = mergeCellsConfig.filter(
        (cell) => cell.row !== startRow || cell.col !== startCol
      )
      hotInstance.updateSettings({ mergeCells: updatedMergeCellsConfig })
      setMergeCellsConfig(updatedMergeCellsConfig)

      updateFieldProperties({
        data,
        cellFormats,
        mergeCellsConfig: updatedMergeCellsConfig,
      })
    }
  }

  const handleSetAsDate = () => {
    const selected = hotTableRef.current?.hotInstance.getSelected()
    if (selected) {
      const [row, col] = selected[0]
      const newFormats = { ...cellFormats, [`${row}-${col}`]: 'date' as const }
      setCellFormats(newFormats)
      updateFieldProperties({ data, cellFormats: newFormats, mergeCellsConfig })
    }
  }

  const handleSetAsCurrency = () => {
    const selected = hotTableRef.current?.hotInstance.getSelected()
    if (selected) {
      const [row, col] = selected[0]
      const newFormats = {
        ...cellFormats,
        [`${row}-${col}`]: 'currency' as const,
      }
      setCellFormats(newFormats)
      updateFieldProperties({ data, cellFormats: newFormats, mergeCellsConfig })
    }
  }

  const updateFieldProperties = (
    updatedMeta: Partial<SpreadsheetProperties['meta']>
  ) => {
    if (!props?.runtime) {
      const safeData = data ?? []

      formBuilderWorksheetActions?.setFieldConfigProperty(props.config?.id!, {
        meta: {
          data: [...safeData.map((row: any) => (row ? [...row] : []))],
          cellFormats: { ...cellFormats },
          mergeCellsConfig: [...mergeCellsConfig],
          ...updatedMeta,
        },
      } as Properties)
    }
  }

  const cellsHandler = (row: number, col: number) => {
    const cellProperties = {} as Handsontable.CellProperties
    cellProperties.width = DEFAULT_COLUMN_WIDTH
    cellProperties.height = DEFAULT_ROW_HEIGHT

    // Check if the cell format exists, or default to undefined
    const format = cellFormats?.[`${row}-${col}`]

    if (format === 'date') {
      cellProperties.renderer = (
        instance,
        td,
        row,
        col,
        prop,
        value,
        cellProperties
      ) =>
        CustomContentRenderer(instance, td, row, col, () => {
          const span = document.createElement('span')
          span.innerText = reformatDate(
            instance.getDataAtCell(row, col) as string
          )
          return span
        })
    } else if (format === 'currency') {
      cellProperties.renderer = (
        instance,
        td,
        row,
        col,
        prop,
        value,
        cellProperties
      ) =>
        CustomContentRenderer(instance, td, row, col, () => {
          const span = document.createElement('span')
          span.innerText = reformatCurrency(
            instance.getDataAtCell(row, col) as string
          )
          return span
        })
    }

    return cellProperties
  }

  return (
    <div
      ref={containerRef}
      className="h-[400px] w-1/2 resize-x overflow-auto border md:w-full"
      style={{ minWidth: '50%', maxWidth: '100%', resize: 'horizontal' }}
      onMouseDown={(e) => e.stopPropagation()}
    >
      <HotTable
        id="mySpreadsheet"
        data={data}
        colHeaders={true}
        rowHeaders={true}
        width="100%"
        height="100%"
        selectionMode="multiple"
        copyPaste={true}
        contextMenu={{
          items: {
            row_above: {},
            row_below: {},
            col_left: {},
            col_right: {},
            remove_row: {},
            remove_col: {},
            clear_column: {},
            mergeCells: { name: 'Merge Cells', callback: handleMergeCells },
            unmergeCells: {
              name: 'Unmerge Cells',
              callback: handleUnmergeCells,
            },
            set_as_date: { name: 'Set as Date', callback: handleSetAsDate },
            set_as_currency: {
              name: 'Set as Currency',
              callback: handleSetAsCurrency,
            },
          },
        }}
        ref={hotTableRef}
        afterChange={handleAfterChange}
        persistentState={true}
        licenseKey="non-commercial-and-evaluation"
        manualColumnResize={false}
        manualRowResize={false}
        autoColumnSize={false}
        autoRowSize={false}
        stretchH="all"
        mergeCells={mergeCellsConfig}
        formulas={{ engine: hyperformulaInstance }}
        cells={cellsHandler}
        colWidths={DEFAULT_COLUMN_WIDTH}
        rowHeights={DEFAULT_ROW_HEIGHT}
      />
    </div>
  )
}

export default registerControl<Properties>(SpreadsheetControl, {
  noDisplayLabel: true,
})