import Username from "@material-symbols/svg-400/outlined/badge.svg";
import Mail from "@material-symbols/svg-400/outlined/mail.svg";
import Password from "@material-symbols/svg-400/outlined/password.svg";
// import AccountCircle from "@material-symbols/svg-400/rounded/account_circle-fill.svg";
import Delete from "@material-symbols/svg-400/rounded/delete.svg";
import Logout from "@material-symbols/svg-400/rounded/logout.svg";
// import * as ImagePicker from "expo-image-picker";
import { type ComponentProps, useState } from "react";
import { useTranslation } from "react-i18next";
import { View } from "react-native";
import { rem, useYoshiki } from "yoshiki/native";
import type { KyooError, User } from "~/models";
import {
	Alert,
	Button,
	H1,
	Icon,
	Input,
	P,
	Popup,
	ts,
	usePopup,
} from "~/primitives";
import { useAccount } from "~/providers/account-context";
import { useMutation } from "~/query";
import { deleteAccount, logout } from "../login/logic";
import { PasswordInput } from "../login/password-input";
import { Preference, SettingsContainer } from "./base";

// function dataURItoBlob(dataURI: string) {
// 	const byteString = atob(dataURI.split(",")[1]);
// 	const ab = new ArrayBuffer(byteString.length);
// 	const ia = new Uint8Array(ab);
// 	for (let i = 0; i < byteString.length; i++) {
// 		ia[i] = byteString.charCodeAt(i);
// 	}
// 	return new Blob([ab], { type: "image/jpeg" });
// }

export const AccountSettings = () => {
	const account = useAccount()!;
	const { css, theme } = useYoshiki();
	const [setPopup, close] = usePopup();
	const { t } = useTranslation();

	const { mutateAsync } = useMutation({
		method: "PATCH",
		path: ["auth", "users", "me"],
		compute: (update: Partial<User>) => ({ body: update }),
		optimistic: (update) => ({
			...account,
			...update,
			claims: { ...account.claims, ...update.claims },
		}),
		invalidate: ["auth", "users", "me"],
	});

	const { mutateAsync: editPassword } = useMutation({
		method: "PATCH",
		path: ["auth", "users", "me", "password"],
		compute: (body: { oldPassword: string; newPassword: string }) => ({
			body,
		}),
		invalidate: null,
	});

	return (
		<SettingsContainer
			title={t("settings.account.label")}
			extra={
				<View {...css({ marginTop: ts(2), gap: ts(2), flexDirection: "row" })}>
					<Button
						licon={<Icon icon={Logout} {...css({ marginX: ts(1) })} />}
						text={t("login.logout")}
						onPress={logout}
						{...css({ flexGrow: 1, flexShrink: 1, flexBasis: 0 })}
					/>
					<Button
						licon={<Icon icon={Delete} {...css({ marginX: ts(1) })} />}
						text={t("login.delete")}
						onPress={async () => {
							Alert.alert(
								t("login.delete"),
								t("login.delete-confirmation"),
								[
									{ text: t("misc.cancel"), style: "cancel" },
									{
										text: t("misc.delete"),
										onPress: deleteAccount,
										style: "destructive",
									},
								],
								{
									cancelable: true,
									userInterfaceStyle:
										theme.mode === "auto" ? "light" : theme.mode,
									icon: "warning",
								},
							);
						}}
						{...css({ flexGrow: 1, flexShrink: 1, flexBasis: 0 })}
					/>
				</View>
			}
		>
			<Preference
				icon={Username}
				label={t("settings.account.username.label")}
				description={account.username}
			>
				<Button
					text={t("misc.edit")}
					onPress={() =>
						setPopup(
							<ChangePopup
								icon={Username}
								autoComplete="username-new"
								label={t("settings.account.username.label")}
								inital={account.username}
								apply={async (v) => await mutateAsync({ username: v })}
								close={close}
							/>,
						)
					}
				/>
			</Preference>
			{/* <Preference */}
			{/* 	icon={AccountCircle} */}
			{/* 	customIcon={<Avatar src={account.logo} />} */}
			{/* 	label={t("settings.account.avatar.label")} */}
			{/* 	description={t("settings.account.avatar.description")} */}
			{/* > */}
			{/* 	<Button */}
			{/* 		text={t("misc.edit")} */}
			{/* 		onPress={async () => { */}
			{/* 			const img = await ImagePicker.launchImageLibraryAsync({ */}
			{/* 				mediaTypes: ImagePicker.MediaTypeOptions.Images, */}
			{/* 				aspect: [1, 1], */}
			{/* 				quality: 1, */}
			{/* 				base64: true, */}
			{/* 			}); */}
			{/* 			if (img.canceled || img.assets.length !== 1) return; */}
			{/* 			const data = dataURItoBlob(img.assets[0].uri); */}
			{/* 			const formData = new FormData(); */}
			{/* 			formData.append("picture", data); */}
			{/* 			await queryFn({ */}
			{/* 				method: "POST", */}
			{/* 				path: ["auth", "me", "logo"], */}
			{/* 				formData, */}
			{/* 			}); */}
			{/* 		}} */}
			{/* 	/> */}
			{/* 	<Button */}
			{/* 		text={t("misc.delete")} */}
			{/* 		onPress={async () => { */}
			{/* 			await queryFn({ */}
			{/* 				method: "DELETE", */}
			{/* 				path: ["auth", "me", "logo"], */}
			{/* 			}); */}
			{/* 		}} */}
			{/* 	/> */}
			{/* </Preference> */}
			<Preference
				icon={Mail}
				label={t("settings.account.email.label")}
				description={account.email}
			>
				<Button
					text={t("misc.edit")}
					onPress={() =>
						setPopup(
							<ChangePopup
								icon={Mail}
								autoComplete="email"
								label={t("settings.account.email.label")}
								inital={account.email}
								apply={async (v) => await mutateAsync({ email: v })}
								close={close}
							/>,
						)
					}
				/>
			</Preference>
			<Preference
				icon={Password}
				label={t("settings.account.password.label")}
				description={t("settings.account.password.description")}
			>
				<Button
					text={t("misc.edit")}
					onPress={() =>
						setPopup(
							<ChangePasswordPopup
								icon={Password}
								label={t("settings.account.password.label")}
								hasPassword={true}
								apply={async (op, np) =>
									await editPassword({ oldPassword: op, newPassword: np })
								}
								close={close}
							/>,
						)
					}
				/>
			</Preference>
		</SettingsContainer>
	);
};

