import type {Dispatch, SetStateAction,MutableRefObject} from 'react';
import React, { useEffect, useRef, useState} from 'react';
import type {ProFormProps} from '@ant-design/pro-form/lib/layouts/ProForm';
import type {Attachment, MsgType, WelcomeMsg} from '@/pages/StaffAdmin/CustomerWelcomeMsg/data';
import {
  createFromIconfontCN,
  DragOutlined,
  EditOutlined,
  FileImageOutlined,
  LinkOutlined,
  MinusCircleOutlined,
  PlusCircleOutlined,
  SyncOutlined,
} from '@ant-design/icons';
import defaultSettings from '../../../../../../config/defaultSettings';
import type {FormInstance} from 'antd';
import {Alert, Dropdown, Form, Menu, message, Spin, Tooltip} from 'antd';
import phoneImage from '@/assets/phone.png';
import avatarDefault from '@/assets/avatar-default.svg';
import ContentEditable from 'react-contenteditable';
import {ReactSortable} from 'react-sortablejs';
import ProForm, {
  ModalForm,
  ProFormDependency,
  ProFormSwitch,
  ProFormText,
  ProFormTextArea,
} from '@ant-design/pro-form';
import ImageUploader from '@/pages/StaffAdmin/Components/Fields/ImageUploader';
import styles from './index.less';
import type { GetSignedURLResult} from "@/services/common";
import {GetSignedURL, ParseURL} from "@/services/common";
import type {UploadRequestOption} from "rc-upload/lib/interface";


export type AutoReplyProps = Omit<ProFormProps, 'onFinish' | 'visible' | 'initialValues'> & {
  welcomeMsg: WelcomeMsg;
  setWelcomeMsg: Dispatch<SetStateAction<WelcomeMsg>>;
  isFetchDone: boolean; // 用于标记异步数据是否拉取完毕
  enableQuickInsert?: boolean; // 是否开启快速插入
};

const msgTypes = {
  image: '图片',
  link: '链接',
  miniprogram: '小程序',
  video: '视频',
};

const IconFont = createFromIconfontCN({
  scriptUrl: defaultSettings.iconfontUrl,
});

const itemDataToFormData = (value: WelcomeMsg) => {
  const item = {...value};
  if (item?.attachments) {
    // @ts-ignore
    item.attachments = item?.attachments?.map((attachment: Attachment, index: number) => {
      return {
        ...attachment,
        id: new Date().getTime().toString() + index.toString(),
        name: attachment?.image?.title || attachment?.link?.title || attachment?.miniprogram?.title,
      };
    });
  }

  return item;
};

