import React, { useCallback, useEffect, useMemo, useState } from "react";
import { Button, Flex, Form, InputNumber, Segmented, Space, Switch } from "antd";
import { chunk } from 'lodash';
import type { BasePlayer } from "../types";
import { GroupMember } from "./GroupMember";
import { sneckGroup } from "../utils/common";
import { useLoaderData } from "react-router";
import { SyncOutlined } from "@ant-design/icons";
import { useRequest } from "ahooks";

interface Player extends BasePlayer {
}

interface CustomPlayer extends Player {
  nowScore: never;
  index: number;
  id: string;
}

interface Props {
  players?: Player[];
  sneckMode: boolean;
  isPassedGame: boolean;
}

enum OrderScore {
  年度积分 = '年度积分',
  当前积分 = '当前积分',
}

export const GroupingPrediction: React.FC<Props> = props => {
  const { uidScore } = useLoaderData<{ uidScore: Map<string, string>}>();
  const uidScoreRequest = useRequest(async () => {
    const uids = props.players?.map(player => player.uid).filter(Boolean);
    const data = await fetch(`/api/user/nowScores`, {
      method: "POST",
      body: JSON.stringify({ uids }),
    }).then(res => res.json()).catch(() => ({}));
    return new Map(Object.entries(data));
  }, { manual: true, refreshDeps: [props.players]});
  console.debug('uidScore', uidScore);
  const [maxPlayerSize, setMaxPlayerSize] = useState(48);
  const [nowScoreGroup, setNowScoreGroup] = useState(
    props.isPassedGame 
      ? OrderScore.年度积分
      : OrderScore.当前积分
  );
  const refactoredPlayers = useMemo(() => {
    return nowScoreGroup === OrderScore.当前积分 ? props.players?.map(e => {
      const nowScore = uidScore.get(e.uid) || uidScoreRequest.data?.get(e.uid);
      return {
        ...e,
        score: !Number.isNaN(Number(nowScore)) ? nowScore : e.score,
      }
    }) : [...props.players ?? []];
  }, [nowScoreGroup, props.players, uidScore, uidScoreRequest]);
  const players = useMemo(() => {
    return (refactoredPlayers as CustomPlayer[]) 
      ?.slice(0, maxPlayerSize)
      ?.sort((a, b) => Number(b.score) - Number(a.score))
      ?.map((e, i) => ({ ...e, index: i + 1, id: `${i}-${e.name}-${e.score}` })) ?? [];
  }, [refactoredPlayers, maxPlayerSize]);
  const [groupLen, setGroupLen] = useState(6);
  useEffect(() => {
    if (props.players) {
      if (players.length < 48) {
        setMaxPlayerSize(players.length);
      }
      if (players.length <= 12) {
        setGroupLen(1);
      }
    }
  }, [props.players?.length]);
  const [sneckMode, setSneckMode] = useState(props.sneckMode);
  const chunkSize = useMemo(() => Math.floor((players.length ?? 0) / groupLen) || 1, [players, groupLen]);
  const grouped = useMemo(() => {
    return chunk(players, chunkSize);
  }, [chunkSize, players]);
  const sneckedGroups = useMemo(() => {
    const sneckIndexGroups = sneckGroup(players.length, groupLen);
    return sneckIndexGroups.map(g => {
      const subGroup = g.map(i => ({
        ...players[i],
      })).filter(Boolean) as CustomPlayer[];
      return subGroup;
    });
  }, [players, grouped, groupLen, maxPlayerSize]);
  const handleSyncUidScore = useCallback(() => {
    uidScoreRequest.runAsync();
  }, []);
  return (
    <>
      <Flex gap={10} wrap>
        <Form.Item label={'取人数'}>
          <InputNumber
            value={maxPlayerSize}
            onChange={e => setMaxPlayerSize(e || props.players?.length || 0)}
            max={props.players?.length}
          />
        </Form.Item>
        <Form.Item label="分组数">
          <InputNumber
            value={groupLen}
            onChange={e => setGroupLen(e ?? 1)}
            min={1}
            max={26}
          />
        </Form.Item>
        <Form.Item label="蛇形分组">
          <Switch checked={sneckMode} onChange={setSneckMode} />
        </Form.Item>
        <Form.Item label="排序积分">
          <Segmented value={nowScoreGroup} onChange={setNowScoreGroup} options={[
            OrderScore.当前积分,
            OrderScore.年度积分,
          ]} />
        </Form.Item>
        <Form.Item hidden={uidScore.size > 0}>
            <Button loading={uidScoreRequest.loading} onClick={handleSyncUidScore} icon={<SyncOutlined />}>
              刷新当前积分
            </Button>
        </Form.Item>
      </Flex>
      <Flex gap='middle' wrap align="center" justify="center">
        <React.Fragment key={'normal'}>
          { !sneckMode && grouped.map((p, i) => <GroupMember key={i} players={p} index={i} />)}
        </React.Fragment>
        <React.Fragment key={'sneck'}>
          { sneckMode && sneckedGroups.map((p, i) => <GroupMember key={i} players={p} index={i} />)}
        </React.Fragment>
      </Flex>
    </>
  );
}