import { Button, Form, Select } from 'antd'
import dayjs, { Dayjs } from 'dayjs'
import { useCallback, useState, cloneElement } from 'react'

import {
  listTenants,
  createCustomer,
  useGetTenantByID,
  useGetMspByOrgId
} from 'apiClient/services/account'
import { FormsPartnerCustomer } from 'apiClient/services/account/interface'
import { useGetTenantSupportPlan } from 'apiClient/services/billing'
import DatePicker from 'components/DatePicker'
import DebounceSelect from 'components/DebounceSelect/DebounceSelect'
import ModalForm from 'components/ModalForm'
import { PlanLevels } from 'pages/Tenants/TenantDetail/BusinessInfo/SupportPlan'
import { format } from 'utils/time'

const fmt = 'YYYY-MM-DD'

export const CreateMSPCustomer: React.FC<
  React.PropsWithChildren<{
    msp_org_id?: string
    msp_customer_id?: string
    trigger?: React.ReactElement
    title?: string
    onCreate?: () => void
  }>
> = ({
  msp_org_id,
  msp_customer_id,
  trigger,
  title = 'Add a MSP Customer',
  onCreate
}) => {
  const [visible, setVisible] = useState(false)

  const { data: bindedPlan } = useGetTenantSupportPlan(msp_org_id || '')

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

  const onSubmit = async (data: {
    msp_org_id: string | { value: string; label: string }
    customer_org_id: string | { value: string; label: string }
    effected_at: string
  }) => {
    const customer: FormsPartnerCustomer = {
      partner_type: 'MSP',
      effected_at:
        dayjs(data.effected_at).startOf('day').format('YYYY-MM-DD') +
        'T00:00:00Z',
      partner_org_id: msp_org_id,
      customer_org_id: msp_customer_id
    }

    if (
      typeof data.msp_org_id !== 'string' &&
      data.msp_org_id &&
      'value' in data.msp_org_id
    ) {
      customer.partner_org_id = data.msp_org_id.value
    }
    if (
      typeof data.customer_org_id !== 'string' &&
      data.customer_org_id &&
      'value' in data.customer_org_id
    ) {
      customer.customer_org_id = data.customer_org_id.value
    }
    await createCustomer(customer)
    onCreate?.()
    onClose()
  }

  const onClose = () => {
    setVisible(false)
  }

  const { data: msp } = useGetMspByOrgId(msp_org_id || '', {
    query: {
      enabled: !!msp_org_id && visible,
      refetchOnWindowFocus: false,
      refetchInterval: false
    }
  })

  const { data: org } = useGetTenantByID(msp_customer_id || '', {
    query: {
      enabled: !!msp_customer_id && visible,
      refetchOnWindowFocus: false,
      refetchInterval: false
    }
  })

  const Trigger = trigger ? (
    cloneElement(trigger, {
      onClick: () => {
        setVisible(true)
      }
    })
  ) : (
    <Button type="primary" onClick={() => setVisible(true)}>
      Add a MSP Customer
    </Button>
  )

  const renderFields = () => {
    return (
      <>
        <Form.Item
          name="msp_org_id"
          label="Linked MSP"
          required
          rules={[{ required: true, message: 'Required' }]}
        >
          {!!msp ? (
            <Select disabled>
              <Select.Option value={msp.data.org_id || ''}>
                {msp.data.name}
              </Select.Option>
            </Select>
          ) : (
            <DebounceSelect
              showSearch
              placeholder="Search by ID/Name/Email"
              fetchOptions={async (search: string) => {
                const data = await listTenants({ org_tag: 'msp', search })
                return (data.data.items || []).map((item) => {
                  return {
                    label: item.name || '',
                    value: item.id || ''
                  }
                })
              }}
            />
          )}
        </Form.Item>
        <Form.Item label="Support Plan Level">
          {bindedPlan?.data.level}
        </Form.Item>
        <Form.Item
          name="customer_org_id"
          label="Customer"
          required
          rules={[{ required: true, message: 'Required' }]}
        >
          {!!org ? (
            <Select disabled>
              <Select.Option value={org.data.id || ''}>
                {org.data.name}
              </Select.Option>
            </Select>
          ) : (
            <DebounceSelect
              showSearch
              placeholder="Search by ID/Name/Email"
              fetchOptions={async (search: string) => {
                const data = await listTenants({
                  search,
                  org_tag: '',
                  status: ['active']
                })
                return (data.data.items || []).map((item) => {
                  return {
                    label: `${item.name} (Org ID: ${item.id})` || '',
                    value: item.id || ''
                  }
                })
              }}
            />
          )}
        </Form.Item>
        <Form.Item
          name="effected_at"
          label="Effective Date"
          required
          rules={[{ required: true, message: 'required' }]}
        >
          <DatePicker
            picker="date"
            format={timeFormat}
            disabledDate={(date) => {
              const end = dayjs().utc().add(1, 'day').startOf('day')
              return dayjs(date).isBefore(end)
            }}
          />
        </Form.Item>
      </>
    )
  }

  return (
    <div>
      {Trigger}
      <ModalForm
        initValues={{
          msp_org_id: msp?.data.org_id || '',
          customer_org_id: org?.data.id || '',
          effected_at: ''
        }}
        width={700}
        name="create-msp-customer-form"
        title={title}
        visible={visible}
        onSubmit={onSubmit}
        onCancel={onClose}
        getFields={renderFields}
        destoryOnClose
      ></ModalForm>
    </div>
  )
}
