import { useInterval } from 'ahooks'
import {
  Skeleton,
  Modal,
  message,
  Avatar,
  Form,
  Select,
  Input,
  Button,
  List,
  Tag,
  Menu,
  FormInstance
} from 'antd'
import { ReactNode, useState } from 'react'
import useProfileContext from 'useProfileContext'

import {
  useUserBehaviorControllerListSubscriptions,
  userBehaviorControllerAddExternalLarkChat,
  userBehaviorControllerCreateSubscription,
  userBehaviorControllerEditSubscription,
  userBehaviorControllerGetLarkChatOptions,
  userBehaviorControllerSendMockEvent
} from 'apiClient/services/devops'
import {
  EntityLarkChatSimplified,
  UserbehaviorAddExternalLarkChatReq,
  UserbehaviorCreateSubscriptionReq,
  UserbehaviorEditSubscriptionReq,
  UserbehaviorRegionSelectorTp,
  UserbehaviorSubscription,
  UserbehaviorUBEventTp
} from 'apiClient/services/devops/interface'
import { ListToolBar } from 'components/Table'

import './index.less'

interface SubscriptionFormData {
  name: string | undefined
  event_type: UserbehaviorUBEventTp | undefined
  subscription_type: string | undefined
  filter_type: 'region' | 'tenant' | undefined
  region_filter: UserbehaviorRegionSelectorTp[] | undefined
  tenant_filter: string | undefined
  lark_chats: number[] | undefined
}

// Color Schemes from https://4x-ant-design.antgroup.com/components/tag-cn/
const regionColors: {
  [key: string]: { bgColor: string; borderColor: string; color: string }
} = {
  // color: orange
  jp: { bgColor: '#f0f5ff', borderColor: '#adc6ff', color: '#1d39c4' },
  // color: geekblue
  na: { bgColor: '#fff7e6', borderColor: '#ffd591', color: '#d46b08' },
  // color: magenta
  apac: { bgColor: '#fff0f6', borderColor: '#ffadd2', color: '#c41d7f' },
  // color: green
  emea: { bgColor: '#f6ffed', borderColor: '#b7eb8f', color: '#389e0d' }
}

const generateRegionAvatar = (regionText: string) => {
  const colorScheme = regionColors[regionText]
  return (
    <Avatar
      style={
        colorScheme && {
          backgroundColor: colorScheme.bgColor,
          borderColor: colorScheme.borderColor,
          color: colorScheme.color
        }
      }
    >
      {regionText.toUpperCase()}
    </Avatar>
  )
}

const eventColors: { [key: string]: string } = {
  tenant: 'geekblue',
  cluster: 'green',
  backup: 'blue',
  restore: 'indigo',
  cdc: 'lime',
  import: 'orange',
  dm: 'magenta'
}

const generateEventTag = (eventText: string) => {
  return <Tag color={eventColors[eventText]}>{eventText}</Tag>
}

