import React, { FC, Suspense, useEffect, useRef, useState } from 'react';
import style from './Score.module.scss';
import Bmob from 'hydrogen-js-sdk';
import {
    PLAYING_THEME_ID_STORAGE_KEY,
    randomString,
    timestampToUsedTimeString,
    USER_ID_STORAGE_KEY,
    USER_NAME_STORAGE_KEY,
} from '../utils';
import WxQrCode from './WxQrCode';

const Fireworks = React.lazy(() => import('./Fireworks'));

interface RankInfo {
    // id
    objectId?: string;
    // 综合评分
    rating: number;
    // 通关数
    level: number;
    // 游戏得分
    score: number;
    // 主题id
    themeId: string;
    // 耗时
    time: number;
    // 用户昵称
    username: string;
    // 用户id
    userId: string;
}

// 该组件条件渲染
const Score: FC<{
    level: number;
    score: number;
    time: number;
    success: boolean;
    restartMethod: () => void;
}> = ({ level, score, time, success, restartMethod }) => {
    const [rankList, setRankList] = useState<RankInfo[]>([]);
    const [username, setUsername] = useState<string>(
        localStorage.getItem(USER_NAME_STORAGE_KEY) || ''
    );
    const [userId, setUserId] = useState<string>(
        localStorage.getItem(USER_ID_STORAGE_KEY) || ''
    );
    const usernameInputRef = useRef<HTMLInputElement>(null);
    const [tip, setTip] = useState<string>('');

    // 综合评分
    const rating = Math.max(0, score) * 100 - Math.round(time / 1000);
    // 分主题排行
    const themeId = localStorage.getItem(PLAYING_THEME_ID_STORAGE_KEY);

    const uploadRankInfo = (id?: string) => {
        const _userId = localStorage.getItem(USER_ID_STORAGE_KEY);
        const _username = localStorage.getItem(USER_NAME_STORAGE_KEY);
        if (!themeId || !_userId || !_username) return;
        const rankInfo: RankInfo = {
            rating,
            themeId,
            level,
            score,
            time,
            username: _username,
            userId: _userId,
        };
        const query = Bmob.Query('rank');
        id && query.set('id', id);
        for (const [key, val] of Object.entries(rankInfo)) {
            query.set(key, val);
        }
        query
            .save()
            .then(() => {
                getRankList();
            })
            .catch((e) => {
                console.log(e);
            });
    };

    const getRankList = (cb?: (rankList: RankInfo[]) => void) => {
        if (!themeId) return;
        const query = Bmob.Query('rank');
        query.equalTo('themeId', '==', themeId);
        query.order('-rating');
        query.limit(50);
        query
            .find()
            .then((res) => {
                setRankList(res as any);
                cb && cb(res as any);
                const _userId = localStorage.getItem(USER_ID_STORAGE_KEY);
                if (_userId) {
                    setTimeout(() => {
                        const rankEl = document.getElementById(_userId + 'el');
                        rankEl?.scrollIntoView({ behavior: 'smooth' });
                    });
                }
            })
            .catch((e) => {
                console.log(e);
            });
    };

    const onConfirmNameClick = () => {
        const inputUsername = usernameInputRef.current?.value;
        if (!inputUsername) return;
        const newUserId = randomString(8);
        setUsername(inputUsername);
        setUserId(newUserId);
        localStorage.setItem(USER_NAME_STORAGE_KEY, inputUsername);
        localStorage.setItem(USER_ID_STORAGE_KEY, newUserId);
        judgeAndUpload(rankList, newUserId);
    };

    // 判断是否需要上传记录
    const judgeAndUpload = (_rankList: RankInfo[], _userId: string) => {
        if (!_userId) return;
        if (
            _rankList.length < 50 ||
            rating > _rankList[_rankList.length - 1].rating
        ) {
            // 榜未满或者分数高于榜上最后一名
            // 本次排名
            let thisRank = _rankList.findIndex((rank) => rank.rating < rating);
            if (thisRank === -1) {
                thisRank = _rankList.length + 1;
            } else {
                thisRank++;
            }
            // 查找是否曾上榜
            const findSelf = _rankList.findIndex(
                (rank) => rank.userId === _userId
            );
            if (findSelf === -1) {
                // 新上榜
                uploadRankInfo();
                setTip(`恭喜上榜！本次排名${thisRank}`);
            } else {
                if (_rankList[findSelf].rating < rating) {
                    // 破自己记录
                    uploadRankInfo(_rankList[findSelf].objectId);
                    setTip(`个人新高！本次排名${thisRank}`);
                } else if (_rankList[findSelf].rating > rating) {
                    // 没破自己记录
                    setTip(
                        `距离你的最高记录${_rankList[findSelf].rating}还差一点～`
                    );
                } else {
                    setTip(`与你的最高记录${_rankList[findSelf].rating}持平～`);
                }
            }
        } else {
            // 未上榜
            setTip('本次未上榜');
        }
    };

    useEffect(() => {
        if (!__DIY__) {
            // 排行榜
            getRankList((rankList) =>
                judgeAndUpload(
                    rankList,
                    localStorage.getItem(USER_ID_STORAGE_KEY) || ''
                )
            );
        }
    }, []);

    return (
        <div className={style.modal}>
            <Suspense fallback={<span>fireworks</span>}>
                {success && <Fireworks />}
            </Suspense>
            <div className={style.inner}>
                {success ? <h1>🎉恭喜通关！</h1> : <h1>😫就差一点！</h1>}
                <table>
                    <thead>
                        <tr>
                            <th>通关数</th>
                            <th>用时</th>
                            <th>得分</th>
                            <th>综合评分</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>{level}</td>
                            <td>{timestampToUsedTimeString(time)}</td>
                            <td>{score}</td>
                            <td>{rating}</td>
                        </tr>
                    </tbody>
                </table>

                {!__DIY__ && !username && (
                    <div className={'flex-container flex-center'}>
                        <input
                            className={style.nameInput}
                            ref={usernameInputRef}
                            placeholder={'留下大名进行排行榜pk!'}
                        />
                        <button
                            className={'primary'}
                            onClick={onConfirmNameClick}
                        >
                            确定
                        </button>
                    </div>
                )}

                <div>{tip}</div>

                {!__DIY__ && (
                    <div className={style.rankContainer}>
                        <h1 className={style.title}>TOP 50</h1>
                        {rankList.length ? (
                            <div className={style.list}>
                                <table>
                                    <thead>
                                        <tr>
                                            <th>名次</th>
                                            <th>名称</th>
                                            <th>通关数</th>
                                            {/*<th>用时</th>*/}
                                            {/*<th>得分</th>*/}
                                            <th>综合评分</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        {rankList.map((rank, idx) => (
                                            <tr
                                                key={idx}
                                                id={rank.userId}
                                                style={{
                                                    background:
                                                        rank.userId === userId
                                                            ? 'rgb(0 0 0 / 20%)'
                                                            : '',
                                                }}
                                            >
                                                <td>{idx + 1}</td>
                                                <td>
                                                    {rank.username}
                                                    {rank.userId === userId &&
                                                        '(你)'}
                                                </td>
                                                <td>{rank.level}</td>
                                                {/*<td>*/}
                                                {/*    {timestampToUsedTimeString(*/}
                                                {/*        rank.time*/}
                                                {/*    )}*/}
                                                {/*</td>*/}
                                                {/*<td>{rank.score}</td>*/}
                                                <td>{rank.rating}</td>
                                            </tr>
                                        ))}
                                    </tbody>
                                </table>
                            </div>
                        ) : (
                            <div className={style.tip}>
                                暂无排行，速速霸榜！
                            </div>
                        )}
                        <button className={'primary'} onClick={restartMethod}>
                            再来一次
                        </button>
                    </div>
                )}
                <WxQrCode />
            </div>
        </div>
    );
};

export default Score;
