import { useTranslation } from "react-i18next";
import type { MetaFunction } from "react-router";
import { useLoaderData, useSearchParams } from "react-router";
import { Label } from "~/components/Label";
import { Main } from "~/components/Main";
import { Pagination } from "~/components/Pagination";
import { WeaponSelect } from "~/components/WeaponSelect";
import { modesShort } from "~/modules/in-game-lists/modes";
import { stageIds } from "~/modules/in-game-lists/stage-ids";
import { mainWeaponIds } from "~/modules/in-game-lists/weapon-ids";
import { metaTags } from "~/utils/remix";
import type { SendouRouteHandle } from "~/utils/remix.server";
import { navIconUrl, VODS_PAGE } from "~/utils/urls";
import { VodListing } from "../components/VodListing";
import { loader } from "../loaders/vods.server";
import { videoMatchTypes } from "../vods-constants";
import styles from "./vods.module.css";

export { loader };

export const handle: SendouRouteHandle = {
	i18n: ["vods"],
	breadcrumb: () => ({
		imgPath: navIconUrl("vods"),
		href: VODS_PAGE,
		type: "IMAGE",
	}),
};

export const meta: MetaFunction<typeof loader> = (args) => {
	return metaTags({
		title: "VODs",
		ogTitle: "Splatoon 3 VODs (gameplay footage search)",
		description:
			"Search for Splatoon 3 VODs (gameplay footage) by mode, stage and/or weapon.",
		location: args.location,
	});
};

export default function VodsSearchPage() {
	const { t } = useTranslation(["vods"]);
	const data = useLoaderData<typeof loader>();
	const [, setSearchParams] = useSearchParams();

	const addToSearchParams = (key: string, value: string | number) => {
		setSearchParams((params) => {
			params.set(key, String(value));
			params.delete("page");
			return params;
		});
	};

	const setPage = (page: number) => {
		setSearchParams((params) => {
			params.set("page", String(page));
			return params;
		});
	};

	return (
		<Main className="stack lg" bigger>
			<Filters addToSearchParams={addToSearchParams} />
			{data.vods.length > 0 ? (
				<>
					<div className={styles.listingList}>
						{data.vods.map((vod) => (
							<VodListing key={vod.id} vod={vod} />
						))}
					</div>
					{data.pagesCount > 1 ? (
						<Pagination
							currentPage={data.currentPage}
							pagesCount={data.pagesCount}
							nextPage={() => setPage(data.currentPage + 1)}
							previousPage={() => setPage(data.currentPage - 1)}
							setPage={setPage}
						/>
					) : null}
				</>
			) : (
				<div className="text-lg text-lighter">{t("vods:noVods")}</div>
			)}
		</Main>
	);
}

function Filters({
	addToSearchParams,
}: {
	addToSearchParams: (key: string, value: string | number) => void;
}) {
	const { t } = useTranslation(["game-misc", "vods"]);

	const [searchParams] = useSearchParams();
	const mode = modesShort.find(
		(mode) => searchParams.get("mode") && mode === searchParams.get("mode"),
	);
	const stageId = stageIds.find(
		(stageId) =>
			searchParams.get("stageId") &&
			stageId === Number(searchParams.get("stageId")),
	);
	const weapon = mainWeaponIds.find(
		(id) =>
			searchParams.get("weapon") && id === Number(searchParams.get("weapon")),
	);
	const type = videoMatchTypes.find(
		(type) => searchParams.get("type") && type === searchParams.get("type"),
	);

	return (
		<div className="stack sm horizontal flex-wrap">
			<div>
				<Label>{t("vods:forms.title.mode")}</Label>
				<select
					name="mode"
					value={mode ?? ""}
					onChange={(e) => addToSearchParams("mode", e.target.value)}
				>
					<option value="">-</option>
					{modesShort.map((mode) => {
						return (
							<option key={mode} value={mode}>
								{t(`game-misc:MODE_SHORT_${mode}`)}
							</option>
						);
					})}
				</select>
			</div>
			<div>
				<Label>{t("vods:forms.title.stage")}</Label>
				<select
					name="stage"
					value={stageId ?? ""}
					onChange={(e) => addToSearchParams("stageId", e.target.value)}
				>
					<option value="">-</option>
					{stageIds.map((stageId) => {
						return (
							<option key={stageId} value={stageId}>
								{t(`game-misc:STAGE_${stageId}`)}
							</option>
						);
					})}
				</select>
			</div>

			<WeaponSelect
				label={t("vods:forms.title.weapon")}
				value={weapon ?? null}
				onChange={(weaponId) => {
					addToSearchParams("weapon", weaponId ?? "");
				}}
				clearable
			/>

			<div>
				<Label>{t("vods:forms.title.type")}</Label>
				<select
					name="type"
					className={styles.typeSelect}
					value={type ?? ""}
					onChange={(e) => addToSearchParams("type", e.target.value)}
				>
					<option value="">-</option>
					{videoMatchTypes.map((type) => {
						return (
							<option key={type} value={type}>
								{t(`vods:type.${type}`)}
							</option>
						);
					})}
				</select>
			</div>
		</div>
	);
}