export default function Subscriptions() {
  const [loading, setLoading] = useState<boolean>(false)
  const [modalMode, setModalMode] = useState<'create' | 'edit'>('create')
  const [modalVisible, setModalVisible] = useState<boolean>(false)
  const [currentRecord, setCurrentRecord] = useState<UserbehaviorSubscription>({
    id: 0
  })
  const [addChatModalLoading, setAddChatModalLoading] = useState<boolean>(false)
  const [addChatModalVisible, setAddChatModalVisible] = useState<boolean>(false)
  const [selectedTab, setSelectedTab] = useState<'all' | 'own'>('all')

  const { data, refetch } = useUserBehaviorControllerListSubscriptions()

  const [form] = Form.useForm<SubscriptionFormData>()

  const {
    profile: { userEmail }
  } = useProfileContext()

  const subscriptionListItem = (record: UserbehaviorSubscription) => {
    interface contentItemType {
      key: string
      label: string
      content: ReactNode
    }

    const contentItems: contentItemType[] = [
      {
        key: 'event_type',
        label: 'Event Type',
        content: record.event_type && generateEventTag(record.event_type)
      },
      record.selector?.tenant_selectors
        ? {
            key: 'tenant_filter',
            label: 'Tenant ID',
            content: record.selector.tenant_selectors[0]
          }
        : {
            key: 'region_filter',
            label: 'Biz Regions',
            content: (
              <Avatar.Group maxCount={4}>
                {record.selector?.region_selectors
                  ?.filter((r) => r.length > 0)
                  .map(generateRegionAvatar)}
              </Avatar.Group>
            )
          },
      {
        key: 'lark_chats',
        label: 'Lark Chats',
        content: (
          <Avatar.Group maxCount={3}>
            {record.lark_chats?.map((c) =>
              c.avatar_url ? (
                <Avatar src={c.avatar_url} />
              ) : (
                <Avatar>{c.name?.charAt(0)}</Avatar>
              )
            )}
          </Avatar.Group>
        )
      }
    ]

    return (
      <List.Item
        actions={[
          <a
            key="list-item-edit"
            onClick={() => {
              var filterType: 'tenant' | 'region' | undefined = undefined
              if (record.selector?.tenant_selectors?.length) {
                filterType = 'tenant'
              } else if (record.selector?.region_selectors?.length) {
                filterType = 'region'
              }
              form.setFieldsValue({
                name: record.name,
                event_type: record.event_type,
                subscription_type: record.subscribe_type,
                filter_type: filterType,
                region_filter: record.selector?.region_selectors,
                tenant_filter: record.selector?.tenant_selectors?.at(0),
                lark_chats: record.lark_chats?.map((c) => c.id)
              })
              setCurrentRecord(record)
              setModalMode('edit')
              setModalVisible(true)
            }}
          >
            Edit
          </a>,
          <a
            key="list-item-mock"
            onClick={async () => {
              try {
                await userBehaviorControllerSendMockEvent(record.id)
                message.success('send mock message successfully, please check')
              } catch (e) {
                message.warn('send mock message failed', e)
              }
            }}
          >
            Mock
          </a>
        ]}
      >
        <List.Item.Meta
          title={record.name}
          description={'Creator: ' + record.creator}
        />
        <div
          style={{
            flex: '1 1',
            display: 'flex',
            flexDirection: 'row',
            justifyContent: 'flex-start'
          }}
        >
          {contentItems.map((i) => (
            <div
              key={i.key}
              style={{
                marginLeft: '20px',
                marginRight: '20px',
                display: 'flex',
                flexDirection: 'column'
              }}
            >
              <div>{i.label}</div>
              <div
                style={{
                  display: 'flex',
                  flexDirection: 'row'
                }}
              >
                {i.content}
              </div>
            </div>
          ))}
        </div>
      </List.Item>
    )
  }

  const reload = async () => {
    try {
      setLoading(true)
      await refetch()
    } catch (e) {
      console.log('refetch failed', e)
      message.warn('reload failed')
    } finally {
      setLoading(false)
      setModalMode('create')
      setModalVisible(false)
      setAddChatModalVisible(false)
    }
  }

  //if (loading) return <Skeleton />

  return (
    <>
      <ListToolBar
        title={
          <Menu
            mode="horizontal"
            className="listtoolbar-title-menu"
            selectedKeys={[selectedTab]}
            disabled={loading}
            onClick={(e) => {
              setSelectedTab(e.key as 'all' | 'own')
            }}
          >
            <Menu.Item key="all">All Subscriptions</Menu.Item>
            <Menu.Item key="own">Own Subscriptions</Menu.Item>
          </Menu>
        }
        reload={reload}
        actions={[
          <Button
            type="primary"
            onClick={() => {
              setModalMode('create')
              form.setFieldsValue({
                name: undefined,
                event_type: undefined,
                subscription_type: undefined,
                region_filter: undefined,
                tenant_filter: undefined,
                lark_chats: undefined
              })
              setModalVisible(true)
            }}
          >
            Create
          </Button>
        ]}
      />
      <List>
        {data?.data.items
          ?.filter((item: UserbehaviorSubscription) =>
            selectedTab === 'own' ? item.creator === userEmail : true
          )
          .map(subscriptionListItem)}
      </List>
      <SubscriptionModal
        record={currentRecord}
        visible={modalVisible}
        mode={modalMode}
        reload={reload}
        onClose={() => {
          setModalVisible(false)
        }}
        form={form}
      />
      <div className="footer">
        <Button
          type="ghost"
          size="small"
          onClick={() => {
            setAddChatModalVisible(true)
          }}
        >
          Add External Lark Chat
        </Button>
      </div>
      <Modal
        title="Add External Lark Chat"
        visible={addChatModalVisible}
        footer={null}
        onCancel={() => {
          setAddChatModalVisible(false)
        }}
      >
        <Form
          onFinish={(formData: UserbehaviorAddExternalLarkChatReq) => {
            async function sendAddLarkChatReq() {
              try {
                await userBehaviorControllerAddExternalLarkChat(formData)
                setAddChatModalVisible(false)
                message.success(
                  'Add external lark chat successfully, please refresh the webpage'
                )
              } catch (e) {
                console.log(e)
                message.warn('add external lark chat failed: ', e)
              } finally {
                setAddChatModalLoading(false)
              }
            }

            setAddChatModalLoading(true)
            sendAddLarkChatReq()
          }}
        >
          <Form.Item
            name="name"
            label="Name"
            rules={[
              { required: true, message: 'Please input external chat name!' }
            ]}
          >
            <Input style={{ width: 120 }}></Input>
          </Form.Item>
          <Form.Item
            name="chat_url"
            label="Chat URL"
            rules={[
              { required: true, message: 'Please input external chat url!' }
            ]}
          >
            <Input style={{ width: 300 }}></Input>
          </Form.Item>
          <Form.Item name="avatar_url" label="Avatar URL">
            <Input style={{ width: 300 }}></Input>
          </Form.Item>
          <Form.Item>
            <Button
              loading={addChatModalLoading}
              type="primary"
              htmlType="submit"
            >
              Submit
            </Button>
          </Form.Item>
        </Form>
      </Modal>
    </>
  )
}