const AutoReply: React.FC<AutoReplyProps> = (props) => {
  const {welcomeMsg, setWelcomeMsg, isFetchDone} = props;
  const [modalVisible, setModalVisible] = useState(false);
  const [attachments, setAttachments] = useState<Attachment[]>([]);
  const [currentIndex, setCurrentIndex] = useState<number>(0);
  const [currentMode, setCurrentMode] = useState<MsgType>('image');
  const [linkFetching, setLinkFetching] = useState(false);
  const [content, setContent] = useState('');
  const contentRef = useRef<React.RefObject<HTMLElement>>();
  const imageModalFormRef = useRef<FormInstance>();
  const linkModalFormRef = useRef<FormInstance>();
  const miniAppModalFormRef = useRef<FormInstance>();

  const UploadFileFn = async (req: UploadRequestOption, ref: MutableRefObject<any | undefined>, inputName: string) => {
    const file = req.file as File;
    if (!file.name) {
      message.error('非法参数');
      return;
    }

    const hide = message.loading('上传中');
    try {
      const res = await GetSignedURL(file.name)
      const data = res.data as GetSignedURLResult
      if (res.code === 0) {
        const uploadRes = (await fetch(data.upload_url, {
          method: 'PUT',
          body: file
        }));
        hide();
        if (uploadRes.ok && ref) {
          ref.current?.setFieldsValue({[inputName]: data.download_url});
          return;
        }

        message.error('上传图片失败');

        return;
      }

      hide();
      message.error('获取上传地址失败');
      return;

    } catch (e) {
      message.error('上传图片失败');
      console.log(e);
    }
  };

  useEffect(() => {
    const formData = itemDataToFormData(welcomeMsg);
    setAttachments(formData.attachments || []);
    setContent(formData.text || '');
  }, [isFetchDone]);

  useEffect(() => {
    setWelcomeMsg({
      text: content || '',
      attachments: attachments || [],
    });
  }, [content, attachments]);

  return (
    <>
      <div className={styles.replyEditor}>
        <div className={'preview-container'}>
          <div className={styles.replyEditorPreview}>
            <img src={phoneImage} className='bg'/>
            <div className='content'>
              <ul className='reply-list'>
                {content && (
                  <li><img
                    src={avatarDefault}/>
                    <div className='msg text' dangerouslySetInnerHTML={{__html: content}}/>
                  </li>
                )}
                {attachments && attachments.length > 0 && (
                  attachments.map((attachment) => {
                    if (attachment.msgtype === 'image') {
                      return (
                        <li key={attachment.id}>
                          <img src={avatarDefault}/>
                          <div className={`msg image`}>
                            <img src={attachment.image?.pic_url}/>
                          </div>
                        </li>
                      );
                    }

                    if (attachment.msgtype === 'link') {
                      return (
                        <li key={attachment.id}>
                          <img src={avatarDefault}/>
                          <div className='msg link'><p className='title'>{attachment.link?.title}</p>
                            <div className='link-inner'><p
                              className='desc'>{attachment.link?.desc}</p>
                              <img src={attachment.link?.picurl}/>
                            </div>
                          </div>
                        </li>
                      );
                    }

                    if (attachment.msgtype === 'miniprogram') {
                      return (
                        <li key={attachment.id}>
                          <img src={avatarDefault}/>
                          <div className='msg miniprogram'>
                            <p className='m-title'>
                              <IconFont
                                type={'icon-weixin-mini-app'}
                                style={{marginRight: 4, fontSize: 14}}
                              />
                              {attachment.miniprogram?.title}
                            </p>
                            <img src={attachment.miniprogram?.pic_media_id}/>
                            <p className='l-title'>
                              <IconFont type={'icon-weixin-mini-app'} style={{marginRight: 4}}/>
                              小程序
                            </p>
                          </div>
                        </li>
                      );
                    }

                    return '';
                  })
                )}
              </ul>
            </div>
          </div>
        </div>

        <div className='text-area-container'>
          <div className={styles.msgTextareaContainer} style={{border: 'none'}}>
            {props.enableQuickInsert && (
              <div className='insert-btn '>
                    <span
                      className='clickable no-select'
                      onClick={() => {
                        setContent(`${content}[客户昵称]`);
                      }}
                    >[插入客户昵称]</span>
              </div>
            )}
            <div className='textarea-container '>
              <ContentEditable
                // @ts-ignore
                innerRef={contentRef}
                onKeyDown={(event) => {
                  if (event.key === 'Enter') {
                    document.execCommand('insertLineBreak');
                    event.preventDefault();
                  }
                }}
                className={'textarea'}
                html={content}
                onChange={(e) => {
                  setContent(e.target.value);
                }}/>
              <div className='flex-row align-side'>
                <p className='text-cnt'>{content.length}/600</p>
              </div>
            </div>
          </div>
        </div>
        <div className='option-area-container'>
          {attachments && attachments.length > 0 && (
            <ReactSortable handle={'.draggable-button'} tag='ul' className={'select-msg-options'} list={attachments} setList={setAttachments}>
              {attachments.map((attachment, index) => (
                <li key={attachment.id} className='flex-row'>
                      <span>
                        <MinusCircleOutlined
                          onClick={() => {
                            const items = [...attachments];
                            items.splice(index, 1);
                            setAttachments(items);
                          }}
                        />
                        【{msgTypes[attachment.msgtype]}】:
                        <span
                          className='col-1'>{attachment?.name}</span>
                      </span>
                  <span className='d-action-container'>
                      <EditOutlined
                        onClick={() => {
                          setCurrentMode(attachment.msgtype);
                          imageModalFormRef.current?.setFieldsValue(attachment.image);
                          linkModalFormRef.current?.setFieldsValue(attachment.link);
                          miniAppModalFormRef.current?.setFieldsValue(attachment.miniprogram);
                          setCurrentIndex(index);
                          setModalVisible(true);
                        }}
                      />
                      <DragOutlined
                        className={'draggable-button'}
                        style={{cursor: 'grabbing'}}
                      />
                    </span>
                </li>
              ))}
            </ReactSortable>
          )}
          <div className='option-container'>
            <Dropdown
              placement='topLeft'
              trigger={['click']}
              overlay={(
                <Menu style={{minWidth: 120}}>
                  <Menu.Item
                    key={'image'}
                    icon={<FileImageOutlined/>}
                    onClick={() => {
                      setCurrentMode('image');
                      setCurrentIndex(attachments.length);
                      imageModalFormRef.current?.resetFields();
                      setModalVisible(true);
                    }}
                  >
                    图片
                  </Menu.Item>
                  <Menu.Item
                    key={'link'}
                    icon={<LinkOutlined/>}
                    onClick={() => {
                      setCurrentMode('link');
                      setCurrentIndex(attachments.length);
                      setModalVisible(true);
                    }}
                  >
                    链接
                  </Menu.Item>
                  <Menu.Item
                    key={'miniApp'}
                    icon={<IconFont type={'icon-weixin-mini-app'}/>}
                    onClick={() => {
                      setCurrentMode('miniprogram');
                      setCurrentIndex(attachments.length);
                      setModalVisible(true);
                    }}
                  >
                    小程序
                  </Menu.Item>
                </Menu>
              )}
            >
              <a className='ant-dropdown-link' onClick={e => e.preventDefault()}>
                <PlusCircleOutlined/> 添加附件
              </a>
            </Dropdown>
          </div>
        </div>
      </div>

      <ModalForm
        formRef={imageModalFormRef}
        className={'dialog from-item-label-100w'}
        layout={'horizontal'}
        width={'560px'}
        visible={currentMode === 'image' && modalVisible}
        onVisibleChange={setModalVisible}
        onFinish={async (params: { title: string, pic_url: string, msgtype: MsgType }) => {
          attachments[currentIndex] = {
            id: new Date().getTime().toString(),
            msgtype: params.msgtype,
            name: params.title,
            image: {...params},
          };
          setAttachments(attachments);
          return true;
        }}
      >
        <h2 className='dialog-title'> 添加图片附件 </h2>
        <ProForm.Item initialValue={'image'} name={'msgtype'} noStyle={true}>
          <input type={'hidden'}/>
        </ProForm.Item>
        <ProFormText
          name='title'
          label='图片名称'
          placeholder={'请输入图片名称'}
          width='md'
          rules={[
            {
              required: true,
              message: '请输入图片名称!',
            },
          ]}
        />
        <Form.Item
          label='上传图片'
          name='pic_url'
          rules={[
            {
              required: true,
              message: '请上传图片!',
            },
          ]}
        >
          <ImageUploader
            customRequest={async (req) => {
              await UploadFileFn(req, imageModalFormRef, 'pic_url')
            }}
          />
        </Form.Item>
      </ModalForm>


      <ModalForm
        formRef={linkModalFormRef}
        className={'dialog from-item-label-100w'}
        layout={'horizontal'}
        width={'560px'}
        visible={currentMode === 'link' && modalVisible}
        onVisibleChange={setModalVisible}
        onFinish={async (params) => {
          attachments[currentIndex] = {
            id: new Date().getTime().toString(),
            msgtype: params.msgtype,
            name: params.title,
            // @ts-ignore
            link: {...params},
          };
          setAttachments(attachments);
          return true;
        }}
      >
        <Spin spinning={linkFetching}>
          <h2 className='dialog-title'> 添加链接附件 </h2>
          <ProForm.Item initialValue={'link'} name={'msgtype'} noStyle={true}>
            <input type={'hidden'}/>
          </ProForm.Item>
          <ProFormText
            name='url'
            label='链接地址'
            width='md'
            fieldProps={{
              disabled: linkFetching,
              addonAfter: (
                <Tooltip title="点击抓取远程链接,自动填充标题,描述,图片">
                  <div
                    onClick={async () => {
                      setLinkFetching(true);
                      const res = await ParseURL(linkModalFormRef.current?.getFieldValue('url'))
                      setLinkFetching(false);
                      if (res.code !== 0) {
                        message.error(res.message);
                      } else {
                        message.success('解析链接成功');
                        linkModalFormRef?.current?.setFieldsValue({
                          customer_link_enable: 1,
                          title: res.data.title,
                          desc: res.data.desc,
                          picurl: res.data.img_url,
                        })
                      }
                    }}
                    style={{
                      cursor: "pointer",
                      width: 32,
                      height: 30,
                      display: 'flex',
                      alignItems: 'center',
                      justifyContent: 'center'
                    }}>
                    <SyncOutlined/>
                  </div>
                </Tooltip>
              )
            }}
            rules={[
              {
                required: true,
                message: '请输入链接地址',
              },
              {
                type: 'url',
                message: '请填写正确的的URL,必须是http或https开头',
              },
            ]}
          />
          <ProFormSwitch
            label={'高级设置'}
            checkedChildren='开启'
            unCheckedChildren='关闭'
            name='customer_link_enable'
            tooltip={'开启后可以自定义链接所有信息'}
          />
          <ProFormDependency name={['customer_link_enable']}>
            {({customer_link_enable}) => {
              if (customer_link_enable) {
                return (
                  <>
                    <ProFormText
                      name='title'
                      label='链接标题'
                      width='md'
                      rules={[
                        {
                          required: true,
                          message: '请输入链接标题',
                        },
                      ]}
                    />
                    <ProFormTextArea
                      name='desc'
                      label='链接描述'
                      width='md'
                    />
                    <Form.Item
                      label='链接封面'
                      name='picurl'
                      rules={[
                        {
                          required: true,
                          message: '请上传链接图片!',
                        },
                      ]}
                    >
                      <ImageUploader
                        customRequest={async (req) => {
                          await UploadFileFn(req, linkModalFormRef, 'picurl')
                        }}
                      />
                    </Form.Item>
                  </>
                );
              }
              return <></>;
            }}
          </ProFormDependency>
        </Spin>
      </ModalForm>


      <ModalForm
        formRef={miniAppModalFormRef}
        className={'dialog from-item-label-100w'}
        layout={'horizontal'}
        width={'560px'}
        labelCol={{
          md: 6,
        }}
        visible={currentMode === 'miniprogram' && modalVisible}
        onVisibleChange={setModalVisible}
        onFinish={async (params) => {
          attachments[currentIndex] = {
            id: new Date().getTime().toString(),
            msgtype: params.msgtype,
            name: params.title,
            // @ts-ignore
            miniprogram: {...params},
          };
          setAttachments(attachments);
          return true;
        }}
      >
        <h2 className='dialog-title'> 添加小程序附件 </h2>

        <Alert
          showIcon={true}
          type='info'
          message={
            '请填写企业微信后台绑定的小程序id和路径,否则会造成发送失败'
          }
          style={{marginBottom: 20}}
        />

        <ProForm.Item initialValue={'miniprogram'} name={'msgtype'} noStyle={true}>
          <input type={'hidden'}/>
        </ProForm.Item>

        <ProFormText
          name='title'
          label='小程序标题'
          width='md'
          rules={[
            {
              required: true,
              message: '请输入链接标题',
            },
          ]}
        />

        <ProFormText
          // 帮助指引
          name='app_id'
          label='小程序AppID'
          width='md'
          rules={[
            {
              required: true,
              message: '请输入小程序AppID',
            },
          ]}
        />

        <ProFormText
          name='page'
          label='小程序路径'
          width='md'
          rules={[
            {
              required: true,
              message: '请输入小程序路径',
            },
          ]}
        />

        <Form.Item
          label='小程序封面'
          name='pic_media_id'
          rules={[
            {
              required: true,
              message: '请小程序封面!',
            },
          ]}
        >
          <ImageUploader
            customRequest={async (req) => {
              await UploadFileFn(req, miniAppModalFormRef, 'pic_media_id')
            }}
          />
        </Form.Item>

      </ModalForm>

    </>
  );
};

export default AutoReply;