import {
  DeleteOutlined,
  DownOutlined,
  PlusOutlined,
  RightOutlined
} from '@ant-design/icons'
import { Button, Input, Select, Space, Typography } from 'antd'
import React, { useMemo, useState } from 'react'

import type { EmptyNodepoolsStepOptions } from './upgradeOperationCr'

type OptionKey = 'delay' | 'delete'

type OptionRow = {
  key: OptionKey
  value: string
}

const ALL_OPTION_KEYS: OptionKey[] = ['delay', 'delete']

function optionsToRows(options?: EmptyNodepoolsStepOptions): OptionRow[] {
  const rows: OptionRow[] = []
  if (options?.delay != null) {
    rows.push({ key: 'delay', value: options.delay })
  }
  if (options?.delete != null) {
    rows.push({ key: 'delete', value: options.delete ? 'true' : 'false' })
  }
  return rows
}

function rowsToOptions(
  rows: OptionRow[]
): EmptyNodepoolsStepOptions | undefined {
  const options: EmptyNodepoolsStepOptions = {}

  for (const row of rows) {
    if (row.key === 'delay') {
      const delay = row.value.trim()
      if (delay) {
        options.delay = delay
      }
    }
    if (row.key === 'delete') {
      options.delete = row.value === 'true'
    }
  }

  return Object.keys(options).length ? options : undefined
}

type Props = {
  options?: EmptyNodepoolsStepOptions
  disabled?: boolean
  defaultExpanded?: boolean
  alignLeft?: number
  alignWidth?: number
  onChange: (options: EmptyNodepoolsStepOptions | undefined) => void
}

const optionRowStyle: React.CSSProperties = {
  display: 'grid',
  gridTemplateColumns: '1fr 1fr 24px',
  gap: 8,
  alignItems: 'center',
  width: '100%'
}

const optionFieldStyle: React.CSSProperties = {
  width: '100%',
  minWidth: 0
}

export const EmptyNodepoolsOptionsEditor: React.FC<Props> = ({
  options,
  disabled,
  defaultExpanded = false,
  alignLeft = 0,
  alignWidth,
  onChange
}) => {
  const [expanded, setExpanded] = useState(
    defaultExpanded || optionsToRows(options).length > 0
  )
  const [rows, setRows] = useState<OptionRow[]>(() => optionsToRows(options))

  const usedKeys = useMemo(() => new Set(rows.map((row) => row.key)), [rows])
  const addableKeys = ALL_OPTION_KEYS.filter((key) => !usedKeys.has(key))

  const commitRows = (nextRows: OptionRow[]) => {
    setRows(nextRows)
    onChange(rowsToOptions(nextRows))
  }

  const updateRow = (index: number, patch: Partial<OptionRow>) => {
    commitRows(
      rows.map((row, i) => {
        if (i !== index) return row
        const merged = { ...row, ...patch }
        if (merged.key === 'delete' && !merged.value) {
          merged.value = 'true'
        }
        return merged
      })
    )
  }

  const removeRow = (index: number) => {
    commitRows(rows.filter((_, i) => i !== index))
  }

  const handleAddRow = () => {
    if (addableKeys.length === 0) {
      return
    }

    const key: OptionKey = addableKeys.includes('delay') ? 'delay' : 'delete'
    setExpanded(true)
    commitRows([
      ...rows,
      {
        key,
        value: key === 'delete' ? 'true' : ''
      }
    ])
  }

  return (
    <div style={{ width: '100%' }}>
      <div
        role="button"
        tabIndex={disabled ? -1 : 0}
        onClick={() => {
          if (!disabled) {
            setExpanded((value) => !value)
          }
        }}
        onKeyDown={(event) => {
          if (disabled) return
          if (event.key === 'Enter' || event.key === ' ') {
            event.preventDefault()
            setExpanded((value) => !value)
          }
        }}
        style={{
          borderTop: '1px solid #f0f0f0',
          textAlign: 'center',
          cursor: disabled ? 'default' : 'pointer',
          padding: '4px 0',
          color: '#8c8c8c',
          lineHeight: 1,
          userSelect: 'none'
        }}
      >
        {expanded ? (
          <DownOutlined style={{ fontSize: 10 }} />
        ) : (
          <RightOutlined style={{ fontSize: 10 }} />
        )}
      </div>
      {expanded ? (
        <div
          style={{
            paddingTop: 12,
            paddingBottom: 4,
            paddingLeft: alignLeft,
            width: alignWidth ? alignLeft + alignWidth : undefined,
            maxWidth: '100%',
            boxSizing: 'border-box'
          }}
        >
          <div
            style={{
              width: '100%',
              border: '1px solid #d6e4ff',
              borderRadius: 4,
              padding: '8px 10px',
              background: '#fafcff',
              boxSizing: 'border-box'
            }}
          >
            <Typography.Text
              type="secondary"
              style={{ display: 'block', marginBottom: 8, fontSize: 12 }}
            >
              Options
            </Typography.Text>
            {rows.length > 0 ? (
              <Space direction="vertical" size={6} style={{ width: '100%' }}>
                {rows.map((row, index) => (
                  <div key={`${row.key}-${index}`} style={optionRowStyle}>
                    <Select<OptionKey>
                      size="small"
                      style={optionFieldStyle}
                      value={row.key}
                      disabled={disabled}
                      options={ALL_OPTION_KEYS.filter(
                        (key) => key === row.key || !usedKeys.has(key)
                      ).map((key) => ({ label: key, value: key }))}
                      onChange={(key) =>
                        updateRow(index, {
                          key,
                          value: key === 'delete' ? 'true' : ''
                        })
                      }
                    />
                    {row.key === 'delay' ? (
                      <Input
                        size="small"
                        style={optionFieldStyle}
                        placeholder="10m"
                        value={row.value}
                        disabled={disabled}
                        onChange={(event) =>
                          updateRow(index, { value: event.target.value })
                        }
                      />
                    ) : (
                      <Select
                        size="small"
                        style={optionFieldStyle}
                        value={row.value || 'true'}
                        disabled={disabled}
                        options={[
                          { label: 'true', value: 'true' },
                          { label: 'false', value: 'false' }
                        ]}
                        onChange={(value) => updateRow(index, { value })}
                      />
                    )}
                    <Button
                      type="text"
                      size="small"
                      danger
                      icon={<DeleteOutlined />}
                      disabled={disabled}
                      onClick={() => removeRow(index)}
                    />
                  </div>
                ))}
              </Space>
            ) : null}
            {addableKeys.length > 0 ? (
              <div style={{ marginTop: rows.length > 0 ? 8 : 0 }}>
                <Button
                  type="dashed"
                  size="small"
                  icon={<PlusOutlined />}
                  disabled={disabled}
                  style={{ width: 32, padding: '0 8px' }}
                  onClick={handleAddRow}
                />
              </div>
            ) : null}
          </div>
        </div>
      ) : null}
    </div>
  )
}
