import { useAtom, useAtomValue, useSetAtom } from 'jotai'
import {
  deleteSslAtom, getProvider,
  KeyTypeEnum,
  KeyTypes,
  ProviderTypeEnum,
  saveOrUpdateSslAtom,
  sslListAtom,
  sslPageAtom,
  sslSearchAtom, uploadSslAtom
} from '@/store/websites/ssl.ts'
import ListPageLayout from '@/layout/ListPageLayout.tsx'
import { BetaSchemaForm, ProColumns, ProFormColumnsType } from '@ant-design/pro-components'
import { memo, useEffect, useMemo, useRef, useState } from 'react'
import { useTranslation } from '@/i18n.ts'
import { Button, Form, Popconfirm, Space } from 'antd'
import { PlusOutlined } from '@ant-design/icons'
import DrawerPicker, { DrawerPickerRef } from '@/components/drawer-picker/DrawerPicker.tsx'
import AcmeList from './acme/AcmeList.tsx'
import { acmeListAtom, AcmeType, getAcmeAccountTypeName } from '@/store/websites/acme.ts'
import { dnsListAtom, getDNSTypeName } from '@/store/websites/dns.ts'
import DNSList from './dns/DNSList.tsx'
import CAList from './ca/CAList.tsx'
import { WebSite } from '@/types'
import Switch from '@/components/switch'
import { Else, If, Then } from 'react-if'
import Action from '@/components/action/Action.tsx'
import { Status } from '@/components/status'
import SSLDetail from './components/Detail.tsx'
import { detailAtom } from './components/store.ts'
import Upload from './components/Upload.tsx'
import { FormInstance } from 'antd/lib'
import Download from '@/components/download/Download.tsx'
import { Table as ProTable } from '@/components/table'