const ChangePopup = ({
	label,
	icon,
	inital,
	autoComplete,
	apply,
	close,
}: {
	label: string;
	icon: Icon;
	inital: string;
	autoComplete: ComponentProps<typeof Input>["autoComplete"];
	apply: (v: string) => Promise<unknown>;
	close: () => void;
}) => {
	const { t } = useTranslation();
	const [value, setValue] = useState(inital);

	return (
		<Popup>
			{({ css }) => (
				<>
					<View
						{...css({ flexDirection: "row", alignItems: "center", gap: ts(2) })}
					>
						<Icon icon={icon} />
						<H1 {...css({ fontSize: rem(2) })}>{label}</H1>
					</View>
					<Input
						autoComplete={autoComplete}
						variant="big"
						value={value}
						onChangeText={(v) => setValue(v)}
					/>
					<View
						{...css({
							flexDirection: "row",
							alignSelf: "flex-end",
							gap: ts(1),
						})}
					>
						<Button
							text={t("misc.cancel")}
							onPress={() => close()}
							{...css({ minWidth: rem(6) })}
						/>
						<Button
							text={t("misc.edit")}
							onPress={async () => {
								await apply(value);
								close();
							}}
							{...css({ minWidth: rem(6) })}
						/>
					</View>
				</>
			)}
		</Popup>
	);
};

const ChangePasswordPopup = ({
	label,
	icon,
	hasPassword,
	apply,
	close,
}: {
	label: string;
	icon: Icon;
	hasPassword: boolean;
	apply: (oldPassword: string, newPassword: string) => Promise<unknown>;
	close: () => void;
}) => {
	const { t } = useTranslation();
	const [oldValue, setOldValue] = useState("");
	const [newValue, setNewValue] = useState("");
	const [error, setError] = useState<string | null>(null);

	return (
		<Popup>
			{({ css }) => (
				<>
					<View
						{...css({ flexDirection: "row", alignItems: "center", gap: ts(2) })}
					>
						<Icon icon={icon} />
						<H1 {...css({ fontSize: rem(2) })}>{label}</H1>
					</View>
					{hasPassword && (
						<PasswordInput
							autoComplete="current-password"
							variant="big"
							value={oldValue}
							onChangeText={(v) => setOldValue(v)}
							placeholder={t("settings.account.password.oldPassword")}
						/>
					)}
					<PasswordInput
						autoComplete="new-password"
						variant="big"
						value={newValue}
						onChangeText={(v) => setNewValue(v)}
						placeholder={t("settings.account.password.newPassword")}
					/>
					{error && (
						<P {...css({ color: (theme) => theme.colors.red })}>{error}</P>
					)}
					<View
						{...css({
							flexDirection: "row",
							alignSelf: "flex-end",
							gap: ts(1),
						})}
					>
						<Button
							text={t("misc.cancel")}
							onPress={() => close()}
							{...css({ minWidth: rem(6) })}
						/>
						<Button
							text={t("misc.edit")}
							onPress={async () => {
								try {
									await apply(oldValue, newValue);
									close();
								} catch (e) {
									setError((e as KyooError).message);
								}
							}}
							{...css({ minWidth: rem(6) })}
						/>
					</View>
				</>
			)}
		</Popup>
	);
};
