import { Button, Notification, toast } from '@/components/ui'
import { GridDto, UiCommandButtonPositionTypeEnum } from '@/proxy/form/models'
import { dynamicFetch } from '@/services/form.service'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { usePermission } from '@/utils/hooks/usePermission'
import { DataGridTypes } from 'devextreme-react/data-grid'
import { ToolbarItem } from 'devextreme/ui/data_grid_types'
import { useEffect, useState } from 'react'
import { useDialogContext } from '../shared/DialogContext'
import { usePWA } from '@/utils/hooks/usePWA'
import { layoutTypes, ListViewLayoutType } from '../admin/listForm/edit/types'
import { useStoreState } from '@/store'

type ToolbarModalData = {
  open: boolean
  content?: JSX.Element
}

// https://js.devexpress.com/Documentation/ApiReference/UI_Components/dxDataGrid/Configuration/toolbar/
// item.name > Accepted Values: 'addRowButton', 'applyFilterButton', 'columnChooserButton', 'exportButton', 'groupPanel', 'revertButton', 'saveButton', 'searchPanel'
const useToolbar = ({
  gridDto,
  listFormCode,
  getSelectedRowKeys,
  getSelectedRowsData,
  refreshData,
  getFilter,
  layout,
  expandAll,
  collapseAll,
}: {
  gridDto?: GridDto
  listFormCode: string
  getSelectedRowKeys: () => void
  getSelectedRowsData: () => any
  refreshData: () => void
  getFilter: () => void
  layout: ListViewLayoutType | string
  expandAll?: () => void
  collapseAll?: () => void
}): {
  toolbarData: ToolbarItem[]
  toolbarModalData: ToolbarModalData | undefined
  setToolbarModalData: (data: ToolbarModalData | undefined) => void
} => {
  const dialog: any = useDialogContext()
  const { translate } = useLocalization()
  const { checkPermission } = usePermission()
  const isPwaMode = usePWA()
  const config = useStoreState((state) => state.abpConfig.config)

  const [toolbarData, setToolbarData] = useState<ToolbarItem[]>([])
  const [toolbarModalData, setToolbarModalData] = useState<ToolbarModalData>()

  const grdOpt = gridDto?.gridOptions

  function getToolbarData() {
    const items: ToolbarItem[] = []

    if (!gridDto || !grdOpt) {
      setToolbarData(items)
      return
    }

    // Add searchPanel
    if (grdOpt.searchPanelDto?.visible) {
      items.push({
        locateInMenu: 'auto',
        showText: 'inMenu',
        name: 'searchPanel',
      })
    }

    // Add InsertNewRecord button
    if (grdOpt.editingOptionDto?.allowAdding && checkPermission(grdOpt.permissionDto?.c)) {
      if (grdOpt.editingOptionDto?.addPageUrl) {
        items.push({
          widget: 'dxButton',
          showText: 'always',
          name: 'addRowButton',
          location: 'after',
          options: {
            text: translate('::ListForms.ListForm.AddNewRecord'),
            hint: translate('::ListForms.ListForm.AddNewRecord'),
            onClick() {
              window.open(grdOpt.editingOptionDto?.addPageUrl, isPwaMode ? '_self' : '_blank')
            },
          },
        })
      } else {
        items.push({
          locateInMenu: 'auto',
          showText: 'always',
          name: 'addRowButton',
          location: 'after',
          options: {
            text: translate('::ListForms.ListForm.AddNewRecord'),
            hint: translate('::ListForms.ListForm.AddNewRecord'),
          },
        })
      }
    }

    items.push({
      widget: 'dxButton',
      name: 'refreshButton',
      options: {
        icon: 'refresh',
        onClick: refreshData,
        text: translate('::ListForms.ListForm.Refresh'),
      },
      location: 'after',
    })

    // Add Expand All button for TreeList
    if (layout === layoutTypes.tree && grdOpt.treeOptionDto?.parentIdExpr) {
      items.push({
        widget: 'dxButton',
        name: 'expandAllButton',
        options: {
          icon: 'plus',
          text: translate('::ListForms.ListFormEdit.ExpandAll'),
          onClick: expandAll,
        },
        location: 'after',
      })

      // Add Collapse All button for TreeList
      items.push({
        widget: 'dxButton',
        name: 'collapseAllButton',
        options: {
          icon: 'minus',
          text: translate('::ListForms.ListFormEdit.CollapseAll'),
          onClick: collapseAll,
        },
        location: 'after',
      })
    }

    // field chooser panel
    if (grdOpt.columnOptionDto?.columnChooserEnabled) {
      items.push({
        locateInMenu: 'auto',
        showText: 'inMenu',
        name: 'columnChooserButton',
        options: {
          hint: translate('::ListForms.ListForm.ColumnChooser'),
        },
      })
    }

    // Add group panel
    if (grdOpt.groupPanelDto?.visible) {
      items.push({
        locateInMenu: 'auto',
        showText: 'inMenu',
        name: 'groupPanel',
      })
    }

    // Add DeleteSelectedRecords button
    // coklu silme icin
    if (grdOpt.editingOptionDto?.allowDeleting && checkPermission(grdOpt.permissionDto?.d)) {
      items.push({
        location: 'after',
        widget: 'dxButton',
        locateInMenu: 'auto',
        showText: 'inMenu',
        name: 'deleteSelectedRecords',
        options: {
          text: translate('::ListForms.ListForm.DeleteSelectedRecords'),
          icon: 'trash',
          visible: false,
          onClick() {
            if (!grdOpt.deleteServiceAddress) {
              return
            }

            dynamicFetch(grdOpt.deleteServiceAddress, 'POST', null, {
              keys: getSelectedRowKeys(),
              listFormCode,
            }).then(() => {
              refreshData()
            })
          },
        },
      })

      // Add DeleteAllRecords button
      // butun kayitlari (filtreli) icin
      if (grdOpt.editingOptionDto?.allowAllDeleting) {
        const buttonDeleteAll: DataGridTypes.ToolbarItem = {
          location: 'after',
          widget: 'dxButton',
          name: 'deleteAllRecords',
          options: {
            text: translate('::ListForms.ListForm.DeleteAllRecords'),
            hint: translate('::ListForms.ListForm.DeleteAllRecords'),
            icon: 'trash',
            visible: true,
            onClick() {
              const parameters = {
                listFormCode,
                filter: JSON.stringify(getFilter()),
                onlyTotalCountQuery: true,
                createDeleteQuery: false,
              }

              dynamicFetch('list-form-select/select', 'GET', parameters).then((r: any) => {
                setToolbarModalData({
                  open: true,
                  content: (
                    <>
                      <h5 className="mb-4">Delete All Records</h5>

                      <p>Are you sure to delete all {r.data.totalCount} records?</p>

                      <div className="text-right mt-6">
                        <Button
                          className="ltr:mr-2 rtl:ml-2"
                          variant="plain"
                          onClick={() => setToolbarModalData(undefined)}
                        >
                          Cancel
                        </Button>
                        <Button
                          variant="solid"
                          onClick={() => {
                            //delete parameters.onlyTotalCountQuery
                            parameters.createDeleteQuery = true // tumunu silme islemi parametresi > set
                            dynamicFetch('list-form-select/select', 'GET', parameters).then(() => {
                              toast.push(
                                <Notification type="success" duration={2000}>
                                  {'Tüm kayıtlar silindi.'}
                                </Notification>,
                                {
                                  placement: 'top-end',
                                },
                              )

                              refreshData()

                              setToolbarModalData(undefined)
                            })
                          }}
                        >
                          Save
                        </Button>
                      </div>
                    </>
                  ),
                })
              })
            },
          },
        }
        items.push(buttonDeleteAll)
      }
    }

    // #region Toolbar icin kullanici tanimli dinamik butonlari ekler
    for (let i = 0; i < grdOpt.commandColumnDto.length; i++) {
      const action = grdOpt.commandColumnDto[i]

      // action.buttonPosition == 1 ise Toolbar butonudur, burada sadece Toolbar butonunu eklenir
      if (action.buttonPosition !== UiCommandButtonPositionTypeEnum.Toolbar) {
        continue
      }

      if (checkPermission(action.authName)) {
        const buttonCustom: DataGridTypes.ToolbarItem = {
          location: 'after',
          widget: 'dxButton',
          name: action.hint,
          options: {
            hint: translate('::' + action.hint),
            text: translate('::' + action.text),
            icon: action.icon,
            visible: true,
            onClick(e: any) {
              if (typeof e.event?.preventDefault === 'function') {
                e?.event?.preventDefault()
              }
              if (action.url) {
                let url = action.url
                // griddeki secili satirlari al
                const selectedRowsData = getSelectedRowsData()
                // constsa her bir secili satir icin donguye gir
                for (let i = 0; i < selectedRowsData.length; i++) {
                  // secili satirin objesine ait property verilerini al
                  const keys = Object.keys(selectedRowsData[i])
                  // secili satirin her bir property si icin donguye gir
                  for (let j = 0; j < keys.length; j++) {
                    // secili satirin j indexine sahip property ismini al
                    const fieldName = keys[j]
                    // secili satirin j indexine sahip property isminin degerini al
                    const fieldValue = selectedRowsData[i][fieldName]
                    // url icerisindeki {PropertyName} seklindeki anahtarlari secili satirdaki uyusan propertyler ile degistir
                    url = url.replace(`@${fieldName}`, fieldValue)
                  }
                  break // Url cagirmak icin kullanilacak parametreler sadece secili olan ilk satirdan alinir!
                }
                window.open(url, isPwaMode ? '_self' : action.urlTarget)
              } else if (action.dialogName) {
                if (action.dialogParameters) {
                  var dynamicMap = JSON.parse(action.dialogParameters)
                  for (const [key, value] of Object.entries<string>(dynamicMap)) {
                    dynamicMap[key] = value.startsWith('@')
                      ? e.row.data[value.replace('@', '')]
                      : value
                  }
                  dialog.setConfig({
                    component: action.dialogName,
                    props: dynamicMap,
                  })
                }
              } else if (action.onClick) {
                eval(action.onClick)
              }
            },
          },
        }
        items.push(buttonCustom)
      }
    }
    // #endregion

    // batch editing icin kaydet ve geri al butonu
    if (
      grdOpt.editingOptionDto?.allowUpdating &&
      grdOpt.editingOptionDto?.mode == 'batch' &&
      checkPermission(grdOpt.permissionDto?.u)
    ) {
      items.push({
        locateInMenu: 'auto',
        showText: 'inMenu',
        name: 'saveButton',
        options: { hint: translate('::App.SaveChanges') },
      })

      items.push({
        locateInMenu: 'auto',
        showText: 'inMenu',
        name: 'revertButton',
        options: { hint: translate('::App.UndoChanges') },
      })
    }
    // #endregion

    setToolbarData(items)
  }

  useEffect(() => {
    if (!gridDto && !listFormCode) return
    if (!config) return

    getToolbarData()
  }, [gridDto, listFormCode, config])

  return {
    toolbarData,
    toolbarModalData,
    setToolbarModalData,
  }
}

export { useToolbar }
