/* eslint-disable @next/next/no-img-element */
import Head from "next/head";
import {withIronSessionSsr} from "iron-session/next";
import {sessionOptions} from "@/lib/session";
import {ChangeEvent, useEffect, useRef, useState} from "react";
import useUser from "@/hooks/useUser";
import {toast, ToastContainer} from "react-toastify";
import Layout from "@/components/High/Layout";
import Input from "@/components/Low/Input";
import Button from "@/components/Low/Button";
import Link from "next/link";
import axios from "axios";
import {ErrorMessage} from "@/constants/errors";
import {RadioGroup} from "@headlessui/react";
import clsx from "clsx";
import {EmploymentStatus, EMPLOYMENT_STATUS, Gender, User} from "@/interfaces/user";
import countryCodes from "country-codes-list";
import {countries, TCountries} from "countries-list";
import CountrySelect from "@/components/Low/CountrySelect";
import {shouldRedirectHome} from "@/utils/navigation.disabled";
import moment from "moment";

export const getServerSideProps = withIronSessionSsr(({req, res}) => {
	const user = req.session.user;

	if (!user || !user.isVerified) {
		res.setHeader("location", "/login");
		res.statusCode = 302;
		res.end();
		return {
			props: {
				user: null,
			},
		};
	}

	if (shouldRedirectHome(user)) {
		res.setHeader("location", "/");
		res.statusCode = 302;
		res.end();
		return {
			props: {
				user: null,
			},
		};
	}

	return {
		props: {user: req.session.user},
	};
}, sessionOptions);

