import { ActionSheet, Dialog, InfiniteScroll, List, NavBar, Toast } from 'antd-mobile';
import { useNavigate } from 'react-router-dom';

import { MoreOutline } from 'antd-mobile-icons';
import { useCallback, useEffect, useState } from 'react';

import MeasureItem from '../components/MeasureItem';
import { Measurement } from '../services/apiTypes';
import Bridge, { bridgeOb } from '../utils/bridge';
import { useAppDispatch, useAppSelector } from '../utils/hooks';
import { refreshSyncProgress } from '../store/features/contextSlice';

const PAGE_SIZE = 10;

export default function UploadList() {
  const navigate = useNavigate();
  const dispatch = useAppDispatch();

  const context = useAppSelector((state) => state.context);

  const [showMenu, setShowMenu] = useState(false);
  const [list, setList] = useState<Measurement[]>([]);
  const [noMore, setNoMore] = useState(false);

  const actions = [
    {
      text: '重试上传',
      key: 'retry',
      onClick: async () => {
        setShowMenu(false);
        const res = await Bridge.retryFailureSync();
        if (!res.success) {
          Toast.show(res.message);
        }
      },
    },
    {
      text: '清空列表',
      key: 'clear',
      onClick: () => {
        setShowMenu(false);
        if (context.syncProgress.status === 'uploading') {
          Dialog.confirm({
            content: '存在未完成的任务，确定清空？',
            onConfirm: () => {
              clearSyncList();
            },
          });
        } else {
          clearSyncList();
        }
      },
    },
    {
      text: '清空已完成任务',
      key: 'clearCompleted',
      onClick: async () => {
        setShowMenu(false);
        const res = await Bridge.clearFinishedSync();
        if (res.success) {
          loadData();
        } else {
          Toast.show(res.message);
        }
      },
    },
  ];

  function clearSyncList() {
    Bridge.clearSyncList().then((res) => {
      if (res.success) {
        loadData();
      } else {
        Toast.show(res.message);
      }
    });
  }
  const loadData = useCallback(() => {
    dispatch(refreshSyncProgress());
    Bridge.getSyncTaskList({ pageNum: 1, size: PAGE_SIZE }).then((res) => {
      if (res.success) {
        const nList = res.data.list.map((r) => ({ ...r, extraDescObj: JSON.parse(r.extraDesc) }));
        setList(nList);
        setNoMore(res.data.list.length < PAGE_SIZE);
      } else {
        Toast.show(res.message);
      }
    });
  }, [dispatch]);

  async function loadMoreData() {
    const pageNum = Math.floor(list.length / PAGE_SIZE);
    const res = await Bridge.getSyncTaskList({ pageNum: pageNum + 1, size: PAGE_SIZE });
    if (res.success) {
      const nList = res.data.list.map((r) => ({ ...r, extraDescObj: JSON.parse(r.extraDesc) }));
      setList(list.concat(nList));
      setNoMore(res.data.list.length < PAGE_SIZE);
    } else {
      Toast.show(res.message);
    }
  }

  useEffect(() => {
    loadData();
  }, [loadData]);

  useEffect(() => {
    const subscription = bridgeOb.subscribe((datagram) => {
      if (datagram.type === 'sync-item-finish') {
        const item = list.find((item) => item.id === datagram.data.id);
        if (item) {
          item.syncStatus = datagram.data.success ? 'finish' : 'fail';
        }
      }
    });
    return () => subscription.unsubscribe();
  }, [list]);

  const back = () => navigate(-1);

  const right = (
    <div
      onClick={() => setShowMenu(!showMenu)}
      className="flex justify-end gap-x-2"
      style={{ fontSize: 24 }}
    >
      <MoreOutline />
    </div>
  );

  const statusText = () => {
    if (context.syncProgress.status === 'finished') {
      return '完成';
    } else if (context.syncProgress.status === 'paused') {
      return '暂停';
    } else if (context.syncProgress.status === 'uploading') {
      return '上传中';
    }
  };

  return (
    <div>
      <NavBar className="bg-white" onBack={back} right={right}>
        上传记录
      </NavBar>
      <div className="main-page-content">
        <header className="h-8 bg-[#EEE] flex items-center px-4">
          <span>剩余任务{context.syncProgress.remaining}个</span>
          <i className="border-l border-[#999] h-3 mx-2" />
          <span>失败{context.syncProgress.fail}个</span>
          <p className="ml-auto text-primary">{statusText()}</p>
        </header>
        <main
          className="relative overflow-x-hidden overflow-y-auto"
          style={{ height: 'calc(100% - 32px)' }}
        >
          {list.length > 0 ? (
            <List>
              {list.map((item) => (
                <List.Item key={item.id}>
                  <MeasureItem
                    item={item}
                    onDetail={() => navigate(`/measure/record/${item.id}`)}
                  />
                </List.Item>
              ))}
              <InfiniteScroll loadMore={loadMoreData} hasMore={!noMore} />
            </List>
          ) : (
            <p className="absolute text-title left-1/2 top-1/3 -translate-x-1/2">暂无数据</p>
          )}
        </main>
      </div>
      <ActionSheet visible={showMenu} actions={actions} onClose={() => setShowMenu(false)} />
    </div>
  );
}