const SSL = () => {

  const { t } = useTranslation()
  const [ form ] = Form.useForm()
  const uploadFormRef = useRef<FormInstance>()
  const [ page, setPage ] = useAtom(sslPageAtom)
  const [ search, setSearch ] = useAtom(sslSearchAtom)
  const { data: acmeData, isLoading: acmeLoading } = useAtomValue(acmeListAtom)
  const { data: dnsData, isLoading: dnsLoading } = useAtomValue(dnsListAtom)
  const { data, isLoading, isFetching, refetch } = useAtomValue(sslListAtom)
  const { mutate: saveOrUpdate, isSuccess, isPending: isSubmitting } = useAtomValue(saveOrUpdateSslAtom)
  const { mutate: deleteSSL, isPending: isDeleting } = useAtomValue(deleteSslAtom)
  const { mutate: uploadSSL, isSuccess: isUploadSuccess, isPending: isUploading } = useAtomValue(uploadSslAtom)
  const updateDetail = useSetAtom(detailAtom)
  const uploadDrawerRef = useRef<DrawerPickerRef>()
  const [ open, setOpen ] = useState(false)

  const columns = useMemo<ProColumns<WebSite.ISSL>[]>(() => {
    return [
      {
        title: 'ID',
        dataIndex: 'id',
        hideInTable: true,
        hideInSearch: false,
        formItemProps: {
          hidden: true,
        }
      },
      {
        title: t('website.ssl.columns.primaryDomain', '域名'),
        dataIndex: 'primary_domain',
        formItemProps: {
          label: t('website.ssl.form.primaryDomain', '主域名'),
          rules: [ { required: true, message: t('message.required', '主域名') } ]
        }
      },
      {
        title: t('website.ssl.columns.otherDomains', '其它域名'),
        dataIndex: 'domains',
      },
      {
        title: t('website.ssl.columns.acmeAccountId', 'Acme帐号'),
        dataIndex: 'acme_account_id',
        valueType: 'select',
        fieldProps: {
          loading: acmeLoading,
          options: acmeData?.rows?.map(item => ({
            label: `${item.email} [${getAcmeAccountTypeName(item.type as AcmeType)}]`,
            value: item.id
          }))
        },
        formItemProps: {
          rules: [
            { required: true, message: t('message.required', '请选择') }
          ]
        }
      },
      {
        title: t('website.ssl.columns.status', '状态'),
        dataIndex: 'status',
        render: (_, record) => {
          return <Status status={record.status}/>
        },
        hideInForm: true,
      },
      {
        title: t('website.ssl.columns.keyType', '密钥算法'),
        dataIndex: 'key_type',
        hideInTable: true,
        valueType: 'select',
        fieldProps: {
          options: KeyTypes
        },
        formItemProps: {
          rules: [
            { required: true, message: t('message.required', '请选择') }
          ]
        },
      },
      {
        title: t('website.ssl.columns.provider', '申请方式'),
        dataIndex: 'provider',
        valueType: 'radio',
        valueEnum: {
          [ProviderTypeEnum.DnsAccount]: {
            text: t('website.ssl.providerTypeEnum.DnsAccount', 'DNS帐号'),
          },
          [ProviderTypeEnum.DnsManual]: {
            text: t('website.ssl.providerTypeEnum.DnsManual', '手动验证'),
          },
          [ProviderTypeEnum.Http]: {
            text: t('website.ssl.providerTypeEnum.Http', 'HTTP'),
          }
        },
        dependencies: [ 'provider' ],
        renderText: (text) => {
          return getProvider(text)
        },
        formItemProps: (form, config) => {
          const val = form.getFieldValue(config.dataIndex)
          const help = {
            [ProviderTypeEnum.DnsAccount]: t('website.ssl.form.provider_{{v}}', '', { v: val }),
            [ProviderTypeEnum.DnsManual]: t('website.ssl.form.provider_{{v}}', '手动解析模式需要在创建完之后点击申请按钮获取 DNS 解析值', { v: val }),
            [ProviderTypeEnum.Http]: t('website.ssl.form.provider_{{v}}', 'HTTP 模式需要安装 OpenResty<br/><span style="color:red;">HTTP 模式无法申请泛域名证书</span>', { v: val }),
          }
          return {
            label: t('website.ssl.form.provider', '验证方式'),
            help: <span dangerouslySetInnerHTML={{ __html: help[val] }}/>,
            rules: [ { required: true, message: t('message.required', '请选择') } ]
          }
        },
      },
      {
        name: [ 'provider' ],
        valueType: 'dependency',
        hideInSetting: true,
        hideInTable: true,
        columns: ({ provider }) => {
          if (provider === ProviderTypeEnum.DnsAccount) {
            return [ {
              title: t('website.ssl.columns.dnsAccountId', 'DNS帐号'),
              dataIndex: 'dns_account_id',
              valueType: 'select',
              formItemProps: {
                rules: [ { required: true, message: t('message.required', '请输入DNS帐号') } ]
              },
              fieldProps: {
                loading: dnsLoading,
                options: dnsData?.rows?.map(item => ({
                  label: `${item.name} [${getDNSTypeName(item.type)}]`,
                  value: item.id
                }))
              },
            } ]
          }
          return []

        }
      },
      {
        title: t('website.ssl.columns.autoRenew', '自动续签'),
        dataIndex: 'auto_renew',
        valueType: 'switch',
        render: (_, record) => {
          return <Switch value={record.auto_renew} size={'small'}/>
        }
      },
      {
        title: t('website.ssl.columns.pushDir', '推送证书到本地目录'),
        dataIndex: 'push_dir',
        valueType: 'switch',
        hideInTable: true,
        hideInSearch: true,

      },
      {
        name: [ 'push_dir' ],
        valueType: 'dependency',
        hideInSetting: true,
        hideInTable: true,
        columns: ({ pushDir }) => {
          if (pushDir) {
            return [ {
              title: t('website.ssl.columns.dir', '目录'),
              dataIndex: 'dir',
              formItemProps: {
                help: t('website.ssl.form.dir_help', '会在此目录下生成两个文件，证书文件：fullchain.pem 密钥文件：privkey.pem'),
                rules: [ { required: true, message: t('message.required', '请输入目录') } ]
              }
            } ]
          }
          return []

        }
      },
      {
        title: t('website.ssl.columns.description', '备注'),
        dataIndex: 'description',
      },
      {
        title: t('website.ssl.columns.expire_date', '过期时间'),
        dataIndex: 'expire_date',
        valueType: 'dateTime',
        hideInForm: true,
      },
      {
        title: t('website.ssl.columns.option', '操作'), valueType: 'option',
        key: 'option',
        fixed: 'right',
        width: 300,
        render: (_, record) => [

          <Action key="detail"
                  as={'a'}
                  disabled={record.status === 'init' || record.status === 'error'}
                  onClick={() => {
                    updateDetail({
                      open: true,
                      record
                    })
                  }}
          >
            {t('actions.detail', '详情')}
          </Action>,
          <If condition={() => record.status !== 'manual'}>
            <Then>
              <Action key="apply"
                      as={'a'}
                      disabled={record.status === 'applying' || record.status === 'manual'}

                      onClick={() => {

                      }}
              >
                {t('actions.apply', '申请')}
              </Action>
            </Then>
            <Else>
              <Action key="update"
                      as={'a'}
                      onClick={() => {

                      }}
              >
                {t('actions.update', '更新')}
              </Action>
            </Else>

          </If>,
          <Download key="download"
                    server={async () => {
                    }}
          >
            <a>{t('actions.download', '下载')}</a>
          </Download>,
          <Popconfirm
            key={'del_confirm'}
            disabled={isDeleting}
            onConfirm={() => {
              deleteSSL(record.id)
            }}
            title={t('message.deleteConfirm')}>
            <a key="del">
              {t('actions.delete', '删除')}
            </a>
          </Popconfirm>
          ,
        ],
      },
    ]

  }, [ acmeData, dnsData ])

  useEffect(() => {
    if (isSuccess) {
      setOpen(false)
    }
  }, [ isSuccess ])

  return (
    <ListPageLayout>
      <ProTable<WebSite.ISSL>
        headerTitle={t('website.ssl.title', '证书列表')}
        search={false}
        loading={isLoading || isFetching}
        rowKey={'id'}
        dataSource={data?.rows ?? []}
        columns={columns}
        columnsState={{
          defaultValue: {
            option: { fixed: 'right', disable: true },
          },
        }}
        options={{
          reload: () => {
            refetch()
          },
        }}
        toolbar={{
          search: {
            loading: isFetching && !!search.key,
            onSearch: (value: string) => {
              setSearch({ key: value })
            },
            placeholder: t('website.ssl.search.placeholder', '输入域名')
          },
          actions: [
            <DrawerPicker
              maskClosable={false}
              title={t('website.ssl.ca.title', '证书颁发机构')}
              width={1000}
              target={<Button type={'primary'} ghost={true}>
                {t('website.ssl.actions.selfSigned', '自签证书')}
              </Button>}
            >
              <CAList/>
            </DrawerPicker>,
            <DrawerPicker
              maskClosable={false}
              title={t('website.ssl.acme.title', 'Acme帐户')}
              width={1000}
              target={<Button type={'primary'} ghost={true}>
                {t('website.ssl.actions.acme', 'Acme帐户')}
              </Button>}
            >
              <AcmeList/>
            </DrawerPicker>,
            <DrawerPicker
              maskClosable={false}
              title={t('website.ssl.dns.title', 'DNS帐户')}
              width={1000}
              target={<Button type={'primary'} ghost={true}>
                {t('website.ssl.actions.dns', 'DNS帐户')}
              </Button>}>
              <DNSList/>
            </DrawerPicker>,
            <Button type={'primary'} onClick={() => {
              uploadDrawerRef.current?.open()
            }}>
              {t('website.ssl.actions.upload', '上传证书')}
            </Button>,
            <Button
              key="button"
              icon={<PlusOutlined/>}
              onClick={() => {
                form.resetFields()
                form.setFieldsValue({
                  id: 0,
                  keyType: KeyTypeEnum.EC256,
                })
                setOpen(true)
              }}
              type="primary"
            >
              {t('actions.sslApply', '申请证书')}
            </Button>,
          ]
        }}
        scroll={{}}
        pagination={{
          pageSize: page?.pageSize ?? 10,
          total: data?.total ?? 0,
          current: page?.page ?? 1,
          onShowSizeChange: (current: number, size: number) => {
            setPage({
              ...page,
              pageSize: size,
              page: current
            })
          },
          onChange: (page, pageSize) => {
            setPage(prev => ({
              ...prev,
              page,
              pageSize,
            }))
          },
        }}
      >

      </ProTable>
      <BetaSchemaForm<WebSite.ISSL>
        shouldUpdate={false}
        width={600}
        form={form}
        layout={'vertical'}
        scrollToFirstError={true}
        title={t(`website.ssl.title_${form.getFieldValue('id') !== 0 ? 'edit' : 'add'}`, form.getFieldValue('id') !== 0 ? '证书编辑' : '证书添加')}
        // colProps={{ span: 24 }}
        labelCol={{ span: 12 }}
        wrapperCol={{ span: 24 }}
        layoutType={'DrawerForm'}
        open={open}
        drawerProps={{
          maskClosable: false,
        }}
        onOpenChange={(open) => {
          setOpen(open)
        }}
        loading={isSubmitting}
        onFinish={async (values) => {
          // console.log('values', values)
          saveOrUpdate(values)
        }}
        columns={columns as ProFormColumnsType[]}/>
      <DrawerPicker
        id={'upload-drawer-picker'}
        ref={uploadDrawerRef}
        maskClosable={false}
        title={t('website.ssl.upload.title', '上传证书')}
        width={800}
        footer={[
          <Space wrap={false} style={{ display: 'flex', justifyContent: 'end' }}>
            <Button onClick={() => uploadDrawerRef.current?.close()}>{t('actions.cancel')}</Button>
            <Button onClick={() => {
              uploadFormRef.current?.validateFields?.().then(values => {
                uploadSSL(values)
                if (isUploadSuccess) {
                  uploadDrawerRef.current?.close()
                }
              })
            }}
                    loading={isUploading}
                    type={'primary'}>{t('actions.ok')}</Button>
          </Space>
        ]}
        target={false}
      >
        <Upload formRef={uploadFormRef}/>
      </DrawerPicker>
      <SSLDetail/>
    </ListPageLayout>
  )
}

export default memo(SSL)