export default function Home() {
	const [bio, setBio] = useState("");
	const [name, setName] = useState("");
	const [email, setEmail] = useState("");
	const [password, setPassword] = useState("");
	const [newPassword, setNewPassword] = useState("");
	const [isLoading, setIsLoading] = useState(false);
	const [profilePicture, setProfilePicture] = useState("");

	const [country, setCountry] = useState<string>();
	const [phone, setPhone] = useState<string>();
	const [gender, setGender] = useState<Gender>();
	const [employment, setEmployment] = useState<EmploymentStatus>();

	const profilePictureInput = useRef(null);

	const {user, mutateUser} = useUser({redirectTo: "/login"});

	const expirationDateColor = (date: Date) => {
		const momentDate = moment(date);
		const today = moment(new Date());

		if (today.add(1, "days").isAfter(momentDate)) return "!bg-mti-red-ultralight border-mti-red-light";
		if (today.add(3, "days").isAfter(momentDate)) return "!bg-mti-rose-ultralight border-mti-rose-light";
		if (today.add(7, "days").isAfter(momentDate)) return "!bg-mti-orange-ultralight border-mti-orange-light";
	};

	useEffect(() => {
		if (user) {
			setName(user.name);
			setEmail(user.email);
			setBio(user.bio);
			setProfilePicture(user.profilePicture);
			setCountry(user.demographicInformation?.country);
			setPhone(user.demographicInformation?.phone);
			setGender(user.demographicInformation?.gender);
			setEmployment(user.demographicInformation?.employment);
		}
	}, [user]);

	const convertBase64 = (file: File) => {
		return new Promise((resolve, reject) => {
			const fileReader = new FileReader();
			fileReader.readAsDataURL(file);
			fileReader.onload = () => {
				resolve(fileReader.result);
			};
			fileReader.onerror = (error) => {
				reject(error);
			};
		});
	};

	const uploadProfilePicture = async (event: ChangeEvent<HTMLInputElement>) => {
		if (event.target.files && event.target.files[0]) {
			const picture = event.target.files[0];
			const base64 = await convertBase64(picture);
			setProfilePicture(base64 as string);
		}
	};

	const updateUser = async () => {
		setIsLoading(true);
		if (email !== user?.email && !password) {
			toast.error("To update your e-mail you need to input your password!");
			setIsLoading(false);
			return;
		}

		if (newPassword && !password) {
			toast.error("To update your password you need to input your current one!");
			setIsLoading(false);
			return;
		}

		const request = await axios.post("/api/users/update", {
			bio,
			name,
			email,
			password,
			newPassword,
			profilePicture,
			demographicInformation: {
				phone,
				country,
				employment,
				gender,
			},
		});
		if (request.status === 200) {
			toast.success("Your profile has been updated!");
			mutateUser((request.data as {user: User}).user);
			setIsLoading(false);
			return;
		}

		toast.error((request.data as ErrorMessage).message);
		setIsLoading(false);
	};

	return (
		<>
			<Head>
				<title>Profile | EnCoach</title>
				<meta
					name="description"
					content="A training platform for the IELTS exam provided by the Muscat Training Institute and developed by eCrop."
				/>
				<meta name="viewport" content="width=device-width, initial-scale=1" />
				<link rel="icon" href="/favicon.ico" />
			</Head>
			<ToastContainer />
			{user && (
				<Layout user={user}>
					<section className="w-full flex flex-col gap-8 px-4 py-8">
						<div className="flex w-full justify-between">
							<div className="flex flex-col gap-8 w-2/3">
								<h1 className="text-4xl font-bold mb-6">Edit Profile</h1>
								<form className="flex flex-col items-center gap-6 w-full">
									<div className="flex flex-row gap-8 w-full">
										<Input
											label="Name"
											type="text"
											name="name"
											onChange={(e) => setName(e)}
											placeholder="Enter your name"
											defaultValue={name}
											required
										/>
										<Input
											label="E-mail Address"
											type="email"
											name="email"
											onChange={(e) => setEmail(e)}
											placeholder="Enter email address"
											defaultValue={email}
											required
										/>
									</div>
									<div className="flex flex-row gap-8 w-full">
										<Input
											label="Old Password"
											type="password"
											name="password"
											onChange={(e) => setPassword(e)}
											placeholder="Enter your password"
											required
										/>
										<Input
											label="New Password"
											type="password"
											name="newPassword"
											onChange={(e) => setNewPassword(e)}
											placeholder="Enter your new password (optional)"
										/>
									</div>

									<div className="flex flex-row gap-8 w-full">
										<div className="flex flex-col gap-3 w-full">
											<label className="font-normal text-base text-mti-gray-dim">Country *</label>
											<CountrySelect value={country} onChange={setCountry} />
										</div>
										<Input
											type="tel"
											name="phone"
											label="Phone number"
											onChange={(e) => setPhone(e)}
											placeholder="Enter phone number"
											defaultValue={phone}
											required
										/>
									</div>
									<div className="flex flex-row gap-8 w-full">
										<div className="relative flex flex-col gap-3 w-full">
											<label className="font-normal text-base text-mti-gray-dim">Employment Status *</label>
											<RadioGroup
												value={employment}
												onChange={setEmployment}
												className="grid grid-cols-2 items-center gap-4 place-items-center">
												{EMPLOYMENT_STATUS.map(({status, label}) => (
													<RadioGroup.Option value={status} key={status}>
														{({checked}) => (
															<span
																className={clsx(
																	"px-6 py-4 w-48 flex justify-center text-sm font-normal rounded-full border focus:outline-none cursor-pointer",
																	"transition duration-300 ease-in-out",
																	!checked
																		? "bg-white border-mti-gray-platinum"
																		: "bg-mti-purple-light border-mti-purple-dark text-white",
																)}>
																{label}
															</span>
														)}
													</RadioGroup.Option>
												))}
											</RadioGroup>
										</div>
										<div className="flex flex-col gap-8 w-full">
											<div className="relative flex flex-col gap-3 w-full">
												<label className="font-normal text-base text-mti-gray-dim">Gender *</label>
												<RadioGroup value={gender} onChange={setGender} className="flex flex-row gap-4 justify-between">
													<RadioGroup.Option value="male">
														{({checked}) => (
															<span
																className={clsx(
																	"px-6 py-4 w-28 flex justify-center text-sm font-normal rounded-full border focus:outline-none cursor-pointer",
																	"transition duration-300 ease-in-out",
																	!checked
																		? "bg-white border-mti-gray-platinum"
																		: "bg-mti-purple-light border-mti-purple-dark text-white",
																)}>
																Male
															</span>
														)}
													</RadioGroup.Option>
													<RadioGroup.Option value="female">
														{({checked}) => (
															<span
																className={clsx(
																	"px-6 py-4 w-28 flex justify-center text-sm font-normal rounded-full border focus:outline-none cursor-pointer",
																	"transition duration-300 ease-in-out",
																	!checked
																		? "bg-white border-mti-gray-platinum"
																		: "bg-mti-purple-light border-mti-purple-dark text-white",
																)}>
																Female
															</span>
														)}
													</RadioGroup.Option>
													<RadioGroup.Option value="other">
														{({checked}) => (
															<span
																className={clsx(
																	"px-6 py-4 w-28 flex justify-center text-sm font-normal rounded-full border focus:outline-none cursor-pointer",
																	"transition duration-300 ease-in-out",
																	!checked
																		? "bg-white border-mti-gray-platinum"
																		: "bg-mti-purple-light border-mti-purple-dark text-white",
																)}>
																Other
															</span>
														)}
													</RadioGroup.Option>
												</RadioGroup>
											</div>
											<div className="flex flex-col gap-3">
												<label className="font-normal text-base text-mti-gray-dim">Expiry Date</label>
												<Link
													href="https://encoach.com/join"
													className={clsx(
														"p-6 w-full flex justify-center text-sm font-normal rounded-full border focus:outline-none cursor-pointer",
														"transition duration-300 ease-in-out",
														!user.subscriptionExpirationDate
															? "bg-mti-green-ultralight border-mti-green-light"
															: expirationDateColor(user.subscriptionExpirationDate),
														"bg-white border-mti-gray-platinum",
													)}>
													{!user.subscriptionExpirationDate && "Unlimited"}
													{user.subscriptionExpirationDate && moment(user.subscriptionExpirationDate).format("DD/MM/YYYY")}
												</Link>
											</div>
										</div>
									</div>
								</form>
							</div>
							<div className="flex flex-col gap-3 items-center w-48">
								<img
									src={profilePicture}
									alt={user.name}
									className="aspect-square h-48 w-48 rounded-full drop-shadow-xl self-end object-cover"
								/>
								<input type="file" className="hidden" onChange={uploadProfilePicture} accept="image/*" ref={profilePictureInput} />
								<span
									onClick={() => (profilePictureInput.current as any)?.click()}
									className="cursor-pointer text-mti-purple-light text-sm">
									Change picture
								</span>
							</div>
						</div>
						<div className="flex flex-col gap-4 mt-8 mb-20">
							<span className="text-lg font-bold">Bio</span>
							<textarea
								className="w-full h-full min-h-[148px] cursor-text px-7 py-8 input border-2 border-mti-gray-platinum bg-white rounded-3xl"
								onChange={(e) => setBio(e.target.value)}
								defaultValue={bio}
								placeholder="Write your text here..."
							/>
						</div>

						<div className="self-end flex justify-between w-full gap-8 absolute bottom-8 left-0 px-8">
							<Link href="/" className="max-w-[200px] self-end w-full">
								<Button color="purple" variant="outline" className="max-w-[200px] self-end w-full">
									Back
								</Button>
							</Link>
							<Button color="purple" className="max-w-[200px] self-end w-full" onClick={updateUser} disabled={isLoading}>
								Save Changes
							</Button>
						</div>
					</section>
				</Layout>
			)}
		</>
	);
}
