import { DatePicker, Divider, Form, Input, Select } from 'antd'
import TextArea from 'antd/lib/input/TextArea'
import Title from 'antd/lib/typography/Title'
import { useEffect, useState } from 'react'
import type { CSSProperties } from 'react'
import ReactMarkdown from 'react-markdown'

import { operationControllerGetOperation } from 'apiClient/services/devops'
import {
  OperationActionStartPolicy,
  OperationOperation,
  OperationInstance
} from 'apiClient/services/devops/interface'

import { SortByWeight } from '../utils'

const actionUpdateGridStyle: CSSProperties = {
  display: 'grid',
  gridTemplateColumns: 'minmax(240px, 1fr) 160px minmax(220px, 1fr)',
  columnGap: 16,
  alignItems: 'start'
}

const actionGridHeaderStyle: CSSProperties = {
  ...actionUpdateGridStyle,
  marginBottom: 16,
  fontWeight: 600
}

const actionGridRowStyle: CSSProperties = {
  ...actionUpdateGridStyle,
  marginBottom: 8
}

const actionNameStyle: CSSProperties = {
  minHeight: 32,
  lineHeight: '32px',
  color: 'black',
  overflowWrap: 'anywhere',
  whiteSpace: 'normal'
}

export type UpdateInstanceFormType = {
  actions?: {
    name: string
    start_policy: OperationActionStartPolicy
    schedule_time?: moment.Moment
  }[]
  reason?: string
  params?: { [key: string]: any }
}

export const UpdateInstanceForm = ({
  cur_instance,
  cur_operation
}: {
  cur_instance: OperationInstance
  cur_operation: OperationOperation
}) => {
  const form = Form.useFormInstance()
  const [refresh, setRefresh] = useState(false)

  return (
    <div>
      <Form.Item label="Operation Categories" name="categories">
        <Select
          options={cur_operation?.categories?.map((category) => ({
            label: category,
            value: category
          }))}
          mode="multiple"
          defaultValue={cur_operation?.categories}
          disabled={true}
        />
      </Form.Item>
      <Form.Item label="Operation">
        <Select disabled={true} value={cur_operation?.name} />
      </Form.Item>
      <Form.Item label="Type" name="type">
        <Input
          disabled={true}
          defaultValue={cur_operation?.target}
          style={{ color: 'black' }}
        ></Input>
      </Form.Item>
      <Form.Item label="Description" name="description">
        <ReactMarkdown>{cur_operation?.description || ``}</ReactMarkdown>
      </Form.Item>
      <Form.Item label="Reason" name="reason">
        <TextArea rows={3} />
      </Form.Item>

      <Divider />
      <Title level={5}>Parameters</Title>
      {cur_instance?.params ? (
        Object.keys(
          SortByWeight(cur_instance?.params, cur_operation?.params)
        ).map((v) => {
          if (cur_operation?.params && cur_operation?.params[v].const) {
            return (
              <Form.Item name={['params', v]} label={v}>
                <Input
                  disabled={true}
                  bordered={false}
                  style={{ color: 'black' }}
                ></Input>
              </Form.Item>
            )
          } else if (cur_operation?.params && cur_operation.params[v].enum) {
            return (
              <Form.Item name={['params', v]} label={v}>
                <Select
                  options={cur_operation.params[v].enum?.map((m) => {
                    return { label: m, value: m }
                  })}
                ></Select>
              </Form.Item>
            )
          } else if (
            cur_operation?.params &&
            cur_operation.params[v].multi_enum
          ) {
            return (
              <Form.Item name={['params', v]} label={v}>
                <Select
                  mode="multiple"
                  options={cur_operation.params[v].multi_enum?.map((m) => {
                    return { label: m, value: m }
                  })}
                ></Select>
              </Form.Item>
            )
          } else {
            return (
              <Form.Item
                name={['params', v]}
                label={v}
                rules={
                  cur_operation?.params &&
                  cur_operation?.params[v].type === 'int'
                    ? [
                        {
                          validator: async (_, value) => {
                            if (value && !isNumberString(value)) {
                              return Promise.reject(
                                new Error('the input should be all digits')
                              )
                            }
                          }
                        }
                      ]
                    : []
                }
              >
                <Input
                  placeholder={
                    cur_operation?.params && cur_operation?.params[v].desc
                  }
                ></Input>
              </Form.Item>
            )
          }
        })
      ) : (
        <> </>
      )}

      <Divider />
      <Title level={5}>Actions</Title>
      <div style={actionGridHeaderStyle}>
        <div>Name</div>
        <div>Schedule</div>
        <div>Schedule Time</div>
      </div>
      {cur_instance.actions?.map((action, index) => (
        <div style={actionGridRowStyle} key={action.name || index}>
          <div>
            <Form.Item hidden name={['actions', index, 'name']}>
              <Input />
            </Form.Item>
            <div style={actionNameStyle}>
              {form.getFieldValue(['actions', index, 'name']) || action.name}
            </div>
          </div>
          <div>
            <Form.Item name={['actions', index, 'start_policy']}>
              <Select
                options={[
                  {
                    label: OperationActionStartPolicy.immediate,
                    value: OperationActionStartPolicy.immediate
                  },
                  {
                    label: OperationActionStartPolicy.manual,
                    value: OperationActionStartPolicy.manual
                  },
                  {
                    label: OperationActionStartPolicy.schedule,
                    value: OperationActionStartPolicy.schedule
                  }
                ]}
                onChange={(val) => {
                  const origin = form.getFieldValue('actions') || {}
                  origin[index].start_policy = val
                  if (val !== OperationActionStartPolicy.schedule) {
                    origin[index].schedule_time = undefined
                  }
                  form.setFieldsValue({ actions: origin })
                  setRefresh((pre) => !pre)
                }}
                style={{ width: '100%' }}
              />
            </Form.Item>
          </div>
          <div>
            <Form.Item
              name={['actions', index, 'schedule_time']}
              rules={[
                {
                  required:
                    form.getFieldValue(['actions', index, 'start_policy']) ===
                    OperationActionStartPolicy.schedule,
                  message: 'please choose the schedule time'
                }
              ]}
            >
              {form.getFieldValue(['actions', index, 'start_policy']) ===
              OperationActionStartPolicy.schedule ? (
                <DatePicker showTime={true} style={{ width: '100%' }} />
              ) : null}
            </Form.Item>
          </div>
        </div>
      ))}
    </div>
  )
}

export default UpdateInstanceForm

function isNumberString(str: string): boolean {
  const regex = /^[0-9]+$/
  return regex.test(str)
}
