import MainControlData from "@/Common/DataReceived/MainControlData";
import MainControl, { DownloadForm } from "@/Common/MainControl/MainControl";
import BusinessTypeSetting, { BusinessEnum } from "@/_BusinessTypeSetting/BusinessTypeSetting";
import { GameData } from "@/define/gameData";
import { PlayerData } from "@/define/playerData";
import { IGameItems } from "@/types";
import { ReactNode, createContext, useContext, useState } from "react";

type GameItemsProviderProps = {
	children: ReactNode;
};
const GameItemsContext = createContext<IGameItems>(undefined);

export function useGameItems() {
	return useContext(GameItemsContext);
}
export let gameObj: IGameItems = null;

export function GameItemsProvider({ children }: GameItemsProviderProps) {
	const [player, setPlayer] = useState<PlayerData>(initPlayerData());
	const [gameData, setGameData] = useState<GameData>(initGameData());

	const game: IGameItems = gameObj = {
		onLoad,
		player,
		setPlayer,
		gameData,
		setGameData
	};

	async function onLoad(serverType: BusinessEnum.ServerType, override?: ConnectionOverride) {
		new MainControl();
		new MainControlData();
		await Promise.all([
			// 設定執行環境
			setBusinessType(serverType, override),

			// // 設定LineTools環境
			// await setLineTools(),

			// DownloadForm
			await MainControl.DownloadForm(DownloadForm.FormType.Formread)
		]);
	}

	/** 設定執行環境 */
	function setBusinessType(useServerType: BusinessEnum.ServerType, override?: ConnectionOverride): void {
		// 連線參數自定義
		const queryParameters = new URLSearchParams(location.search);
		const servertype: string = queryParameters.get("servertype") ?? useServerType.toString();
		const host: string = queryParameters.get("host");
		const port: string = queryParameters.get("port");
		const patch: string = queryParameters.get("patch");
		const downloadurl: string = queryParameters.get("downloadurl");
		const liffid: string = queryParameters.get("liffid");
		if (servertype) {
			// 自定預設環境
			BusinessTypeSetting.UseServerType = +servertype;
			BusinessTypeSetting.UseHost = BusinessTypeSetting.GetHostUrl(BusinessTypeSetting.UseServerType);
			BusinessTypeSetting.UsePort = BusinessTypeSetting.GetPortNum(BusinessTypeSetting.UseServerType);
			BusinessTypeSetting.UsePatch = BusinessTypeSetting.GetPatchUrl(BusinessTypeSetting.UseServerType);
			BusinessTypeSetting.UseDownloadUrl = BusinessTypeSetting.GetDownloadUrl(BusinessTypeSetting.UseServerType);
			BusinessTypeSetting.UseLiffID = BusinessTypeSetting.GetLiffID(BusinessTypeSetting.UseServerType);
			BusinessTypeSetting.UseLineID = BusinessTypeSetting.GetLineID(BusinessTypeSetting.UseServerType);
		}
		if (override) {
			// 試算表(平台+環境)帶入的連線設定：蓋過 ServerType 預設，仍可被網址參數覆寫
			if (override.host) {
				BusinessTypeSetting.UseHost = override.host;
			}
			if (override.port) {
				BusinessTypeSetting.UsePort = override.port;
			}
			if (override.patch) {
				BusinessTypeSetting.UsePatch = override.patch;
			}
			if (override.downloadUrl) {
				BusinessTypeSetting.UseDownloadUrl = override.downloadUrl;
			}
			if (override.liffId) {
				BusinessTypeSetting.UseLiffID = override.liffId;
			}
			if (override.lineId) {
				BusinessTypeSetting.UseLineID = override.lineId;
			}
		}
		if (host) {
			// 自定連線1(有自定則無視UseServerType)
			BusinessTypeSetting.UseHost = host;
		}
		if (port) {
			// 自定連線2(有自定則無視UseServerType)
			BusinessTypeSetting.UsePort = +port;
		}
		if (patch) {
			// 自定連資源伺服器(有自定則無視UseServerType)
			BusinessTypeSetting.UsePatch = patch;
		}
		if (downloadurl) {
			// 自定連靜態伺服器(有自定則無視UseServerType)
			BusinessTypeSetting.UseDownloadUrl = downloadurl;
		}
		if (liffid) {
			// 自定連Line Liff(有自定則無視UseServerType)
			BusinessTypeSetting.UseLiffID = liffid;
		}
		return;
	}

	return (
		<GameItemsContext.Provider value={game}>
			{children}
		</GameItemsContext.Provider>
	);
}

/** 試算表(平台+環境)帶入的連線設定覆寫 */
export interface ConnectionOverride {
	host?: string;
	port?: number;
	patch?: string;
	downloadUrl?: string;
	liffId?: string;
	lineId?: string;
}

function initPlayerData(): PlayerData {
	return {
		token: undefined,
		aId: undefined,
		f: undefined,
		r: undefined,
		rf: undefined,
		name: undefined,
		a: undefined,
		m: 0,
		lp: undefined,
		tr: undefined,
		lct: undefined
	};
}

function initGameData(): GameData {
	return {
		slotData: [],
		slotList: [],
		nowSlotId: undefined,
	};
}
