import MainControl from "@/Common/MainControl/MainControl";
import CSMessage from "@/Common/Message/CSMessage";
import { CoroutineV2 } from "@/Engine/CatanEngine/CoroutineV2/CoroutineV2";
import { INetResponse } from "@/Engine/CatanEngine/NetManagerV2/Core/INetResponse";
import { BusinessEnum } from "@/_BusinessTypeSetting/BusinessTypeSetting";
import { useGameItems } from "@/context/GameItemsContext";
import { AccountLoginRequest } from "@/define/Request/AccountRequest";
import { CommonAccountResponse, LineLoginRequest } from "@/define/Request/RegisterRequest";
import WheelSelect from "@/components/WheelSelect";
import { EnvName, fetchGameUrl, fetchPlatformConfig, fetchPlatformList, PlatformEnvConfig, PlatformOption } from "@/modules/GoogleSheet/GoogleSheetService";
import { Button, Input, Spin } from "antd";
import React, { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";

const { TextArea } = Input;

/** 環境對應原本的 ServerType（影響 SD 機台判斷等既有邏輯） */
const ENV_TO_SERVER_TYPE: Record<EnvName, BusinessEnum.ServerType> = {
	Dev: BusinessEnum.ServerType.Internal_Dev,
	B2B: BusinessEnum.ServerType.Out_B2B,
	Out: BusinessEnum.ServerType.Out,
};

const ENV_OPTIONS: { value: EnvName; label: string }[] = [
	{ value: "Dev", label: "Dev（內版開發）" },
	{ value: "B2B", label: "B2B（商業DEMO）" },
	{ value: "Out", label: "Out（外版）" },
];

const STORAGE_PLATFORM: string = "lp_bot_platform";
const STORAGE_ENV: string = "lp_bot_env";
const STORAGE_TOKEN: string = "lp_bot_token";

const Login = () => {
	const { onLoad, player, setPlayer } = useGameItems();
	const navigate = useNavigate();
	const [isLogin, setIsLogin] = useState<boolean>(false);
	const [loginStep, setLoginStep] = useState<string>("");
	const [platforms, setPlatforms] = useState<PlatformOption[]>([]);
	const [platformCode, setPlatformCode] = useState<string>(undefined);
	const [env, setEnv] = useState<EnvName>("B2B");
	const [listError, setListError] = useState<string>("");
	const [isOpening, setIsOpening] = useState<boolean>(false);
	let a = "eyJhbGciOiJIUzI1NiJ9.pQJchovldtKZZX-j1cPWNtyw_SvMF4xDciy7SdjxU5jkbDV33_4IIIt7sX6NA2ra6L7ubTSZK647lDAUpRaUjMaSLlVwBx9AL8n_s7G-mtrqPhwdSmxZhBovo-TaENKH2fCOB2bz_8E_ri44Se3FUwFLVWPOgLGm3_XiRWjPz90.uejJKDhcnPwv0EwmbYyUWhbcdJmSFNF2oA923Rtiaqo";
	if (import.meta.env.PROD) {
		a = "";
	}
	// 上次記住的 token 優先，沒有才用開發預設值
	const [token, SetToken] = useState(localStorage.getItem(STORAGE_TOKEN) || a);

	/** 載入平台清單（Google Sheet 專案清單） */
	async function loadPlatforms() {
		setListError("");
		try {
			const list: PlatformOption[] = await fetchPlatformList();
			setPlatforms(list);
			const saved: string = localStorage.getItem(STORAGE_PLATFORM);
			if (saved && list.some((p: PlatformOption) => p.code === saved)) {
				setPlatformCode(saved);
			} else if (list.length > 0) {
				setPlatformCode(list[0].code);
			}
			const savedEnv: string = localStorage.getItem(STORAGE_ENV);
			if (savedEnv === "Dev" || savedEnv === "B2B" || savedEnv === "Out") {
				setEnv(savedEnv);
			}
		} catch (e) {
			console.error(e);
			setListError(e?.message ?? "讀取平台清單失敗");
		}
	}

	useEffect(() => {
		loadPlatforms();
	}, []);

	/** 開遊戲：打開試算表「跳過維護阻擋(ver2.0 use)」列的網址 */
	async function onClickOpenGame() {
		const platform: PlatformOption = platforms.find((p: PlatformOption) => p.code === platformCode);
		if (!platform) {
			CSMessage.CreateYesMsg("請選擇平台");
			return;
		}
		localStorage.setItem(STORAGE_PLATFORM, platform.code);
		localStorage.setItem(STORAGE_ENV, env);
		setIsOpening(true);
		try {
			const url: string = await fetchGameUrl(platform, env);
			window.open(url, "_blank");
		} catch (e) {
			console.error(e);
			CSMessage.CreateYesMsg(e?.message ?? "讀取遊戲網址失敗");
		} finally {
			setIsOpening(false);
		}
	}

	async function onClickLogin() {
		if (!token) {
			CSMessage.CreateYesMsg("請輸入token");
			return;
		}
		const platform: PlatformOption = platforms.find((p: PlatformOption) => p.code === platformCode);
		if (!platform) {
			CSMessage.CreateYesMsg("請選擇平台");
			return;
		}
		localStorage.setItem(STORAGE_PLATFORM, platform.code);
		localStorage.setItem(STORAGE_ENV, env);
		setIsLogin(true);
		try {
			// 讀平台分頁取得該環境的連線設定
			setLoginStep(`讀取 ${platform.code} ${env} 連線設定`);
			const config: PlatformEnvConfig = await fetchPlatformConfig(platform, env);
			console.log(`[Login] ${config.sheetTitle} / ${env}`, config);
			setLoginStep(`連線 ${config.host}:${config.port}`);
			await onLoad(ENV_TO_SERVER_TYPE[env], {
				host: config.host,
				port: config.port,
				patch: config.patch,
				downloadUrl: config.downloadUrl,
				liffId: config.liffId,
				lineId: config.lineId,
			});
		} catch (e) {
			console.error(e);
			CSMessage.CreateYesMsg(e?.message ?? "讀取平台設定失敗");
			setIsLogin(false);
			return;
		}
		CoroutineV2.Single(login()).Start();
	}

	function* login() {
		yield* MainControl.Instance.ConnectAsync();
		yield* registerLineLogin();
	}

	function* registerLineLogin() {
		let req: LineLoginRequest = new LineLoginRequest(token);
		yield req.SendAsync(true);
		let resp: INetResponse<CommonAccountResponse> = req.Result;
		if (!resp.IsValid) {
			//取得帳號失敗直接斷開SOCKET
			if (resp.Status != 12) {
				const msg: string = "Line Info Error. Error Code:" + req.Result.Status;
				CSMessage.CreateYesMsg(msg);
				setIsLogin(false);
				return;
			}
			console.warn("LINE帳號無綁定");
			setIsLogin(false);
			return;
		}
		yield* serverAccountLogin(resp.Data.id, resp.Data.pw);
	}

	/** 遊戲帳號登入取得玩家資料.統一登入時在刪除需要刪除的資料 */
	function* serverAccountLogin(a: string, pw: string, partner: string = null): IterableIterator<any> {
		let hasAP: boolean = (a && a != "null" && a != "undefined" && pw && pw != "null" && pw != "undefined");
		if (!hasAP) {
			CSMessage.CreateYesMsg("沒有帳號或密碼.請確認回傳接值.");
			setIsLogin(false);
			return;
		}
		let req: AccountLoginRequest = new AccountLoginRequest(a, pw, partner);
		yield req.SendAsync(true);
		let resp: INetResponse<any> = req.Result;
		if (!resp.IsValid) {
			CSMessage.CreateYesMsg("Login Account Error! Error Code : " + resp.Status);
			setIsLogin(false);
			return;
		}
		setPlayer({
			...player,
			...resp.Data,
			token: token
		});
		navigate(`/lobby/`);
	}

	const platformOptions = platforms.map((p: PlatformOption) => ({ value: p.code, label: p.label }));
	const isListLoading: boolean = platforms.length === 0 && !listError;

	return (
		<div style={pageStyle}>
			<div className="lp-panel lp-corners lp-rise" style={cardStyle}>
				<div style={{ marginBottom: 28 }}>
					<div className="lp-kicker" style={{ marginBottom: 8 }}>Line Project // Console</div>
					<h1 className="lp-title" style={{ fontSize: 30 }}>BOT 控制台</h1>
					<div className="lp-label" style={{ marginTop: 6 }}>
						<span className={`lp-dot ${isLogin ? "lp-dot--amber" : listError ? "lp-dot--red" : ""}`} style={{ marginRight: 8 }} />
						{isLogin ? "connecting..." : listError ? "sheet error" : isListLoading ? "loading sheet..." : "standby"}
					</div>
				</div>

				{isLogin
					? <div style={connectingStyle}>
						<Spin size="large" />
						<div className="lp-mono lp-cursor" style={{ marginTop: 18, color: "var(--lp-text-dim)" }}>
							{loginStep || "正在連線伺服器"}
						</div>
					</div>
					: <>
						<div style={fieldStyle}>
							<div className="lp-label" style={labelStyle}>平台</div>
							<WheelSelect
								style={{ width: "100%" }}
								size="large"
								value={platformCode}
								options={platformOptions}
								loading={isListLoading}
								placeholder={isListLoading ? "從試算表載入平台清單..." : "選擇平台"}
								showSearch
								optionFilterProp="label"
								onChange={(v: string) => { setPlatformCode(v); localStorage.setItem(STORAGE_PLATFORM, v); }}
							/>
							{listError &&
								<div style={{ marginTop: 6, display: "flex", alignItems: "center", gap: 10 }}>
									<span style={{ color: "var(--lp-red)", fontSize: 12 }}>{listError}</span>
									<Button size="small" onClick={loadPlatforms}>重試</Button>
								</div>
							}
						</div>

						<div style={fieldStyle}>
							<div className="lp-label" style={labelStyle}>環境</div>
							<WheelSelect
								style={{ width: "100%" }}
								size="large"
								value={env}
								options={ENV_OPTIONS}
								onChange={(v: EnvName) => { setEnv(v); localStorage.setItem(STORAGE_ENV, v); }}
							/>
						</div>

						<div style={fieldStyle}>
							<div className="lp-label" style={labelStyle}>TOKEN</div>
							<TextArea
								rows={5}
								value={token}
								onChange={e => { SetToken(e.target.value); localStorage.setItem(STORAGE_TOKEN, e.target.value); }}
								placeholder="貼上 Line Token"
								style={{ fontFamily: "var(--lp-font-mono)", fontSize: 12 }}
							/>
						</div>

						<div style={{ display: "flex", gap: 12 }}>
							<Button size="large" onClick={onClickOpenGame} loading={isOpening} disabled={isListLoading || !!listError}
								style={{ flex: 1, height: 48, fontWeight: 700, letterSpacing: "0.2em", textIndent: "0.2em" }}>
								開遊戲
							</Button>
							<Button type="primary" size="large" onClick={onClickLogin} disabled={isListLoading || !!listError}
								style={{ flex: 1, height: 48, fontWeight: 700, letterSpacing: "0.2em", textIndent: "0.2em" }}>
								登入
							</Button>
						</div>
					</>
				}
			</div>
		</div>
	);
};

export default Login;

const pageStyle: React.CSSProperties = {
	height: "100%",
	display: "flex",
	alignItems: "center",
	justifyContent: "center",
	padding: 16,
};

const cardStyle: React.CSSProperties = {
	width: "min(440px, 100%)",
	padding: "36px 36px 32px",
	boxShadow: "0 24px 60px rgba(0, 0, 0, 0.5)",
};

const fieldStyle: React.CSSProperties = {
	marginBottom: 20,
};

const labelStyle: React.CSSProperties = {
	marginBottom: 8,
};

const connectingStyle: React.CSSProperties = {
	display: "flex",
	flexDirection: "column",
	alignItems: "center",
	padding: "36px 0 24px",
};
