import React, { useState, useEffect, useRef } from 'react';
import { List, Form, Modal, Input, message } from 'antd';
import { Session } from '@/utils';
import { history } from 'umi';
import JSEncrypt from 'jsencrypt';
import API from '@/api';

type Unpacked<T> = T extends (infer U)[] ? U : T;

const passwordStrength = {
  strong: <span className="strong">强</span>,
  medium: <span className="medium">中</span>,
  weak: <span className="weak">弱 Weak</span>,
};

const SecurityView: React.FC = () => {
  const [visible, setVisible] = useState<boolean>(false);
  const [loading, setLoading] = useState<boolean>(false);
  const [publicKey, setPublicKey] = useState<string>('');
  const timer = useRef<any>(null);
  useEffect(() => {
    API.AccountService.pk().then(({ data }) => setPublicKey(data));
  }, []);

  const handleSubmit = (formVal: Values) => {
    const { password } = formVal;
    setLoading(true);
    const encrypt = new JSEncrypt();
    encrypt.setPublicKey(publicKey);
    const payload = {
      password: encrypt.encrypt(password),
    };
    API.AccountService.fakeAccountChangePassword(payload).then(
      ({ success, errorMsg }) => {
        setLoading(false);
        if (success) {
          setVisible(!visible);
          Session.destroy();
          successCountDown();
        } else {
          message.error(errorMsg);
        }
      },
    );
  };
  const successCountDown = () => {
    let secondsToGo = 5;
    const modal = Modal.success({
      title: '密码修改成功',
      content: `系统将于 ${secondsToGo} 秒后重新登录。`,
      okText: '立即登录',
      onOk: () => {
        clearInterval(timer.current);
        history.push('/passport/sign-in');
      },
    });
    timer.current = setInterval(() => {
      secondsToGo -= 1;
      modal.update((prevConfig) => ({
        ...prevConfig,
        content: `系统将于 ${secondsToGo} 秒后重新登录。`,
      }));
    }, 1000);
    setTimeout(() => {
      clearInterval(timer.current);
      modal.destroy();
      history.push('/passport/sign-in');
    }, secondsToGo * 1000);
  };

  const getData = () => [
    {
      title: '账户密码',
      description: (
        <>
          当前密码强度：
          {passwordStrength.strong}
        </>
      ),
      actions: [
        <a key="Modify" onClick={() => setVisible(!visible)}>
          修改
        </a>,
      ],
    },
  ];
  const data = getData();
  return (
    <>
      <List<Unpacked<typeof data>>
        itemLayout="horizontal"
        dataSource={data}
        renderItem={(item) => (
          <List.Item actions={item.actions}>
            <List.Item.Meta title={item.title} description={item.description} />
          </List.Item>
        )}
      />
      {visible && (
        <SetPassportForm
          visible={visible}
          loading={loading}
          onCancel={() => setVisible(!visible)}
          onCreate={handleSubmit}
        />
      )}
    </>
  );
};

export default SecurityView;

interface Values {
  password: string;
  confirm: string;
}

interface CollectionPassportProps {
  visible: boolean;
  loading?: boolean;
  onCreate?: (values: Values) => void;
  onCancel?: () => void;
}

const SetPassportForm: React.FC<CollectionPassportProps> = ({
  visible,
  loading,
  onCreate,
  onCancel,
}) => {
  const [form] = Form.useForm();
  return (
    <Modal
      visible={visible}
      title="密码修改"
      destroyOnClose
      onCancel={onCancel}
      confirmLoading={loading}
      onOk={() => {
        form.validateFields().then((values) => {
          onCreate && onCreate(values);
        });
      }}
    >
      <Form form={form} layout="vertical">
        <Form.Item
          name="password"
          label="新密码"
          rules={[{ required: true }]}
          hasFeedback
        >
          <Input.Password />
        </Form.Item>
        <Form.Item
          name="confirm"
          label="确认新密码"
          dependencies={['password']}
          hasFeedback
          rules={[
            { required: true },
            ({ getFieldValue }) => ({
              validator(text, value) {
                if (!value || getFieldValue('password') === value) {
                  return Promise.resolve();
                }
                return Promise.reject(new Error('两次输入的密码不一致!'));
              },
            }),
          ]}
        >
          <Input.Password />
        </Form.Item>
      </Form>
    </Modal>
  );
};
