import { CheckCircleFilled } from "@ant-design/icons";

import {
  sendHsNotReady,
  sendHsReady,
  sendHsToDuelList,
  sendHsToObserver,
  sendUpdateDeck,
  ygopro,
} from "@/api";
import socketMiddleWare, { socketCmd } from "@/middleware/socket";
import PlayerState = ygopro.StocHsPlayerChange.State;
import SelfType = ygopro.StocTypeChange.SelfType;
import { Avatar, Button, ConfigProvider, Skeleton, Space } from "antd";
import classNames from "classnames";
import { useState } from "react";
import { useNavigate } from "react-router-dom";
import { useSnapshot } from "valtio";

import { useConfig } from "@/config";
import { accountStore, deckStore, IDeck, Player, roomStore } from "@/stores";
import { Background, IconFont, Select, SpecialButton } from "@/ui/Shared";

import { Chat } from "./Chat";
import styles from "./index.module.scss";
import { MoraPopover, TpPopover } from "./Popover";

const NeosConfig = useConfig();

const theme = {
  components: {
    Button: {
      lineWidth: 0,
      fontSizeLG: 14,
      fontSize: 12,
      colorBgContainer: "hsla(0, 0%, 100%, 0.05)",
      colorPrimaryHover: "#ccc",
      colorPrimaryActive: "#aaa",
    },
    Popover: {
      colorBgElevated: "hsla(0, 0%, 100%, 0.1)",
    },
  },
};

export const Component: React.FC = () => {
  const { user } = useSnapshot(accountStore);
  const [collapsed, setCollapsed] = useState(false);
  const { decks } = useSnapshot(deckStore);
  const [deck, setDeck] = useState<IDeck>(JSON.parse(JSON.stringify(decks[0])));
  const room = useSnapshot(roomStore);

  return (
    <ConfigProvider theme={theme}>
      <div
        className={classNames(styles.container, {
          [styles.collapsed]: collapsed,
        })}
      >
        <Background />
        <div className={styles.sider}>
          <Chat />
        </div>
        <div className={styles.content}>
          <SideButtons
            collapsed={collapsed}
            switchCollapse={() => setCollapsed(!collapsed)}
          />
          <div className={styles.wrap}>
            <Controller
              onDeckChange={(deckName: string) => {
                const deck = deckStore.get(deckName);
                // 同步后端
                if (deck) {
                  setDeck(deck);
                } else {
                  alert(`Deck ${deckName} not found`);
                }
              }}
            />
            <div className={styles["both-side-container"]}>
              <PlayerZone
                who={Who.Me}
                player={room.getMePlayer()}
                avatar={user?.avatar_url}
                btn={
                  <>
                    <Button
                      size="large"
                      className={styles["btn-join"]}
                      onClick={() => {
                        if (
                          room.getMePlayer()?.state === PlayerState.NO_READY
                        ) {
                          sendUpdateDeck(deck);
                          window.myExtraDeckCodes = [...deck.extra];
                          sendHsReady();
                        } else {
                          sendHsNotReady();
                        }
                      }}
                    >
                      {room.getMePlayer()?.state === PlayerState.NO_READY
                        ? "决斗准备"
                        : "取消准备"}
                    </Button>
                  </>
                }
              />
              <PlayerZone who={Who.Op} player={room.getOpPlayer()} />
            </div>
            <ActionButton />
          </div>
        </div>
      </div>
    </ConfigProvider>
  );
};

enum Who {
  Me = "me",
  Op = "op",
}

