import { useState } from 'react'
import { Button } from '../Button/index.js'
import { Modal } from '../Modal/index.js'
import { TextInput } from '../TextInput/index.js'
import { SelectInput, SelectInputProps } from '../SelectInput/index.js'
import { NumberInput } from '../NumberInput/index.js'
import { SwitchInput } from '../SwitchInput/index.js'
import { DateInput } from '../DateInput/index.js'
import { Dropdown } from '../Dropdown/index.js'
import { Badge } from '../Badge/index.js'
import { IconButton } from '../IconButton/index.js'
import { Icon, IconProps } from '../Icon/index.js'
import { Text } from '../Text/index.js'
import { colors } from '../../utils/colors.js'
import { radius } from '../../utils/radius.js'
import { styled } from 'inlines'

type StringTagInputProps = {
  variant: 'string'
  value?: string[]
  onChange: (value: string[]) => void
}
type NumberTagInputProps = {
  variant: 'number'
  value?: number[]
  onChange: (value: number[]) => void
}
type BooleanTagInputProps = {
  variant: 'boolean'
  value?: boolean[]
  onChange: (value: boolean[]) => void
}
type EnumTagInputProps = {
  variant: 'enum'
  value?: string[]
  onChange: (value: string[]) => void
  options: SelectInputProps['options']
}
type DateTimeTagInputProps = {
  variant: 'date-time'
  value?: number[]
  onChange: (value: number[]) => void
}

type TagInputProps = (
  | StringTagInputProps
  | NumberTagInputProps
  | BooleanTagInputProps
  | EnumTagInputProps
  | DateTimeTagInputProps
) & {
  disabled?: boolean
  label?: string
  description?: string
  error?: boolean
  placeholder?: string
  placeholderIcon?: IconProps['variant']
}

function TagInput(props: TagInputProps) {
  const value = props.value ?? []
  const [open, setOpen] = useState(false)
  const [editIndex, setEditIndex] = useState<number>()
  const [editValue, setEditValue] = useState<string | number | boolean>()

  return (
    <div
      style={{
        display: 'flex',
        flexDirection: 'column',
        width: '100%',
        gap: 8,
      }}
    >
      <div
        style={{
          width: '100%',
          borderRadius: radius[8],
          border: `1px solid ${colors.neutral20Adjusted}`,
          height: 120,
          verticalAlign: 'center',
          fontSize: 0,
          padding: 8,
          overflowY: 'auto',
          overflowX: 'hidden',
          ...(props.error && {
            border: `1px solid ${colors.red80}`,
          }),
          ...(props.disabled && {
            cursor: 'not-allowed',
            color: colors.neutral20,
            background: colors.neutral5,
            border: `1px solid transparent`,
          }),
        }}
      >
        {Boolean(value?.length) &&
          value.map((val, index) => (
            <styled.div
              onClick={() => {
                if (props.disabled) return
                setEditIndex(index)
                setEditValue(val)
                setOpen(true)
              }}
              style={{
                maxWidth: '100%',
                display: 'inline-flex',
                alignItems: 'center',
                padding: 4,
                borderRadius: radius[4],
                background: colors.neutral10Adjusted,
                cursor: 'not-allowed',
                marginBottom: 8,
                marginRight: 8,
                outline: 'none',
                color: colors.neutral20,
                ...(!props.disabled && {
                  color: colors.neutral80,
                  cursor: 'pointer',
                  '&:hover': {
                    background: colors.neutral20Adjusted,
                  },
                }),
              }}
            >
              <div style={{ width: 2, height: '100%', flexShrink: 0 }} />
              <Text singleLine variant="subtext-medium" color="inherit">
                {props.variant === 'date-time'
                  ? new Date(val as number).toLocaleString()
                  : val.toString()}
              </Text>
              <div style={{ width: 2, height: '100%', flexShrink: 0 }} />
              <styled.div
                onClick={(e) => {
                  if (props.disabled) return
                  e.stopPropagation()
                  props.onChange(value.filter((_, i) => i !== index) as any)
                }}
                style={{
                  flexShrink: 0,
                  display: 'flex',
                  alignItems: 'center',
                  justifyContent: 'center',
                  cursor: 'not-allowed',
                  borderRadius: radius[4],
                  ...(!props.disabled && {
                    cursor: 'pointer',
                    '&:hover': {
                      background: colors.neutral20Adjusted,
                    },
                  }),
                }}
              >
                <Icon variant="close" size="small" />
              </styled.div>
            </styled.div>
          ))}
        {Boolean(!value?.length) && (
          <div
            style={{
              width: '100%',
              height: '100%',
              justifyContent: 'center',
              alignItems: 'center',
              display: 'flex',
              flexDirection: 'column',
              gap: 4,
              color: colors.neutral60,
            }}
          >
            {props.placeholderIcon && <Icon variant={props.placeholderIcon} />}
            {props.placeholder && (
              <Text variant="subtext-medium" color="inherit">
                {props.placeholder}
              </Text>
            )}
          </div>
        )}
      </div>
      <div style={{ display: 'flex', gap: 8 }}>
        <Button
          leadIcon="add"
          variant="border"
          onClick={() => {
            setOpen(true)
          }}
          disabled={props.disabled}
        >
          Add {props.variant}
        </Button>
      </div>
      {open && (
        <Modal
          open
          onOpenChange={() => {
            setOpen(false)
            setEditIndex(undefined)
            setEditValue(undefined)
          }}
          size="small"
        >
          <Modal.Header
            title={
              typeof editIndex === 'number'
                ? `Edit ${props.variant}`
                : `Add ${props.variant}`
            }
          />
          <Modal.Body>
            {props.variant === 'string' && (
              <TextInput value={editValue as string} onChange={setEditValue} />
            )}
            {props.variant === 'number' && (
              <NumberInput
                value={editValue as number}
                onChange={setEditValue}
              />
            )}
            {props.variant === 'boolean' && (
              <SelectInput
                value={editValue as boolean}
                onChange={setEditValue}
                options={[
                  { value: true, label: 'True' },
                  { value: false, label: 'False' },
                ]}
              />
            )}
            {props.variant === 'enum' && (
              <SelectInput
                value={editValue as string}
                onChange={setEditValue}
                options={props.options}
              />
            )}
            {props.variant === 'date-time' && (
              <DateInput
                value={editValue as number}
                onChange={setEditValue}
                variant="date-time"
              />
            )}
          </Modal.Body>
          <Modal.Actions>
            {({ close }) => (
              <>
                <Button variant="border" onClick={close} keyHint="Esc">
                  Cancel
                </Button>
                <Button
                  keyHint="Enter"
                  disabled={typeof editValue === 'undefined'}
                  onClick={() => {
                    if (typeof editIndex !== 'undefined') {
                      props.onChange(
                        value.map(
                          (e, i) => (i === editIndex ? editValue : e) as any,
                        ),
                      )
                    } else {
                      props.onChange([...value, editValue as any])
                    }

                    setOpen(false)
                    setEditValue(undefined)
                    setEditIndex(undefined)
                  }}
                >
                  {editIndex ? 'Save' : 'Add'}
                </Button>
              </>
            )}
          </Modal.Actions>
        </Modal>
      )}
    </div>
  )
}

export { TagInput }
export type { TagInputProps, EnumTagInputProps }
