import Container from '@/components/shared/Container'
import { DX_CLASSNAMES } from '@/constants/app.constant'
import { GridDto, ListFormCustomizationTypeEnum } from '@/proxy/form/models'
import {
  getListFormCustomization,
  postListFormCustomization,
} from '@/services/list-form-customization.service'
import { useLocalization } from '@/utils/hooks/useLocalization'
import Chart, {
  ChartRef,
  CommonSeriesSettings,
  Size,
  Tooltip,
} from 'devextreme-react/chart'
import PivotGrid, {
  FieldChooser,
  FieldPanel,
  HeaderFilter,
  PivotGridRef,
  PivotGridTypes,
  Scrolling,
  Search,
  StateStoring,
} from 'devextreme-react/pivot-grid'
import CustomStore from 'devextreme/data/custom_store'
import PivotGridDataSource, { Field } from 'devextreme/ui/pivot_grid/data_source'
import { useCallback, useEffect, useRef, useState } from 'react'
import { Helmet } from 'react-helmet'
import { GridColumnData } from './GridColumnData'
import {
  addCss,
  addJs,
  controlStyleCondition,
  pivotFieldConvertDataType,
  setGridPanelColor,
} from './Utils'
import { useFilters } from './useFilters'
import WidgetGroup from '@/components/common/WidgetGroup'
import { Button } from '@/components/ui'
import { FaCog, FaTimes, FaUndo } from 'react-icons/fa'
import { usePermission } from '@/utils/hooks/usePermission'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { usePWA } from '@/utils/hooks/usePWA'
import { layoutTypes } from '../admin/listForm/edit/types'
import { useListFormCustomDataSource } from './useListFormCustomDataSource'
import { useListFormColumns } from './useListFormColumns'

interface PivotProps {
  listFormCode: string
  searchParams?: URLSearchParams
  isSubForm?: boolean
  level?: number
  refreshData?: () => Promise<void>
  gridDto?: GridDto
  refreshGridDto: () => Promise<void>
}

const statedGridPanelColor = 'rgba(50, 200, 200, 0.5)' // kullanici tanimli gridState ile islem gormus gridin paneline ait renk

