import {
  Button,
  Form,
  Input,
  InputNumber,
  Select,
  TreeSelect,
  Checkbox,
  Modal
} from 'antd'
import { DataNode } from 'antd/lib/tree'
import dayjs, { Dayjs } from 'dayjs'
import React, { useMemo, useState } from 'react'

import { useGetCreditTypeTree } from 'apiClient/api'
import { FormsCreditTypeNode } from 'apiClient/api/interface'
import DatePicker from 'components/DatePicker'
import ModalForm from 'components/ModalForm'
import { format } from 'utils/time'

import { addCredits } from '../../../../apiClient/services/devops'
import { TenantAddCreditsReq } from '../../../../apiClient/services/devops/interface'
import { CreditsPackageUsage } from '../BusinessInfo/Credits'

const fmt = 'YYYY-MM-DD HH:mm:ss'
const EMPTY_CREDIT_TYPE_TREE: FormsCreditTypeNode[] = []

type CreditTypeTreeDataNode = DataNode & {
  value: string | number
}

const getDefaultPocUnitFilters = (tree: FormsCreditTypeNode[]): string[] => {
  const findGeneralProduct = (
    nodes: FormsCreditTypeNode[]
  ): FormsCreditTypeNode | undefined => {
    for (const n of nodes) {
      if (n.name === 'General Product') {
        return n
      }
      if (n.children && n.children.length > 0) {
        const found = findGeneralProduct(n.children)
        if (found) {
          return found
        }
      }
    }
    return undefined
  }

  const target = findGeneralProduct(tree) || tree[0]

  if (!target) {
    return []
  }

  return [
    JSON.stringify({
      filter_id: target.type_id || '',
      name: target.name || ''
    })
  ]
}

const getTreeData = (tree: FormsCreditTypeNode[]): CreditTypeTreeDataNode[] => {
  return tree.map((t) => {
    const data: CreditTypeTreeDataNode = {
      title: t.name,
      value: JSON.stringify({
        filter_id: t.type_id || '',
        name: t.name || ''
      }),
      key: t.type_id || '',
      children: t.children ? getTreeData(t.children) : []
    }
    return data
  })
}

export const AddCredit: React.FC<
  React.PropsWithChildren<{
    orgId: string
  }>
