import { Col, Form, Input, Row, Switch } from 'antd'
import classNames from 'classnames'
import LabelTooltip from 'components/LabelTooltip/LabelTooltip'
import { Paragraph, Text } from 'components/Typography'
import { DATA_CAPTURE_FIELD_TITLE } from 'constants/data-capture'
import { DataCaptureFieldItem } from 'models/talent/talent-profile-module.model'
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { DraggableProvidedDragHandleProps } from 'react-beautiful-dnd'
import DragDropButton from '../Button/DragDropButton'
import { Icon } from '../Icon'
import CaptureOptionList from 'components/CaptureOptionList'
import CaptureLegals from 'components/CaptureLegals'
import './CaptureFieldItem.scss'

import { DataCaptureFieldType, LegalsType } from '@komi-app/shared-types'

interface CaptureFieldItemProps {
  type: DataCaptureFieldType
  defaultValue?: string
  className?: string
  title?: string
  name?: string
  value?: string
  edit?: boolean
  isDisableDragged?: boolean
  disableDrag?: boolean
  required?: boolean
  onSetItem?: (value: any) => void
  onRemoveItem?: () => void
  onClick?: () => void
  dragHandleProps?: DraggableProvidedDragHandleProps
  field: DataCaptureFieldItem
  isActive?: boolean
}