const Pivot = (props: PivotProps) => {
  const { listFormCode, searchParams, isSubForm, level, gridDto } = props
  const { translate } = useLocalization()
  const { checkPermission } = usePermission()
  const isPwaMode = usePWA()

  const gridRef = useRef<PivotGridRef>()
  const chartRef = useRef<ChartRef>(null)
  const refListFormCode = useRef('')

  const [gridDataSource, setGridDataSource] = useState<CustomStore<any, any>>()
  const [columnData, setColumnData] = useState<GridColumnData[]>()

  const { filterToolbarData, ...filterData } = useFilters({
    gridDto,
    gridRef,
    listFormCode,
  })

  const { createSelectDataSource } = useListFormCustomDataSource({ gridRef })
  const { getBandedColumns } = useListFormColumns({
    gridDto,
    listFormCode,
    isSubForm,
    gridRef,
  })

  function onCellPrepared(e: any) {
    const columnFormats = gridDto?.columnFormats
    if (!columnFormats) {
      return
    }

    // satir, hucre yada header vb. kisimlara conditional style uygulamak icin
    for (let indxCol = 0; indxCol < columnFormats.length; indxCol++) {
      const colFormat = columnFormats[indxCol]
      for (let indxStyl = 0; indxStyl < colFormat.columnStylingDto.length; indxStyl++) {
        const colStyle = colFormat.columnStylingDto[indxStyl] // uygulanacak style
        if (e.rowType == colStyle.rowType) {
          // header, filter, data, group, summaries ..her birisine style uygulanabilir
          // style bütün satıra uygulansın olarak seçili ise yada sadece ilgili field üzerinde ise
          if (colStyle.useRow || e.column?.dataField == colFormat.fieldName) {
            if (
              !colStyle.conditionValue ||
              controlStyleCondition(e.data, colFormat.fieldName, colStyle)
            ) {
              // css sınıf ismi var ise uygula
              if (colStyle.cssClassName) {
                e.cellElement.addClass(colStyle.cssClassName)
              }
              // css inline style var ise uygula
              if (colStyle.cssStyles) {
                e.cellElement.attr('style', e.cellElement.attr('style') + ';' + colStyle.cssStyles)
              }
            }
          }
        }
      }
    }
  }

  const clearPivotFilters = () => {
    const grid = gridRef.current?.instance()
    if (!grid) return

    const ds = grid.getDataSource()
    if (ds) {
      const fields = ds.fields()
      fields.forEach((f: any) => {
        f.filterValues = undefined
        f.filterType = undefined
      })
      ds.reload()
    }
  }

  const moveAllFieldsToFilterArea = () => {
    const grid = gridRef.current?.instance()
    if (!grid) return

    const ds = grid.getDataSource()
    if (!ds) return

    const fields = ds.fields()

    fields.forEach((field: any) => {
      field.area = 'filter' // tüm alanları filtre alanına taşı
      field.areaIndex = undefined
    })

    ds.fields(fields)
    ds.reload() // PivotGrid’i yeniden yükle
    grid.repaint() // UI güncelle
  }

  const resetPivotGridState = async () => {
    const grid = gridRef.current?.instance()
    if (grid) {
      // kullaniciya ait kayitli grid state i sil customizationData boşalt silinsin.
      await postListFormCustomization({
        listFormCode: listFormCode,
        customizationType: ListFormCustomizationTypeEnum.GridState,
        filterName: `pivot-${gridRef.current?.instance()?.option('stateStoring')?.storageKey ?? ''}`,
        customizationData: '',
      })

      await props.refreshGridDto()
      clearPivotFilters()
      moveAllFieldsToFilterArea()
    }
  }

  const customSaveState = useCallback(
    (state: any) => {
      return postListFormCustomization({
        listFormCode: listFormCode,
        customizationType: ListFormCustomizationTypeEnum.GridState,
        filterName: `pivot-${gridRef.current?.instance()?.option('stateStoring')?.storageKey ?? ''}`,
        customizationData: JSON.stringify(state),
      }).then(() => {
        setGridPanelColor(statedGridPanelColor)
      })
    },
    [listFormCode],
  )

  const customLoadState = useCallback(
    () => {
      return getListFormCustomization(
        listFormCode,
        ListFormCustomizationTypeEnum.GridState,
        `pivot-${gridRef.current?.instance()?.option('stateStoring')?.storageKey ?? ''}`,
      ).then((response: any) => {
        setGridPanelColor(statedGridPanelColor)
        if (response.data?.length > 0) {
          return JSON.parse(response.data[0].customizationData)
        }
      })
    },
    [listFormCode],
  )

  useEffect(() => {
    if (gridRef?.current) {
      const instance = gridRef?.current?.instance()
      if (instance) {
        instance.option('remoteOperations', false)
        instance.option('dataSource', undefined)
        instance.option('stateStoring', undefined)
      }
    }
  }, [listFormCode])

  useEffect(() => {
    if (!gridDto) {
      return
    }

    // Set js and css
    const grdOpt = gridDto.gridOptions
    if (grdOpt.customJsSources.length) {
      for (const js of grdOpt.customJsSources) {
        addJs(js)
      }
    }
    if (grdOpt.customStyleSources.length) {
      for (const css of grdOpt.customStyleSources) {
        addCss(css)
      }
    }
  }, [gridDto])

  useEffect(() => {
    if (!gridDto) {
      return
    }

    // Set columns
    const cols = getBandedColumns()
    setColumnData(cols?.filter((a) => a.colData?.pivotSettingsDto.isPivot))

    // Set data source
    const dataSource: CustomStore<any, any> = createSelectDataSource(
      gridDto.gridOptions,
      listFormCode,
      searchParams,
      layoutTypes.pivot,
      cols,
    )

    setGridDataSource(dataSource)
  }, [gridDto, searchParams])

  useEffect(() => {
    refListFormCode.current = listFormCode
    if (!gridRef?.current) {
      return
    }

    const fields: any = columnData?.map((b) => {
      return {
        dataField: b.dataField,
        caption: b.caption,
        dataType: pivotFieldConvertDataType(b.dataType),
        area: b.colData?.pivotSettingsDto.area,
        format: b.colData?.pivotSettingsDto.format,
        summaryType: b.colData?.pivotSettingsDto.summaryType,
        groupInterval: b.colData?.pivotSettingsDto.groupInterval,
        sortOrder: b.colData?.pivotSettingsDto.sortOrder,
        expanded: b.colData?.pivotSettingsDto.expanded,
        wordWrapEnabled: b.colData?.pivotSettingsDto.wordWrapEnabled,
        visible: true,
        width: b.width,
      } as Field
    })

    PivotGridDataSource
    const dataSource: PivotGridTypes.Properties['dataSource'] = {
      remoteOperations: true,
      store: gridDataSource,
      fields,
    }

    const instance = gridRef?.current?.instance()
    if (instance) {
      instance.option('dataSource', dataSource)
      instance.option('state', null)
    }

    //chart Integration
    if (gridRef?.current && chartRef?.current) {
      const pivotInstance = gridRef?.current?.instance()
      const chartInstance = chartRef?.current?.instance()
      if (pivotInstance && chartInstance) {
        pivotInstance.bindChart(chartInstance, {
          dataFieldsDisplayMode: 'splitPanes',
          alternateDataFields: false,
        })
      }
    }
  }, [columnData])

  return (
    <>
      <WidgetGroup widgetGroups={gridDto?.widgets ?? []} />

      <Container className={DX_CLASSNAMES}>
        {!isSubForm && (
          <Helmet
            titleTemplate="%s | Erp Platform"
            title={translate('::' + gridDto?.gridOptions.title)}
            defaultTitle="Erp Platform"
          ></Helmet>
        )}
        {gridDto && columnData && (
          <div className="p-1 bg-white dark:bg-neutral-800 dark:border-neutral-700 ">
            <div className="flex justify-end items-center">
              <div className="relative pb-1 flex gap-1 border-b-1">

                <Button
                  size="xs"
                  variant={'default'}
                  className="text-sm flex items-center gap-1"
                  onClick={clearPivotFilters}
                  title="Remove Filter"
                >
                  <FaTimes className="w-3 h-3" /> Remove Filters
                </Button>

                <Button
                  size="xs"
                  variant={'default'}
                  className="text-sm flex items-center gap-1"
                  onClick={resetPivotGridState}
                  title="Reset Grid State"
                >
                  <FaUndo className="w-3 h-3" /> Reset Grid State
                </Button>

                {checkPermission(gridDto?.gridOptions.permissionDto.u) && (
                  <Button
                    size="xs"
                    variant={'default'}
                    className="text-sm"
                    onClick={() => {
                      window.open(
                        ROUTES_ENUM.protected.saas.listFormManagement.edit.replace(
                          ':listFormCode',
                          listFormCode,
                        ),
                        isPwaMode ? '_self' : '_blank',
                      )
                    }}
                    title="Form Manager"
                  >
                    <FaCog className="w-3 h-3" />
                  </Button>
                )}
              </div>
            </div>
            {gridDto.gridOptions.pivotOptionDto.showChart && (
              <Chart ref={chartRef as any}>
                <Size height={gridDto.gridOptions.pivotOptionDto.chartHeight} />
                <Tooltip enabled={true}></Tooltip>
                <CommonSeriesSettings
                  type={gridDto.gridOptions.pivotOptionDto.chartCommonSeriesType}
                />
              </Chart>
            )}

            <div className="dx-datagrid-header-panel h-1"></div>

            <PivotGrid
              ref={gridRef as any}
              id={'Pivot-' + listFormCode}
              allowFiltering={gridDto.gridOptions.filterRowDto.visible}
              allowSorting={gridDto.gridOptions.sortMode !== 'none'}
              allowSortingBySummary={gridDto.gridOptions.sortMode !== 'none'}
              height={gridDto.gridOptions.height || '100%'}
              width={gridDto.gridOptions.width || '100%'}
              showBorders={gridDto.gridOptions.columnOptionDto?.showBorders}
              rtlEnabled={gridDto.gridOptions.columnOptionDto?.rtlEnabled}
              hoverStateEnabled={gridDto.gridOptions.columnOptionDto?.hoverStateEnabled}
              onCellPrepared={onCellPrepared}
            >
              <HeaderFilter
                allowSelectAll={gridDto.gridOptions.selectionDto.allowSelectAll}
                width={gridDto.gridOptions.headerFilterDto.width}
                height={gridDto.gridOptions.headerFilterDto.height}
              >
                <Search
                  enabled={gridDto.gridOptions.headerFilterDto.allowSearch}
                  timeout={gridDto.gridOptions.headerFilterDto.searchTimeout}
                ></Search>
              </HeaderFilter>
              <FieldPanel
                allowFieldDragging={gridDto.gridOptions.pivotOptionDto.allowFieldDragging}
                visible={gridDto.gridOptions.pivotOptionDto.showFieldPanel}
                showDataFields={gridDto.gridOptions.pivotOptionDto.showDataFields}
                showColumnFields={gridDto.gridOptions.pivotOptionDto.showColumnFields}
                showRowFields={gridDto.gridOptions.pivotOptionDto.showRowFields}
                showFilterFields={gridDto.gridOptions.pivotOptionDto.showFilterFields}
              />
              <FieldChooser
                enabled={gridDto.gridOptions.pivotOptionDto.columnChooserEnabled}
                height={500}
              />
              <StateStoring
                enabled={gridDto?.gridOptions.stateStoringDto?.enabled}
                type={gridDto?.gridOptions.stateStoringDto?.type}
                savingTimeout={gridDto?.gridOptions.stateStoringDto?.savingTimeout}
                storageKey={gridDto?.gridOptions.stateStoringDto?.storageKey}
                customSave={
                  gridDto?.gridOptions.stateStoringDto?.enabled &&
                  gridDto?.gridOptions.stateStoringDto?.type === 'custom'
                    ? customSaveState
                    : undefined
                }
                customLoad={
                  gridDto?.gridOptions.stateStoringDto?.enabled &&
                  gridDto?.gridOptions.stateStoringDto?.type === 'custom'
                    ? customLoadState
                    : undefined
                }
              />
              <Scrolling mode={gridDto.gridOptions.pagerOptionDto.scrollingMode} />
            </PivotGrid>
          </div>
        )}
      </Container>
    </>
  )
}

export default Pivot