> = ({ orgId }) => {
  const [visible, setVisible] = useState(false)

  const defaultTime = dayjs(dayjs().format('YYYY-MM-DD') + ' 00:00:00')

  const timeFormat = (value: Dayjs) => {
    return format(value.format(fmt), undefined, 'YYYY-MM-DD HH:mm:ss', 8)
  }

  const { data } = useGetCreditTypeTree()
  const creditTypeTree = data?.data?.children || EMPTY_CREDIT_TYPE_TREE
  const defaultPocUnitFilters = useMemo(() => {
    return getDefaultPocUnitFilters(creditTypeTree)
  }, [creditTypeTree])
  const creditTypeTreeData = useMemo(() => {
    return getTreeData(creditTypeTree)
  }, [creditTypeTree])
  const initValues = useMemo(
    () => ({
      usage: CreditsPackageUsage.POC,
      discount_enabled: true,
      unit_filters: defaultPocUnitFilters
    }),
    [defaultPocUnitFilters]
  )

  const onSubmit = async (values: any) => {
    const data = values as TenantAddCreditsReq

    if (data.unit_filters) {
      // @ts-ignore
      data.unit_filters = data.unit_filters.map((it) => {
        return JSON.parse(it.toString()) as { filter_id: string; name: string }
      })
    }
    try {
      const resp = await addCredits(orgId || '', {
        ...data
      })
      const id = resp.data.instance_id
      Modal.success({
        title: 'Info',
        content: (
          <div>
            <p>
              Operation <b>{id}</b> is awaiting approval and can only be started
              after approval.
              <br></br>
              <br></br>
              To check the progress of this operation, please refer to the{' '}
              <a href={`/operations/${id}`}>Detail</a> page.
            </p>
          </div>
        ),
        onOk() {}
      })
      setVisible(false)
    } catch (error) {
      Modal.error({
        title: error.response.data.errcode,
        content: error.response.data.errmsg
      })
    }
  }

  const renderFields = () => {
    return (
      <>
        <Form.Item
          name="department"
          label="Department"
          rules={[
            {
              required: true,
              message: 'Please select the department'
            }
          ]}
        >
          <Select
            style={{ width: 300 }}
            options={[
              { value: 'APAC', label: 'APAC' },
              { value: 'JAPAN', label: 'JAPAN' },
              { value: 'NA', label: 'NA' },
              { value: 'EMEA', label: 'EMEA' },
              { value: 'CEG', label: 'CEG' },
              { value: 'RDG', label: 'RDG' },
              { value: 'BO', label: 'BO' }
            ]}
          />
        </Form.Item>
        <Form.Item
          name="use_case"
          label="Use Case"
          rules={[
            {
              required: true,
              message: 'Please select the use case'
            }
          ]}
        >
          <Select
            style={{ width: 300 }}
            options={[
              { value: 'Demo', label: 'Demo' },
              { value: 'QA', label: 'QA' },
              { value: 'Internal Trial', label: 'Internal Trial' },
              { value: 'Other', label: 'Other' }
            ]}
          />
        </Form.Item>
        <Form.Item
          name="usage"
          label="Usage"
          required
          rules={[{ required: true, message: 'Required' }]}
        >
          <Input disabled={true} bordered={false} />
        </Form.Item>
        <Form.Item
          name="unit_filters"
          label="Credit Type"
          required
          rules={[{ required: true, message: 'Required' }]}
        >
          <TreeSelect
            showCheckedStrategy="SHOW_PARENT"
            treeCheckable
            treeDefaultExpandAll
            treeData={creditTypeTreeData}
          />
        </Form.Item>
        <Form.Item
          name="discount_enabled"
          label="Apply credits after discount"
          valuePropName="checked"
        >
          <Checkbox />
        </Form.Item>
        <Form.Item
          name="total_credits"
          label="Credits"
          required
          rules={[{ required: true, message: 'Required' }]}
        >
          <InputNumber<string>
            stringMode
            min="0"
            step="0.01"
            precision={2}
            style={{ display: 'inline-block', width: '100%' }}
          />
        </Form.Item>
        <Form.Item
          name="expired_date"
          label="Expiry Date"
          required
          rules={[{ required: true, message: 'Required' }]}
          extra="Current time zone is UTC+08:00"
        >
          <DatePicker
            showNow={false}
            showTime={{
              defaultValue: defaultTime,
              format: 'HH:mm:ss'
            }}
            format={timeFormat}
          />
        </Form.Item>
        <Form.Item
          name="apply_for_test"
          style={{ width: 1800 }}
          label="Applied for these 3 types of testing (Incident Verification, Feature Verification, Tuning)?"
          valuePropName="checked"
        >
          <Checkbox />
        </Form.Item>
        <Form.Item
          label="Reason"
          name="reason"
          required
          rules={[{ required: true, message: 'Required' }]}
        >
          <Input.TextArea rows={3} placeholder="Reason to add credits" />
        </Form.Item>
      </>
    )
  }

  return (
    <div>
      <Button
        type="link"
        onClick={() => setVisible(true)}
        style={{ padding: 0, width: '100%', textAlign: 'left' }}
      >
        Add Credit
      </Button>
      <ModalForm
        width={700}
        layout={{
          labelCol: { span: 8 }
        }}
        initValues={initValues}
        name="add-credit-form"
        // labelAlign="left"
        title="Add Credit"
        visible={visible}
        onSubmit={onSubmit}
        onCancel={() => setVisible(false)}
        getFields={renderFields}
      ></ModalForm>
    </div>
  )
}