const CaptureFieldItem = ({
  className,
  name,
  edit,
  dragHandleProps,
  onSetItem,
  defaultValue = '',
  isDisableDragged,
  onRemoveItem,
  required = false,
  type,
  field,
  isActive,
  onClick
}: CaptureFieldItemProps) => {
  const ref = useRef<Input>(null)
  const [legalsType, setLegalsType] = useState(LegalsType.DEFAULT_UNCHECK)
  const [legalText, setLegalText] = useState<string>(field?.text || '')
  const [value, setValue] = useState(defaultValue)
  const isHasItem = useMemo(
    () =>
      [
        DataCaptureFieldType.SELECT_MULTIPLE,
        DataCaptureFieldType.SELECT_SINGLE,
        DataCaptureFieldType.LEGALS
      ].includes(type),
    [type]
  )

  const handleChange = useCallback(event => {
    const text = event.target.value
    setValue(text)
  }, [])
  const handleBlur = useCallback(() => {
    if (!value.length) {
      return
    }
    onSetItem?.({ edit: false, label: value })
  }, [value, onSetItem])
  const handleKeyDown = useCallback(
    event => {
      if (event.key === 'Enter') {
        event.preventDefault()
        if (!value.length) {
          return
        }
        onSetItem?.({ edit: false, label: value })
      }
    },
    [onSetItem, value]
  )
  const handleEnableEdit = useCallback(() => {
    onSetItem?.({ edit: true })
    setTimeout(() => {
      ref?.current?.focus()
    }, 200)
  }, [ref, onSetItem])
  useEffect(() => {
    if (defaultValue?.length) {
      setValue(defaultValue)
    }
  }, [defaultValue])

  useEffect(() => {
    if (field.type === DataCaptureFieldType.LEGALS) {
      setLegalsType(field?.legalType || LegalsType.DEFAULT_UNCHECK)
    }
  }, [field.type])

  const handleChangeRequired = useCallback(
    (checked: boolean) => {
      onSetItem?.({ required: checked })
    },
    [onSetItem]
  )

  const handleAddOption = useCallback(() => {
    const currentOptions = field?.options || []
    let checked = false
    if (
      type === DataCaptureFieldType.LEGALS &&
      legalsType === LegalsType.DEFAULT_CHECK
    ) {
      checked = true
    }
    const newOption = [
      {
        label: `Option ${(field.options?.length || 0) + 1}`,
        order: field.options?.length,
        edit: false,
        checked
      }
    ]
    const options = [...currentOptions, ...newOption]
    onSetItem?.({
      options
    })
  }, [onSetItem, field, legalsType, type])
  const handleChangeLegalsType = useCallback(
    (value: LegalsType) => {
      setLegalsType(value)
      onSetItem?.({
        legalType: value,
        options:
          field.options?.map(option => {
            return { ...option, checked: value === LegalsType.DEFAULT_CHECK }
          }) || []
      })
    },
    [onSetItem, setLegalsType]
  )

  const handleChangeLegalText = useCallback(
    (text: string) => {
      setLegalText(text)
      onSetItem?.({ text })
    },
    [setLegalText, onSetItem]
  )

  useEffect(() => {
    if (field?.text) {
      setLegalText(field.text)
    }
  }, [field?.text])

  const renderOptions = () => {
    switch (type) {
      case DataCaptureFieldType.SELECT_MULTIPLE:
        return (
          <div className="p__x--16 p__t--16 p__b--20 capture-field-option-wrapper">
            <CaptureOptionList
              multiple
              options={field?.options || []}
              onSetItem={onSetItem}
              onAddOption={handleAddOption}
            />
          </div>
        )
      case DataCaptureFieldType.SELECT_SINGLE:
        return (
          <div className="p__x--16 p__t--16 p__b--20 capture-field-option-wrapper">
            <CaptureOptionList
              multiple={false}
              options={field?.options || []}
              onSetItem={onSetItem}
              onAddOption={handleAddOption}
            />
          </div>
        )

      case DataCaptureFieldType.LEGALS:
        return (
          <CaptureLegals
            onAddOption={handleAddOption}
            options={field?.options || []}
            onSetItem={onSetItem}
            type={legalsType}
            setType={handleChangeLegalsType}
            text={legalText || ''}
            onChangeText={handleChangeLegalText}
            name={name}
          />
        )

      default:
        break
    }
  }

  return (
    <div
      className={classNames('capture-field-item-wrapper', {
        active: isActive
      })}
      onClick={onClick}
    >
      <div
        className={classNames('capture-field-item', className, {
          'has-item': isHasItem
        })}
      >
        <Row align="middle">
          <Col flex="1">
            {!edit && (
              <div onClick={handleEnableEdit} className={'cursor-pointer'}>
                <LabelTooltip
                  label={value}
                  maxLength={35}
                  preset="semibold16"
                />
              </div>
            )}
            {edit && (
              <Form.Item
                rules={[
                  {
                    required: true,
                    message: 'Please enter this field'
                  }
                ]}
                name={name}
                className={classNames('m__t--0 m__b--0', !edit && 'd--none')}
              >
                <Input
                  ref={ref}
                  autoFocus
                  onBlur={handleBlur}
                  onChange={handleChange}
                  onKeyDown={handleKeyDown}
                  placeholder="Enter field name"
                  maxLength={35}
                />
              </Form.Item>
            )}
            {edit ? (
              <Text
                preset="regular12"
                className="m__t--4 text--default opacity--50"
              >
                {`${value.length}/35 characters`}
              </Text>
            ) : (
              <Paragraph
                className="opacity--60 m__t--4 leading-16"
                preset="regular12"
              >
                {DATA_CAPTURE_FIELD_TITLE[type]}
              </Paragraph>
            )}
          </Col>
          <Col className="m__r--24">
            <Text className="opacity--80 m__r--8" preset="regular12">
              Required
            </Text>
            <Switch checked={required} onChange={handleChangeRequired} />
          </Col>
          <Col>
            <Row gutter={16} align="middle" wrap={false}>
              <Col onClick={onRemoveItem} className="height--24 cursor-pointer">
                <Icon name="trash" />
              </Col>
              <Col>
                <DragDropButton
                  className="p__x--0 p__y--0 min-h-auto d--flex align__items--center"
                  dragType="vertical"
                  dragHandleProps={dragHandleProps}
                  disabled={isDisableDragged}
                  onClick={event => event.stopPropagation()}
                />
              </Col>
            </Row>
          </Col>
        </Row>
      </div>
      {renderOptions()}
    </div>
  )
}

export default React.memo(CaptureFieldItem)
