import { Percent } from '@uniswap/sdk-core'
import { FeeAmount } from '@uniswap/v3-sdk'
import { StyledPercentInput } from 'components/PercentInput'
import ms from 'ms'
import { useCreatePositionContext } from 'pages/Pool/Positions/create/CreatePositionContext'
import { NumericalInputMimic, NumericalInputSymbolContainer } from 'pages/Swap/common/shared'
import { useEffect, useState } from 'react'
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
import styled from 'styled-components'
import { ClickableTamaguiStyle, CloseIcon } from 'theme/components'
import { Button, Flex, Input, Text } from 'ui/src'
import { BackArrow } from 'ui/src/components/icons/BackArrow'
import { CheckCircleFilled } from 'ui/src/components/icons/CheckCircleFilled'
import { Plus } from 'ui/src/components/icons/Plus'
import { Search } from 'ui/src/components/icons/Search'
import { Modal } from 'uniswap/src/components/modals/Modal'
import { ModalName } from 'uniswap/src/features/telemetry/constants'
import { useTranslation } from 'uniswap/src/i18n'
import useResizeObserver from 'use-resize-observer'
import { useFormatter } from 'utils/formatNumbers'

const FeeTierPercentInput = styled(StyledPercentInput)`
  text-align: end;
  justify-content: flex-end;
`

