import * as React from "react";
import { useTranslation } from "react-i18next";
import { AbilitiesSelector } from "~/components/AbilitiesSelector";
import { GearSelect } from "~/components/GearSelect";
import type { GearType } from "~/db/tables";
import type { CustomFieldRenderProps } from "~/form/FormField";
import { FormFieldWrapper } from "~/form/fields/FormFieldWrapper";
import { SendouForm, useFormFieldContext } from "~/form/SendouForm";
import { rankedModesShort } from "~/modules/in-game-lists/modes";
import type { BuildAbilitiesTupleWithUnknown } from "~/modules/in-game-lists/types";
import { newBuildSchema } from "../user-page-schemas";

interface NewBuildFormProps {
	defaultValues?: Parameters<typeof SendouForm>[0]["defaultValues"];
	gearIdToAbilities: Record<string, BuildAbilitiesTupleWithUnknown[number]>;
	isEditing?: boolean;
}

export function NewBuildForm({
	defaultValues,
	gearIdToAbilities,
	isEditing,
}: NewBuildFormProps) {
	const { t } = useTranslation(["builds"]);

	return (
		<SendouForm
			schema={newBuildSchema}
			defaultValues={
				defaultValues ?? {
					modes: [...rankedModesShort],
				}
			}
			title={t(
				isEditing ? "builds:forms.title.edit" : "builds:forms.title.new",
			)}
		>
			{({ FormField }) => (
				<>
					<FormField name="weapons" />
					<FormField name="head">
						{(props: CustomFieldRenderProps) => (
							<GearFormField
								type="HEAD"
								gearIdToAbilities={gearIdToAbilities}
								{...props}
							/>
						)}
					</FormField>
					<FormField name="clothes">
						{(props: CustomFieldRenderProps) => (
							<GearFormField
								type="CLOTHES"
								gearIdToAbilities={gearIdToAbilities}
								{...props}
							/>
						)}
					</FormField>
					<FormField name="shoes">
						{(props: CustomFieldRenderProps) => (
							<GearFormField
								type="SHOES"
								gearIdToAbilities={gearIdToAbilities}
								{...props}
							/>
						)}
					</FormField>
					<FormField name="abilities">
						{(props: CustomFieldRenderProps) => (
							<AbilitiesFormField {...props} />
						)}
					</FormField>
					<FormField name="title" />
					<FormField name="description" />
					<FormField name="modes" />
					<FormField name="private" />
				</>
			)}
		</SendouForm>
	);
}

function GearFormField({
	type,
	name,
	value,
	onChange,
	error,
	gearIdToAbilities,
}: {
	type: GearType;
	name: string;
	value: unknown;
	onChange: (value: unknown) => void;
	error: string | undefined;
	gearIdToAbilities: Record<string, BuildAbilitiesTupleWithUnknown[number]>;
}) {
	const { t } = useTranslation("builds");
	const { values, setValue } = useFormFieldContext();
	const id = React.useId();

	const handleChange = (gearId: number | null) => {
		onChange(gearId);

		if (!gearId) return;

		const abilitiesFromExistingGear = gearIdToAbilities[`${type}_${gearId}`];
		if (!abilitiesFromExistingGear) return;

		const abilities = values.abilities as BuildAbilitiesTupleWithUnknown;
		const gearIndex = type === "HEAD" ? 0 : type === "CLOTHES" ? 1 : 2;
		const currentAbilities = abilities[gearIndex];

		if (!currentAbilities.every((a) => a === "UNKNOWN")) return;

		const newAbilities = structuredClone(abilities);
		newAbilities[gearIndex] = abilitiesFromExistingGear;
		setValue("abilities", newAbilities);
	};

	return (
		<FormFieldWrapper
			id={id}
			name={name}
			label={t(`forms.gear.${type}`)}
			error={error}
		>
			<GearSelect
				type={type}
				value={value as number | null}
				clearable
				onChange={handleChange}
			/>
		</FormFieldWrapper>
	);
}

function AbilitiesFormField({
	name,
	value,
	onChange,
	error,
}: {
	name: string;
	value: unknown;
	onChange: (value: unknown) => void;
	error: string | undefined;
}) {
	const { t } = useTranslation("builds");

	return (
		<FormFieldWrapper
			id={`${name}-abilities`}
			name={name}
			label={t("forms.abilities")}
			error={error}
		>
			<AbilitiesSelector
				selectedAbilities={value as BuildAbilitiesTupleWithUnknown}
				onChange={onChange}
			/>
		</FormFieldWrapper>
	);
}
