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

import Button from '../Button/Button'
import { hasValue } from '../../services/HelperServiceTyped'
import StandardTable from '../TableComponents/StandardTable'
import Switch from '../Switch/Switch'
import { ToggleProviderContext } from '../ToggleProvider/ToggleProvider'
import { c } from '../../translations/LibraryTranslationService'
import { getToggleFromCookie } from '../../hooks/useToggle/useToggle'

type DataItem = {
  key: string
  enabled: boolean
}

type ToggleTableProps = {
  data: Array<DataItem>
  rerenderCallout: CalloutType
  searchTerm?: string
  setSearchTerm?: (term: string) => void
}

type CalloutType = React.Dispatch<React.SetStateAction<Record<string, unknown>>>

const ToggleTable = ({
  data,
  rerenderCallout,
  searchTerm,
  setSearchTerm,
}: ToggleTableProps): React.JSX.Element => {
  const { toggles } = useContext(ToggleProviderContext)

  const checkEnvDifference = (toggleKey: string) => {
    const isFeatureOn = toggles?.some(
      (toggle) => toggle.key === toggleKey && toggle.enabled,
    )

    return localStorage.getItem(toggleKey) &&
      (localStorage.getItem(toggleKey) === 'true') !== isFeatureOn
      ? 'bgc-light-orange'
      : ''
  }

  const tableConfig = [
    {
      label: c('toggle'),
      name: 'key',
      noSort: true,
      mainColumn: true,
      cell: {
        children: (d: DataItem) => {
          return <div style={{ wordBreak: 'break-all' }}>{d.key}</div>
        },
        className: (d: DataItem) => checkEnvDifference(d.key),
      },
    },
    {
      label: '',
      name: '',
      noSort: true,
      cell: {
        children: (d: DataItem) => {
          const isFeatureOn = d.enabled
          const cookieToggleOn = hasValue(getToggleFromCookie(d.key))
            ? getToggleFromCookie(d.key) === 'true'
            : isFeatureOn
          return (
            <div className='flex justify-end'>
              <ToggleValue
                value={cookieToggleOn}
                rerenderCallout={rerenderCallout}
                name={d.key}
              />
            </div>
          )
        },
        className: (d: DataItem) => checkEnvDifference(d.key),
      },
    },
  ]

  type DataType = {
    application?: string
    key: string
    enabled: boolean
  }

  const tableGroupConfig = useCallback(
    (
      name:
        | 'Predict'
        | 'Shelf'
        | 'Library'
        | 'Toggle'
        | 'Connect'
        | 'Admin'
        | 'Amplifi',
    ) => {
      return {
        groupHeader: name,
        check: (data: DataType): boolean => data.application === name,
        groupAccordion: {
          isCollapsed: false,
          groupKey: name.toLowerCase(),
        },
      }
    },
    [],
  )

  const tableGroups = useMemo(
    () => [
      tableGroupConfig('Admin'),
      tableGroupConfig('Connect'),
      tableGroupConfig('Predict'),
      tableGroupConfig('Shelf'),
      tableGroupConfig('Toggle'),
      tableGroupConfig('Amplifi'),
      // We want the Library toggles to appear as the last group in every application.
      tableGroupConfig('Library'),
    ],
    [tableGroupConfig],
  )

  return (
    <StandardTable
      data={data}
      config={tableConfig}
      dataKey='key'
      hasData={data?.length > 0}
      loading={false}
      noSort
      tableId={'devtools-toggles'}
      noDataFields={{
        primaryText: c('noTogglesFound'),
        secondaryText: c('updateSearchField'),
      }}
      successStatus={true}
      tableHeaderProps={{
        header: {
          name: c('toggles'),
          value: data.length || 0,
        },
        search: {
          placeholder: c('toggleKey'),
          value: searchTerm ?? '',
          onChange: setSearchTerm ?? (() => {}),
        },
        rightSectionChildren: (
          <Button
            onClick={() => {
              window.location.reload()
            }}
          >
            {c('reload')}
          </Button>
        ),
      }}
      customHeight='auto'
      customWidth='100%'
      showGroups
      groups={tableGroups}
    />
  )
}

export default ToggleTable

const ToggleValue = ({
  name,
  value,
  rerenderCallout,
}: {
  name: string
  value: boolean
  rerenderCallout: CalloutType
}): React.JSX.Element => {
  const [checked, setChecked] = useState(value)
  const { setToggleOverride } = useContext(ToggleProviderContext)

  const callout = (val: boolean) => {
    setChecked(val)
    setToggleOverride?.(name, val)
    // This will be removed in the future
    localStorage.setItem(name, val.toString())
    rerenderCallout({})
  }

  return <Switch checked={checked} callout={callout} />
}
