import Container from '@/components/shared/Container'
import { Dialog, Notification, toast } from '@/components/ui'
import { DX_CLASSNAMES } from '@/constants/app.constant'
import { GridDto } from '@/proxy/form/models'
import { useLocalization } from '@/utils/hooks/useLocalization'
import useResponsive from '@/utils/hooks/useResponsive'
import Gantt, {
  Column,
  Editing,
  GanttRef,
  Item,
  Tasks,
  Toolbar,
  Validation,
} from 'devextreme-react/gantt'
import DataSource from 'devextreme/data/data_source'
import { useCallback, useEffect, useRef, useState } from 'react'
import { Helmet } from 'react-helmet'
import { getList } from '@/services/form.service'
import { useListFormCustomDataSource } from './useListFormCustomDataSource'
import { useToolbar } from './useToolbar'
import { useFilters } from './useFilters'
import { addCss, addJs } from './Utils'
import { layoutTypes } from '../admin/listForm/edit/types'
import WidgetGroup from '@/components/ui/Widget/WidgetGroup'

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

const GanttView = (props: GanttViewProps) => {
  const { listFormCode, searchParams, isSubForm, level, gridDto: extGridDto } = props
  const { translate } = useLocalization()
  const { smaller } = useResponsive()

  const ganttRef = useRef<GanttRef>()
  const refListFormCode = useRef('')
  const widgetGroupRef = useRef<HTMLDivElement>(null)

  const [ganttDataSource, setGanttDataSource] = useState<DataSource<any, any>>()
  const [gridDto, setGridDto] = useState<GridDto>()
  const [widgetGroupHeight, setWidgetGroupHeight] = useState(0)

  useEffect(() => {
    const initializeGantt = async () => {
      const response = await getList({ listFormCode })
      setGridDto(response.data)
    }

    if (extGridDto === undefined) {
      initializeGantt()
    } else {
      setGridDto(extGridDto)
    }
  }, [listFormCode, extGridDto])

  const layout = layoutTypes.gantt || 'gantt'
  const { toolbarData, toolbarModalData, setToolbarModalData } = useToolbar({
    gridDto,
    listFormCode,
    getSelectedRowKeys: () => Promise.resolve([]),
    getSelectedRowsData: () => [],
    refreshData,
    getFilter: () => undefined,
    layout,
  })

  const { filterToolbarData, ...filterData } = useFilters({
    gridDto,
    gridRef: ganttRef as any,
    listFormCode,
  })

  const { createSelectDataSource } = useListFormCustomDataSource({ gridRef: ganttRef as any })

  function refreshData() {
    ganttRef.current?.instance()?.refresh()
  }

  function onTaskInserted() {
    props.refreshData?.()
  }

  function onTaskUpdated() {
    props.refreshData?.()
  }

  function onTaskDeleted() {
    props.refreshData?.()
  }

  useEffect(() => {
    if (ganttRef?.current) {
      const instance = ganttRef?.current?.instance()
      if (instance) {
        instance.option('dataSource', undefined)
      }
    }

    if (refListFormCode.current !== listFormCode) {
      // Reset state if needed
    }
  }, [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

    const customStore = createSelectDataSource(
      gridDto.gridOptions,
      listFormCode,
      searchParams,
      layout,
      undefined,
    )

    // Gantt için DataSource wrapper'ı oluştur
    const dataSource = new DataSource({
      store: customStore,
      reshapeOnPush: true,
    })

    setGanttDataSource(dataSource)
  }, [gridDto, searchParams, createSelectDataSource])

  useEffect(() => {
    refListFormCode.current = listFormCode
  }, [listFormCode])

  // WidgetGroup yüksekliğini hesapla
  useEffect(() => {
    const calculateWidgetHeight = () => {
      if (widgetGroupRef.current) {
        const height = widgetGroupRef.current.offsetHeight
        setWidgetGroupHeight(height)
      }
    }

    calculateWidgetHeight()

    const resizeObserver = new ResizeObserver(calculateWidgetHeight)
    if (widgetGroupRef.current) {
      resizeObserver.observe(widgetGroupRef.current)
    }

    return () => {
      resizeObserver.disconnect()
    }
  }, [gridDto?.widgets])

  // Gantt için sütunları oluştur
  const getGanttColumns = useCallback(() => {
    if (!gridDto?.columnFormats) return []

    return gridDto.columnFormats
      .filter((col) => col.canRead && col.isActive && col.visible)
      .map((col) => {
        const column: any = {
          dataField: col.fieldName,
          caption: col.captionName ? translate('::' + col.captionName) : col.fieldName,
          width: col.width > 0 ? col.width : undefined,
          alignment: col.alignment,
          format: col.format,
        }

        return column
      })
  }, [gridDto, translate])

  const ganttColumns = getGanttColumns()

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

      <Container className={DX_CLASSNAMES}>
        {!isSubForm && (
          <Helmet
            titleTemplate="%s | Erp Platform"
            title={translate('::' + gridDto?.gridOptions.title)}
            defaultTitle="Erp Platform"
          >
            <link rel="stylesheet" href="/css/gantt/dx-gantt.min.css" />
          </Helmet>
        )}
        {!gridDto && <div className="p-4">Loading gantt configuration...</div>}
        {gridDto && !ganttDataSource && <div className="p-4">Loading data source...</div>}
        {gridDto && ganttDataSource && (
          <>
            <div className="p-1">
              <Gantt
                ref={ganttRef as any}
                key={`Gantt-${listFormCode}-${ganttDataSource ? 'loaded' : 'loading'}`}
                id={'Gantt-' + listFormCode}
                taskListWidth={500}
                scaleType="weeks"
                rootValue={
                  gridDto.gridOptions.treeOptionDto?.rootValue === '' ||
                  gridDto.gridOptions.treeOptionDto?.rootValue === undefined
                    ? null
                    : gridDto.gridOptions.treeOptionDto?.rootValue
                }
                height={
                  gridDto.gridOptions.height > 0
                    ? gridDto.gridOptions.height
                    : gridDto.gridOptions.fullHeight
                      ? `calc(100vh - ${170 + widgetGroupHeight}px)`
                      : 700
                }
                showResources={true}
                showDependencies={true}
                onTaskInserted={onTaskInserted}
                onTaskUpdated={onTaskUpdated}
                onTaskDeleted={onTaskDeleted}
              >
                <Tasks
                  dataSource={ganttDataSource}
                  keyExpr={gridDto.gridOptions.treeOptionDto?.keyExpr}
                  parentIdExpr={gridDto.gridOptions.treeOptionDto?.parentIdExpr}
                  titleExpr={gridDto.gridOptions.treeOptionDto?.titleExpr}
                  startExpr={gridDto.gridOptions.treeOptionDto?.startExpr}
                  endExpr={gridDto.gridOptions.treeOptionDto?.endExpr}
                  progressExpr={gridDto.gridOptions.treeOptionDto?.progressExpr}
                />

                <Toolbar>
                  <Item name="undo" />
                  <Item name="redo" />
                  <Item name="separator" />
                  <Item name="collapseAll" />
                  <Item name="expandAll" />
                  <Item name="separator" />
                  <Item name="addTask" />
                  <Item name="deleteTask" />
                  <Item name="separator" />
                  <Item name="zoomIn" />
                  <Item name="zoomOut" />
                </Toolbar>

                <Editing
                  enabled={gridDto.gridOptions.editingOptionDto?.allowUpdating}
                  allowTaskAdding={gridDto.gridOptions.editingOptionDto?.allowAdding}
                  allowTaskUpdating={gridDto.gridOptions.editingOptionDto?.allowUpdating}
                  allowTaskDeleting={gridDto.gridOptions.editingOptionDto?.allowDeleting}
                  allowDependencyAdding={false}
                  allowDependencyDeleting={false}
                  allowResourceAdding={false}
                  allowResourceDeleting={false}
                />

                <Validation autoUpdateParentTasks={true} />

                {ganttColumns.map((col: any) => (
                  <Column
                    key={col.dataField}
                    dataField={col.dataField}
                    caption={col.caption}
                    width={col.width}
                  />
                ))}
              </Gantt>
            </div>
          </>
        )}

        <Dialog
          isOpen={toolbarModalData?.open || false}
          onClose={() => setToolbarModalData(undefined)}
          onRequestClose={() => setToolbarModalData(undefined)}
        >
          {toolbarModalData?.content}
        </Dialog>
      </Container>
    </>
  )
}

export default GanttView
