import { chunk } from "lodash";
import type { Player } from "../types";

export const KAIQIU_BASE_URL = `https://kaiqiuwang.cc`;
export const LOGTO_DOMAIN = 'https://logto.ksr.la';
export const LOGTO_APPID = 'iq0oceaeqazpcned7hzil';

export function sneckGroup(size: number, groupLen: number) {
  const indexArray = new Array<number>(size).fill(0).map((_, i) => i);
  const chunckSize = Math.round((size / groupLen));
  const chunckedGroup = chunk(indexArray, groupLen);
  const reversedGroup = chunckedGroup.map((e, i) => {
    if (i % 2 === 0) return e;
    return [...e].reverse();
  });
  const newGroups: number[][] = [];
  for (let groupIndex = 0; groupIndex < groupLen; groupIndex++) {
    const group: number[] = [];
    for (let colIndex = 0; colIndex < chunckSize; colIndex++) {
      const data = reversedGroup[colIndex]?.[groupIndex];
      group.push(data === undefined ? NaN : data);
    }
    newGroups.push(group);
  }
  return newGroups;
}

export function getRoundTable<T>(dataList: T[], round: number) {
  const list = [...dataList];
  const half = list.length / 2;
  if (round > list.length - 1) {
    const left = [...list].slice(0, half);
    const right = [...list].slice(half);
    return [left, right];
  }
  const sliceStart = (list.length) - round;
  const slice = list.slice(sliceStart);
  // console.debug(JSON.stringify({ list }));
  list.splice(sliceStart);
  const [first, ...others] = list;
  const newList = [first, ...slice, ...others].filter(Boolean);
  // console.debug(JSON.stringify({ sliceStart, len: list.length, first, others, slice, newList }));
  const left = [...newList].slice(0, half);
  const right = [...newList].slice(half).reverse();
  return [left, right];
}

export function createGameID(matchId: string, user1: string, user2: string) {
  return [matchId, user1, user2].join('-');
}

export function higherWin(absScore: number) {
  if (absScore <= 12) return 8;
  if (absScore <= 37) return 7;
  if (absScore <= 62) return 6;
  if (absScore <= 87) return 5;
  if (absScore <= 112) return 4;
  if (absScore <= 137) return 3;
  if (absScore <= 162) return 2;
  if (absScore <= 187) return 2;
  if (absScore <= 212) return 1;
  if (absScore <= 237) return 1;
  return 0;
}

export function lowerWin(absScore: number) {
  if (absScore <= 12) return 8;
  if (absScore <= 37) return 10;
  if (absScore <= 62) return 13;
  if (absScore <= 87) return 16;
  if (absScore <= 112) return 20;
  if (absScore <= 137) return 25;
  if (absScore <= 162) return 30;
  if (absScore <= 187) return 35;
  if (absScore <= 212) return 40;
  if (absScore <= 237) return 45;
  return 50;
}

export function calculate(winerScore: number, loserScore: number) {
  const absScore = Math.abs(winerScore - loserScore);
  if (winerScore >= loserScore) {
    console.debug('higherWin', absScore, { winerScore, loserScore });
    return higherWin(absScore);
  } else {
    console.debug('lowerWin', absScore, { winerScore, loserScore });
    return lowerWin(absScore);
  }
}

export type WsServerSendTopicPayload = {
  MEMBER_CHANGE: number;
  MY_CLIENT_ONLINE: number;
  DEBUG_MSG: string;
  EVENT_MEMBER_CHANGE: {
    event: string;
    memberNum: number;
  };
  MSG: { channel: string; name: string; avatar: string; message: string };
  SERVER_PUSH: {
    title: string;
    options?: NotificationOptions & {
      data?: {
        url?: string;
      }
    },
  };
}

export type WsServerSendTopics = keyof WsServerSendTopicPayload;

export type WsWebSendTopicPayload = {
  UNKONOW: undefined;
  SUB: { topic: string };
  UNSUB: { topic: string };
  MSG: { channel: string; name: string; avatar: string; message: string };
}

export type WsWebSendTopics = keyof WsWebSendTopicPayload;

export type WsTopicPayload = WsServerSendTopicPayload & WsWebSendTopicPayload;
export type WsTopics = keyof WsTopicPayload;

export function ensureTopicData<T extends WsTopics>(data: any): WsTopicPayload[T] | undefined {
  return data;
}

export function getEventSubKey(eventId: string) {
  return `event:${eventId}`;
}

export function toWebProcessMessage(
  topic: WsTopics,
  data: WsTopicPayload[WsTopics],
) {
  return JSON.stringify({ topic, data });
}

export function fromCustomMessage(message: string): {
  clientTopic: WsWebSendTopics;
  data?: WsWebSendTopicPayload[WsWebSendTopics];
} {
  try {
    const { topic: clientTopic, data } = JSON.parse(message);
    return { clientTopic, data };
  } catch(e) {
    return {
      clientTopic: 'UNKONOW',
      data: undefined,
    };
  }
}

export function fromServerMessage(message: string): {
  topic: WsServerSendTopics;
  data?: WsServerSendTopicPayload[WsServerSendTopics];
} {
  try {
    const { topic, data } = JSON.parse(message);
    return { topic, data };
  } catch(e) {
    return {
      topic: 'DEBUG_MSG',
      data: `${e}`,
    };
  }
}


export function diffArrays(array: Set<string>, compare: Set<string>) {
  const deletedSet = new Set(array);
  const newSet = new Set<string>();
  for (const item of compare) {
    if (deletedSet.has(item)) {
      deletedSet.delete(item);
    } else {
      newSet.add(item);
    }
  }
  return {
    deletedList: deletedSet.values().toArray(),
    newMemberList: newSet.values().toArray(),
  }
}