export function FeeTierSearchModal() {
  const {
    positionState: { fee: selectedFee },
    setPositionState,
    feeTierSearchModalOpen,
    setFeeTierSearchModalOpen,
  } = useCreatePositionContext()
  const onClose = () => {
    setCreateFeeValue('')
    setCreateModeEnabled(false)
    setFeeTierSearchModalOpen(false)
  }
  const { t } = useTranslation()
  const [searchValue, setSearchValue] = useState('')
  const [createFeeValue, setCreateFeeValue] = useState('')
  const [createModeEnabled, setCreateModeEnabled] = useState(false)
  const { formatPercent } = useFormatter()
  const [autoDecrementing, setAutoDecrementing] = useState(false)
  const [autoIncrementing, setAutoIncrementing] = useState(false)
  const [holdDuration, setHoldDuration] = useState(0)
  const hiddenObserver = useResizeObserver<HTMLElement>()

  useEffect(() => {
    let interval: NodeJS.Timeout
    let holdTimeout: NodeJS.Timeout
    const baseInterval = 100
    let currentInterval = baseInterval

    if (autoDecrementing || autoIncrementing) {
      holdTimeout = setTimeout(() => {
        setHoldDuration((prev) => prev + 1)
      }, ms('1s'))

      if (holdDuration >= 2) {
        currentInterval = baseInterval / 2
      }
      if (holdDuration >= 4) {
        currentInterval = baseInterval / 4
      }
      if (holdDuration >= 6) {
        currentInterval = baseInterval / 8
      }

      interval = setInterval(() => {
        setCreateFeeValue((prev) => {
          let newValue = parseFloat(prev)
          if (autoDecrementing) {
            newValue -= 0.01
            if (newValue < 0) {
              return '0'
            }
          } else if (autoIncrementing) {
            newValue += 0.01
            if (newValue > 100) {
              return '100'
            }
          }
          return newValue.toFixed(2)
        })
      }, currentInterval)

      return () => {
        clearInterval(interval)
        clearTimeout(holdTimeout)
      }
    }

    return () => {
      clearInterval(interval)
      clearTimeout(holdTimeout)
      setHoldDuration(0) // Reset hold duration on release
    }
  }, [autoDecrementing, autoIncrementing, holdDuration])

  // TODO(WEB-4920): use tiers from Positions API for this specific pool, not presets.
  const feeTiers = [FeeAmount.LOWEST, FeeAmount.LOW, FeeAmount.MEDIUM, FeeAmount.HIGH]

  return (
    <Modal name={ModalName.FeeTierSearch} onClose={onClose} isDismissible isModalOpen={feeTierSearchModalOpen}>
      <Flex width="100%" gap="$gap20">
        <Flex row justifyContent="space-between" alignItems="center" gap="$spacing4" width="100%">
          {createModeEnabled && (
            <Flex {...ClickableTamaguiStyle} onPress={() => setCreateModeEnabled(false)}>
              <BackArrow size="$icon.24" />
            </Flex>
          )}
          <Text variant="body2" flexGrow={1} textAlign="center" pl={createModeEnabled ? 0 : 24}>
            {createModeEnabled ? t('fee.tier.create') : t('fee.tier.select')}
          </Text>
          <CloseIcon data-testid="LiquidityModalHeader-close" onClick={onClose} size={24} />
        </Flex>

        {createModeEnabled ? (
          <Flex gap="$gap20">
            <Text variant="body2" color="$neutral2" textAlign="center">
              {t('fee.tier.create.description')}
            </Text>
            <Flex row alignItems="center" gap="$spacing28" px="$spacing20">
              <Flex
                justifyContent="center"
                alignItems="center"
                backgroundColor="$surface3"
                borderRadius="$roundedFull"
                userSelect="none"
                height="$spacing36"
                width="$spacing36"
                onPressIn={() => {
                  setAutoDecrementing(true)
                }}
                onPressOut={() => {
                  setAutoDecrementing(false)
                }}
                onPress={() => {
                  setCreateFeeValue((prev) => {
                    if (!prev || prev === '') {
                      return '0'
                    }
                    const newValue = parseFloat(prev) - 0.01
                    if (newValue < 0) {
                      return '0'
                    }
                    return newValue.toFixed(2)
                  })
                }}
                {...ClickableTamaguiStyle}
              >
                <Text variant="heading3">-</Text>
              </Flex>
              <Flex grow justifyContent="flex-end">
                <Flex row maxWidth="100%" alignItems="center">
                  <FeeTierPercentInput
                    value={createFeeValue}
                    onUserInput={(input) => {
                      if (parseInt(input) > 100) {
                        setCreateFeeValue('100')
                      } else {
                        setCreateFeeValue(input)
                      }
                    }}
                    placeholder="0"
                    maxDecimals={2}
                    maxLength={4}
                    $width={createFeeValue && hiddenObserver.width ? hiddenObserver.width + 1 : undefined}
                  />
                  <NumericalInputSymbolContainer showPlaceholder={!createFeeValue}>%</NumericalInputSymbolContainer>
                  <NumericalInputMimic ref={hiddenObserver.ref}>{createFeeValue}</NumericalInputMimic>
                </Flex>
              </Flex>
              <Flex
                justifyContent="center"
                alignItems="center"
                backgroundColor="$surface3"
                borderRadius="$roundedFull"
                userSelect="none"
                height={36}
                width={36}
                onPressIn={() => {
                  setAutoIncrementing(true)
                }}
                onPressOut={() => {
                  setAutoIncrementing(false)
                }}
                onPress={() => {
                  setCreateFeeValue((prev) => {
                    if (!prev || prev === '') {
                      return '0.01'
                    }
                    const newValue = parseFloat(prev) + 0.01
                    if (newValue > 100) {
                      return '100'
                    }
                    return newValue.toFixed(2)
                  })
                }}
                {...ClickableTamaguiStyle}
              >
                <Text variant="heading3">+</Text>
              </Flex>
            </Flex>
            {/* TODO(WEB-4920): search existing fee tiers for a match and optionally show this, with real TVL value */}
            {/* <Text variant="body2" color="$neutral2" textAlign="center">
              {t('fee.tier.alreadyExists', { formattedTVL: '$289.6K' })}
            </Text> */}
            {/* TODO(WEB-4920): search existing fee tiers for close matches and optionally similar list */}

            <Button
              flex={1}
              py="$spacing16"
              px="$spacing20"
              backgroundColor="$accent3"
              hoverStyle={{
                backgroundColor: undefined,
                opacity: 0.8,
              }}
              pressStyle={{
                backgroundColor: undefined,
              }}
              disabled={!createFeeValue || createFeeValue === '0' || createFeeValue === ''}
              onPress={() => {
                const feeBips = Math.round(parseFloat(createFeeValue) * 100)
                setPositionState((prevState) => ({ ...prevState, fee: feeBips }))
                onClose()
              }}
            >
              {/* TODO(WEB-4920): change this button label to "Select existing tier" if the value matches an existing tier. */}
              <Text variant="buttonLabel2" color="$surface1">
                {t('fee.tier.create.button')}
              </Text>
            </Button>
          </Flex>
        ) : (
          <>
            <Flex row py="$padding12" px="$padding8" backgroundColor="$surface2" borderRadius="$rounded24">
              <Search size={20} color="$neutral2" />
              <Input
                width="100%"
                height="100%"
                fontWeight="$book"
                backgroundColor="$transparent"
                placeholder={t('fee.tier.search.short')}
                placeholderTextColor="$neutral2"
                onChange={(event: any) => {
                  setSearchValue(event.target.value)
                }}
                value={searchValue}
              />
            </Flex>
            <Flex width="100%" gap="$gap4">
              {/* TODO(WEB-4920): filter fee tiers based on search term */}
              {feeTiers.map((feeTier) => (
                <Flex
                  row
                  alignItems="center"
                  gap="$spacing24"
                  key={feeTier}
                  py="$padding12"
                  px="$padding16"
                  justifyContent="space-between"
                  {...ClickableTamaguiStyle}
                  onPress={() => {
                    setPositionState((prevState) => ({ ...prevState, fee: feeTier }))
                    onClose()
                  }}
                >
                  <Flex>
                    <Text variant="subheading2">{formatPercent(new Percent(feeTier, 1000000))}</Text>
                    <Flex row gap="$gap12" alignItems="center">
                      {/* TODO(WEB-4920): use real data from positions API */}
                      <Text variant="body3" color="$neutral2">
                        $289.6K TVL
                      </Text>
                      <Text variant="body3" color="$neutral2">
                        {t('fee.tier.percent.select', { percentage: 4 })}
                      </Text>
                    </Flex>
                  </Flex>
                  {feeTier === selectedFee && <CheckCircleFilled size="$icon.24" color="$accent3" />}
                </Flex>
              ))}
            </Flex>
            <Flex py="$padding12" gap="$gap12" alignItems="center">
              <Text variant="body3" color="$neutral2">
                {t('fee.tier.missing.description')}
              </Text>
              <Button
                py="$spacing8"
                px="$spacing12"
                gap="$gap4"
                theme="secondary"
                size="small"
                icon={<Plus size={16} color="$neutral1" />}
                onPress={() => setCreateModeEnabled(true)}
              >
                {t('fee.tier.create.button')}
              </Button>
            </Flex>
          </>
        )}
      </Flex>
    </Modal>
  )
}