// 玩家区域: 双方各有一个
const PlayerZone: React.FC<{
  btn?: React.ReactNode; // 在内部右侧可以放一个按钮
  who?: Who;
  player?: Player;
  avatar?: string; // 因为对手的头像目前不清楚如何获取，因此暂时这里作为一个参数传入
}> = ({ btn, who, player, avatar }) => {
  return (
    <div className={classNames(styles["side-box"], who && styles[who])}>
      <div className={styles.inner}></div>
      <div style={{ position: "relative" }}>
        <Avatar
          src={
            avatar && player
              ? avatar
              : player && player.state != PlayerState.LEAVE
              ? `${NeosConfig.assetsPath}/default-avatar.png`
              : ""
          }
          size={48}
        />
        {player?.state === PlayerState.READY && (
          <CheckCircleFilled className={styles.check} />
        )}
      </div>
      <div className={styles.name}>
        {player && player.state != PlayerState.LEAVE ? (
          player.name
        ) : (
          <Skeleton.Input size="small" />
        )}
      </div>
      {btn}
    </div>
  );
};

const Controller: React.FC<{ onDeckChange: (deckName: string) => void }> = ({
  onDeckChange,
}) => {
  const snapDeck = useSnapshot(deckStore);
  const snapRoom = useSnapshot(roomStore);
  return (
    <Space>
      <Select
        title="卡组"
        showSearch
        style={{ width: 250 }}
        defaultValue={snapDeck.decks[0].deckName}
        options={snapDeck.decks.map((deck) => ({
          value: deck.deckName,
          title: deck.deckName,
        }))}
        onChange={
          // @ts-ignore
          (value) => onDeckChange(value)
        }
      />
      <Button
        size="large"
        icon={<IconFont type="icon-record" size={18} />}
        onClick={() => {
          if (snapRoom.selfType != SelfType.OBSERVER) {
            sendHsToObserver();
          } else {
            sendHsToDuelList();
          }
        }}
      >
        {snapRoom.selfType == SelfType.OBSERVER ? "加入决斗者" : "加入观战"}
        <Avatar.Group className={styles["avatars-watch"]}>
          {Array.from({ length: snapRoom.observerCount }).map((_, idx) => (
            <Avatar
              key={idx}
              src={`${NeosConfig.assetsPath}/default-avatar.png`}
              size="small"
            />
          ))}
        </Avatar.Group>
      </Button>
    </Space>
  );
};

const SideButtons: React.FC<{
  switchCollapse: () => void;
  collapsed: boolean;
}> = ({ switchCollapse, collapsed }) => {
  const navigate = useNavigate();
  return (
    <div className={styles["btns-side"]}>
      <Button
        className={styles["btn"]}
        danger
        icon={
          <span className={styles["btn-icon"]}>
            <IconFont type="icon-exit" size={17} />
            <span className={styles["btn-text"]}>&#20;&#20;退出房间</span>
          </span>
        }
        onClick={() => {
          // 断开websocket🔗，
          socketMiddleWare({ cmd: socketCmd.DISCONNECT });
          // 返回上一个路由
          navigate("..");
        }}
      />
      <Button
        className={styles["btn"]}
        icon={
          <span className={styles["btn-icon"]}>
            <IconFont type="icon-side-bar-fill" size={16} />
            <span className={styles["btn-text"]}>
              &#20;&#20;{collapsed ? "展开" : "收起"}侧栏
            </span>
          </span>
        }
        onClick={switchCollapse}
      />
    </div>
  );
};

const ActionButton: React.FC = () => {
  return (
    <MoraPopover>
      <TpPopover>
        <SpecialButton className={styles["btns-action"]} disabled={false}>
          <>
            <IconFont type="icon-play" size={12} />
            开始游戏
          </>
          {/* <>
          <IconFont type="icon-mora" size={18} />
          <span>请猜拳</span>
        </> */}
          <>
            {/* 这里要把disabled设为true */}
            {/* <LoadingOutlined size={20} />
          <span>等待对方猜拳</span> */}
          </>
          {/* <>
          <IconFont type="icon-one" size={18} />
          <span>请选择先后手</span>
        </> */}
          <>
            {/* 这里要把disabled设为true */}
            {/* <LoadingOutlined size={20} />
          <span>等待选择先后手</span> */}
          </>
        </SpecialButton>
      </TpPopover>
    </MoraPopover>
  );
};
