import { Avatar, Button, Card, Divider, Flex, Image, message as AntdMessage, Popconfirm, Radio, Segmented, Spin, Typography } from "antd";
import { useFavPlayerStore } from "../store/useFavPlayerStore";
import { useNavigate } from "react-router";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useLogto, type IdTokenClaims } from "@logto/react";
import { DeleteOutlined, LoginOutlined, SyncOutlined, UploadOutlined } from "@ant-design/icons";
import { useRequest } from "ahooks";
import type { XCXProfile } from "../types";
import useAutoLogin from "../hooks/useAutoLogin";
import { useAuthHeaders } from "../hooks/useAuthHeaders";

enum SortType {
  DEFAULT = '注册时间',
  SCORE_UP = '积分升序',
  SCORE_DOWN = '积分降序',
}
enum ShowType {
  LOCAL = '本地收藏',
  ACCOUNT = '账号收藏',
}

export function FavePlayersPage() {
  const [message, contextHolder] = AntdMessage.useMessage();
  const { favMap, unFav } = useFavPlayerStore(state => state);
  const [sortType, setSortType] = useState<SortType>(SortType.DEFAULT);
  const [showType, setShowType] = useState(ShowType.LOCAL);
  const [claims, setClaims] = useState<IdTokenClaims>();
  const headers = useAuthHeaders();
  const { login } = useAutoLogin();
  const localList = Object.values(favMap);
  const favListRequest = useRequest<XCXProfile[], [string]>(async (aud: string) => {
    const res = await fetch(`/api/fav`, { headers });
    const data = await res.json();
    return data;
  }, { manual: true, cacheKey: 'favListRequest', cacheTime: 3 * 60 * 1000 });

  const list = useMemo(() => {
    const l = showType === ShowType.LOCAL ? localList : favListRequest.data?.map(e => ({
      ...e,
      name: e.username,
      avatar: e.realpic,
    })) || [];
    switch (sortType) {
      case SortType.DEFAULT: return l;
      case SortType.SCORE_UP: return l.sort(({ score: a }, { score: b }) => +a - +b);
      case SortType.SCORE_DOWN: return l.sort(({ score: b }, { score: a }) => +a - +b);
      default: return localList;
    }
  }, [favMap, sortType, showType, localList, favListRequest]);
  const navigate = useNavigate();
  const { isAuthenticated, getIdTokenClaims } = useLogto();
  useEffect(() => {
    if (!isAuthenticated) return;
    const id = setTimeout(async () => {
      const claims = await getIdTokenClaims();
      setClaims(claims);
      favListRequest.runAsync(claims?.aud!);
    }, 300);
    return () => clearTimeout(id);
  }, [isAuthenticated, getIdTokenClaims]);
  const handleSyncFav = useCallback(async () => {
    if (!isAuthenticated) return;
    const claims = await getIdTokenClaims()!;
    const aud = claims?.aud;
    const jobs = list.map(async u => {
      await fetch(`/api/fav/${u.uid}`, { method: 'PUT', headers });
    });
    message.open({ key: 'sync', content: '同步中...', type: 'loading' });
    await Promise.all(jobs);
    await favListRequest.runAsync(aud!);
    message.open({ key: 'sync', content: '已同步', type: 'success' });
  }, [isAuthenticated, list]);
  const handleClearLocal = useCallback(() => {
    list.forEach(e => unFav(e.uid));
  }, []);
  return (
    <div className="app">
      {contextHolder}
      <Flex vertical gap={48}>
        <Typography.Title>收藏的球员</Typography.Title>
        <Flex justify="center" align="center" gap={12} style={{ display: isAuthenticated ? '' : 'none' }}>
          <Radio.Group
            optionType="button"
            value={showType}
            onChange={e => setShowType(e.target.value)}
            options={[
              { label: `${ShowType.LOCAL}(${localList.length})`, value: ShowType.LOCAL},
              { label: `${ShowType.ACCOUNT}(${favListRequest.data?.length ?? 0})`, value: ShowType.ACCOUNT}
            ]}
          />
          <Button
            onClick={async () => favListRequest.runAsync(claims?.aud!)}
            icon={<SyncOutlined spin={favListRequest.loading} />}
          />
        </Flex>
        <div style={{ position: 'sticky', zIndex: 1 }}>
          <Segmented
            value={sortType}
            onChange={e => setSortType(e)}
            options={[
              SortType.DEFAULT,
              SortType.SCORE_UP,
              SortType.SCORE_DOWN,
            ]}
          />
        </div>
        <Spin spinning={showType === ShowType.ACCOUNT && favListRequest.loading}>
          {!favListRequest.loading && list.length === 0 ? (
            <>
              <Divider>暂无收藏的球员</Divider>
            </>
          ) : (
            <>
              <Flex wrap gap={16} align="center" justify="center">
                {list.map(e => (
                  <Card
                    hoverable
                    size="small"
                    key={e.uid}
                    style={{ width: 240 }}
                  >
                    <Flex gap={12}>
                      {e.avatar?.includes('noavatar')
                        ? <Avatar size={64} shape="square">{e.name}</Avatar>
                        : <Image width={64} height={64} src={e.avatar} style={{ objectFit: 'cover' }} />}
                      <Flex
                        vertical
                        justify="center"
                        align="center"
                        style={{ flex: 1 }}
                        onClick={() => navigate(`/profile/${e.uid}`)}
                      >
                        <h2 style={{ margin: 0 }}>{e.name}</h2>
                        <Typography.Text type="secondary">{e.realname}</Typography.Text>
                      </Flex>
                    </Flex>
                  </Card>
                ))}
              </Flex>
              <Flex vertical gap={12} style={{ marginTop: 12 }}>
                { (showType === ShowType.LOCAL && isAuthenticated && list.length > 0) && (
                  <Button onClick={handleSyncFav} icon={<UploadOutlined />}>同步到云端</Button>
                ) }
                { (showType === ShowType.LOCAL && !isAuthenticated && list.length > 0) && (
                  <Button
                    onClick={() => login(window.location.pathname)}
                    icon={<LoginOutlined />}
                  >登陆后可同步收藏球员</Button>
                ) }
                {(showType === ShowType.LOCAL && (
                  <Popconfirm
                    title='确定要清空本地收藏吗？该操作不可恢复。'
                    onConfirm={handleClearLocal}
                    okText='清空'
                    cancelText='取消'
                    okButtonProps={{ danger: true, icon: <DeleteOutlined /> }}
                  >
                    <Button danger icon={<DeleteOutlined />}>清空</Button>
                  </Popconfirm>
                ))}
              </Flex>
            </>
          )}
        </Spin>
      </Flex>
    </div>
  );
}