function SubscriptionModal({
  record,
  visible,
  mode,
  reload,
  onClose,
  form
}: {
  record: UserbehaviorSubscription
  visible: boolean
  mode: 'none' | 'edit' | 'create'
  reload: () => Promise<void>
  onClose: () => void
  form: FormInstance<SubscriptionFormData>
}) {
  const [larkchatOptions, setLarkChatOptions] = useState<
    EntityLarkChatSimplified[]
  >([])
  const [submitting, setSubmitting] = useState<boolean>(false)
  const loadLarkchatoptions = async function () {
    try {
      const data = (await userBehaviorControllerGetLarkChatOptions()).data
      if (data.items) setLarkChatOptions(data.items)
    } catch (e) {
      console.error(e)
    }
  }

  useInterval(
    () => {
      loadLarkchatoptions()
    },
    1000 * 60,
    { immediate: true }
  )

  const handleCreate = async (formData: SubscriptionFormData) => {
    var req: UserbehaviorCreateSubscriptionReq = {
      name: formData.name,
      subscribe_type:
        formData.subscription_type === 'by_chat' ? 'by_chat' : undefined,
      lark_chats: formData.lark_chats?.map((i) => {
        return { id: i }
      }),
      event_type: formData.event_type as UserbehaviorUBEventTp,
      selector: {
        region_selectors: formData.region_filter,
        tenant_selectors: formData.tenant_filter
          ? [formData.tenant_filter]
          : undefined
      }
    }

    setSubmitting(true)
    const resp = userBehaviorControllerCreateSubscription(req)
    try {
      await resp
      reload()
    } catch (e) {
      message.warn('Create failed', e)
    } finally {
      setSubmitting(false)
    }
  }

  const handleEdit = async (formData: SubscriptionFormData) => {
    var req: UserbehaviorEditSubscriptionReq = {
      name: formData.name,
      subscribe_type:
        formData.subscription_type === 'by_chat' ? 'by_chat' : undefined,
      lark_chats: formData.lark_chats?.map((i) => {
        return { id: i }
      }),
      event_type: formData.event_type,
      selector: {
        region_selectors: formData.region_filter,
        tenant_selectors: formData.tenant_filter
          ? [formData.tenant_filter]
          : undefined
      }
    }

    setSubmitting(true)
    const resp = userBehaviorControllerEditSubscription(record.id, req)
    try {
      await resp
      reload()
    } catch (e) {
      message.warn('Edit failed', e)
    } finally {
      setSubmitting(false)
    }
  }

  const modalContent = (mode: 'none' | 'edit' | 'create') => {
    if (mode === 'none') {
      return <Skeleton />
    } else {
      return (
        <Form
          onFinish={mode === 'create' ? handleCreate : handleEdit}
          form={form}
        >
          <Form.Item
            label="Name"
            name="name"
            rules={[
              { required: true, message: 'Please input Subscription Name!' }
            ]}
          >
            <Input style={{ width: 200 }} />
          </Form.Item>
          <Form.Item
            label="Event"
            name="event_type"
            rules={[
              {
                required: true,
                message: 'Please select what event you want to subscribe!'
              }
            ]}
          >
            <Select
              style={{ width: 200 }}
              options={[
                {
                  value: UserbehaviorUBEventTp.tenant,
                  label: 'Tenant Event'
                },
                {
                  value: UserbehaviorUBEventTp.cluster,
                  label: 'Cluster Event'
                },
                {
                  value: UserbehaviorUBEventTp.import,
                  label: 'Import Event'
                },
                {
                  value: UserbehaviorUBEventTp.backup,
                  label: 'Backup Event'
                },
                {
                  value: UserbehaviorUBEventTp.restore,
                  label: 'Restore Event'
                },
                {
                  value: UserbehaviorUBEventTp.cdc,
                  label: 'CDC Changefeed Event'
                },
                {
                  value: UserbehaviorUBEventTp.startup,
                  label: 'New Customer Event'
                }
              ]}
            ></Select>
          </Form.Item>
          <Form.Item
            label="Subscription Type"
            name="subscription_type"
            rules={[
              {
                required: true,
                message:
                  'Please select how do you want to subscribe the events!'
              }
            ]}
          >
            <Select
              style={{ width: 200 }}
              options={[
                {
                  value: 'by_chat',
                  label: 'By Lark Chat'
                }
              ]}
            ></Select>
          </Form.Item>
          <Form.Item
            label="Filter By"
            name="filter_type"
            rules={[
              {
                required: true,
                message: 'Please select the filter type!'
              }
            ]}
          >
            <Select
              allowClear
              style={{ width: 200 }}
              options={[
                {
                  value: 'region',
                  label: 'Biz Region'
                },
                {
                  value: 'tenant',
                  label: 'Tenant'
                }
              ]}
            />
          </Form.Item>
          <Form.Item
            noStyle
            shouldUpdate={(prevValues, currentValues) =>
              prevValues.filter_type !== currentValues.filter_type
            }
          >
            {({ getFieldValue }) => {
              const filterType = getFieldValue('filter_type')
              if (filterType === 'region') {
                return (
                  <Form.Item
                    label="Biz Region"
                    name="region_filter"
                    shouldUpdate
                    rules={[
                      {
                        required: true,
                        message:
                          'Please select the biz regions you want to subscribe!'
                      }
                    ]}
                  >
                    <Select
                      mode="multiple"
                      allowClear
                      style={{ width: 200 }}
                      options={[
                        {
                          value: 'na',
                          label: 'NA'
                        },
                        {
                          value: 'emea',
                          label: 'EMEA'
                        },
                        {
                          value: 'jp',
                          label: 'JP'
                        },
                        {
                          value: 'apac',
                          label: 'APAC'
                        }
                      ]}
                    ></Select>
                  </Form.Item>
                )
              } else if (filterType === 'tenant') {
                return (
                  <Form.Item label="Tenant ID" name="tenant_filter">
                    <Input style={{ width: 200 }}></Input>
                  </Form.Item>
                )
              } else {
                return <></>
              }
            }}
          </Form.Item>
          <Form.Item
            label="Subscribe Lark Chats"
            name="lark_chats"
            rules={[
              {
                required: true,
                message: 'Please select which lark chats you want to send to!'
              }
            ]}
          >
            <Select
              mode="multiple"
              options={[
                {
                  label: 'External Chats',
                  options: larkchatOptions
                    .filter((e) => e.is_external)
                    .map((e) => {
                      return {
                        key: e.id,
                        value: e.id,
                        label: e.name ? e.name : ''
                      }
                    })
                },
                {
                  label: 'Internal Chats',
                  options: larkchatOptions
                    .filter((e) => !e.is_external)
                    .map((e) => {
                      return {
                        key: e.id,
                        value: e.id,
                        label: e.name ? e.name : ''
                      }
                    })
                }
              ]}
            ></Select>
          </Form.Item>
          <Form.Item>
            {mode === 'create' ? (
              <Button type="primary" htmlType="submit" loading={submitting}>
                Create
              </Button>
            ) : (
              <Button type="primary" htmlType="submit" loading={submitting}>
                Edit
              </Button>
            )}
          </Form.Item>
        </Form>
      )
    }
  }

  return (
    <Modal
      visible={visible}
      onCancel={onClose}
      title={mode === 'create' ? 'Create Subscription' : 'Edit Subscription'}
      footer={null}
    >
      {modalContent(mode)}
    </Modal>
  )
}
