"use client";

import { useEffect, useState } from "react";
import { useRouter } from "@/i18n/navigation";
import { useTranslations } from "next-intl";
import { useSession } from "next-auth/react";
import { Eye, EyeOff, KeyRound, Loader2, UserRound } from "lucide-react";
import Button from "@/components/ui/Button";
import Input from "@/components/ui/Input";
import { formatUserName } from "@/lib/user-display";
import { readApiJson, toastError, toastPromise } from "@/lib/toast";

interface ProfileSettingsFormsProps {
  initialFirstName: string;
  initialLastName: string;
  initialUsername: string;
  email: string;
}

export default function ProfileSettingsForms({
  initialFirstName,
  initialLastName,
  initialUsername,
  email,
}: ProfileSettingsFormsProps) {
  const t = useTranslations("profile");
  const tc = useTranslations("common");
  const ta = useTranslations("auth");
  const router = useRouter();
  const { update } = useSession();

  const [firstName, setFirstName] = useState(initialFirstName);
  const [lastName, setLastName] = useState(initialLastName);
  const [username, setUsername] = useState(initialUsername);
  const [currentPassword, setCurrentPassword] = useState("");
  const [newPassword, setNewPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");
  const [showCurrent, setShowCurrent] = useState(false);
  const [showNew, setShowNew] = useState(false);
  const [showConfirm, setShowConfirm] = useState(false);
  const [savingProfile, setSavingProfile] = useState(false);
  const [savingPassword, setSavingPassword] = useState(false);

  useEffect(() => {
    setFirstName(initialFirstName);
    setLastName(initialLastName);
    setUsername(initialUsername);
  }, [initialFirstName, initialLastName, initialUsername]);

  const profileDirty =
    firstName.trim() !== initialFirstName.trim() ||
    lastName.trim() !== initialLastName.trim() ||
    username.trim().toLowerCase() !== initialUsername.trim().toLowerCase();

  const profileValid =
    firstName.trim().length > 0 &&
    lastName.trim().length > 0 &&
    username.trim().length >= 3;

  const passwordsMatch =
    confirmPassword.length === 0 || newPassword === confirmPassword;
  const passwordReady =
    currentPassword.length > 0 &&
    newPassword.length >= 6 &&
    confirmPassword.length > 0 &&
    passwordsMatch;

  async function saveProfile(e: React.FormEvent) {
    e.preventDefault();
    if (!profileValid) return;

    setSavingProfile(true);
    try {
      const next = await toastPromise(
        readApiJson<{
          firstName: string;
          lastName: string;
          username: string;
          name?: string | null;
        }>(
          await fetch("/api/account", {
            method: "PATCH",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({
              firstName: firstName.trim(),
              lastName: lastName.trim(),
              username: username.trim().toLowerCase(),
            }),
          }),
          tc("somethingWrong")
        ),
        {
          loading: tc("saving"),
          success: t("profileSaved"),
        }
      );
      await update({
        firstName: next.firstName,
        lastName: next.lastName,
        username: next.username,
        name: next.name ?? formatUserName(next),
      });
      router.refresh();
    } catch {
      // toast
    } finally {
      setSavingProfile(false);
    }
  }

  async function savePassword(e: React.FormEvent) {
    e.preventDefault();
    if (newPassword !== confirmPassword) {
      toastError(ta("passwordMismatch"));
      return;
    }
    if (newPassword.length < 6) {
      toastError(ta("passwordMinLength"));
      return;
    }

    setSavingPassword(true);
    try {
      await toastPromise(
        readApiJson(
          await fetch("/api/account", {
            method: "PATCH",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({
              currentPassword,
              newPassword,
            }),
          }),
          tc("somethingWrong")
        ),
        {
          loading: tc("saving"),
          success: t("passwordSaved"),
        }
      );
      setCurrentPassword("");
      setNewPassword("");
      setConfirmPassword("");
      setShowCurrent(false);
      setShowNew(false);
      setShowConfirm(false);
    } catch {
      // toast
    } finally {
      setSavingPassword(false);
    }
  }

  return (
    <div className="grid gap-5 lg:grid-cols-2 lg:items-start">
      <form
        onSubmit={saveProfile}
        className="overflow-hidden rounded-2xl border border-[var(--border)] bg-[var(--bg-elevated)]"
      >
        <div className="flex items-center gap-3 border-b border-[var(--border)] px-5 py-4">
          <div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-[var(--accent-muted)] text-[var(--accent)]">
            <UserRound className="h-4 w-4" />
          </div>
          <div className="min-w-0">
            <h2 className="text-sm font-semibold">{t("editSection")}</h2>
            <p className="text-xs text-[var(--text-faint)]">{t("editSectionHint")}</p>
          </div>
        </div>

        <div className="space-y-4 p-5">
          <div className="grid gap-4 sm:grid-cols-2">
            <Input
              label={ta("firstName")}
              value={firstName}
              onChange={(e) => setFirstName(e.target.value)}
              required
              autoComplete="given-name"
            />
            <Input
              label={ta("lastName")}
              value={lastName}
              onChange={(e) => setLastName(e.target.value)}
              required
              autoComplete="family-name"
            />
          </div>
          <div className="space-y-1.5">
            <Input
              label={ta("username")}
              hint={ta("usernameHint")}
              hintLabel={tc("helpLabel")}
              value={username}
              onChange={(e) => setUsername(e.target.value.toLowerCase())}
              required
              autoComplete="username"
            />
          </div>
          <div className="space-y-1.5">
            <Input
              label={ta("email")}
              hint={t("emailReadonlyHint")}
              hintLabel={tc("helpLabel")}
              type="email"
              value={email}
              disabled
            />
          </div>
        </div>

        <div className="flex items-center justify-between gap-3 border-t border-[var(--border)] bg-[var(--bg)]/40 px-5 py-4">
          <p className="text-xs text-[var(--text-faint)]">
            {profileDirty ? t("unsavedChanges") : t("profileUpToDate")}
          </p>
          <Button
            type="submit"
            disabled={savingProfile || !profileDirty || !profileValid}
            className="min-w-[96px]"
          >
            {savingProfile ? (
              <>
                <Loader2 className="h-4 w-4 animate-spin" />
                {tc("saving")}
              </>
            ) : (
              tc("save")
            )}
          </Button>
        </div>
      </form>

      <form
        onSubmit={savePassword}
        className="overflow-hidden rounded-2xl border border-[var(--border)] bg-[var(--bg-elevated)]"
      >
        <div className="flex items-center gap-3 border-b border-[var(--border)] px-5 py-4">
          <div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-[var(--accent-muted)] text-[var(--accent)]">
            <KeyRound className="h-4 w-4" />
          </div>
          <div className="min-w-0">
            <h2 className="text-sm font-semibold">{t("passwordSection")}</h2>
            <p className="text-xs text-[var(--text-faint)]">{t("passwordSectionHint")}</p>
          </div>
        </div>

        <div className="space-y-4 p-5">
          <PasswordField
            label={t("currentPassword")}
            value={currentPassword}
            onChange={setCurrentPassword}
            visible={showCurrent}
            onToggle={() => setShowCurrent((v) => !v)}
            autoComplete="current-password"
            showLabel={t("showPassword")}
            hideLabel={t("hidePassword")}
            required
          />
          <PasswordField
            label={t("newPassword")}
            value={newPassword}
            onChange={setNewPassword}
            visible={showNew}
            onToggle={() => setShowNew((v) => !v)}
            autoComplete="new-password"
            placeholder={ta("passwordMinPlaceholder")}
            showLabel={t("showPassword")}
            hideLabel={t("hidePassword")}
            required
          />
          <div className="space-y-1.5">
            <PasswordField
              label={t("confirmPassword")}
              value={confirmPassword}
              onChange={setConfirmPassword}
              visible={showConfirm}
              onToggle={() => setShowConfirm((v) => !v)}
              autoComplete="new-password"
              showLabel={t("showPassword")}
              hideLabel={t("hidePassword")}
              required
              error={
                confirmPassword.length > 0 && !passwordsMatch
                  ? ta("passwordMismatch")
                  : undefined
              }
            />
            {newPassword.length > 0 && newPassword.length < 6 && (
              <p className="text-xs text-[var(--text-faint)]">{ta("passwordMinLength")}</p>
            )}
          </div>
        </div>

        <div className="flex justify-end border-t border-[var(--border)] bg-[var(--bg)]/40 px-5 py-4">
          <Button type="submit" disabled={savingPassword || !passwordReady} className="min-w-[140px]">
            {savingPassword ? (
              <>
                <Loader2 className="h-4 w-4 animate-spin" />
                {tc("saving")}
              </>
            ) : (
              t("updatePassword")
            )}
          </Button>
        </div>
      </form>
    </div>
  );
}

function PasswordField({
  label,
  value,
  onChange,
  visible,
  onToggle,
  autoComplete,
  placeholder,
  required,
  error,
  showLabel,
  hideLabel,
}: {
  label: string;
  value: string;
  onChange: (value: string) => void;
  visible: boolean;
  onToggle: () => void;
  autoComplete: string;
  placeholder?: string;
  required?: boolean;
  error?: string;
  showLabel: string;
  hideLabel: string;
}) {
  return (
    <div className="space-y-1.5">
      <label className="block text-sm font-medium text-[var(--text-muted)]">{label}</label>
      <div className="relative">
        <input
          type={visible ? "text" : "password"}
          value={value}
          onChange={(e) => onChange(e.target.value)}
          autoComplete={autoComplete}
          placeholder={placeholder}
          required={required}
          aria-invalid={error ? true : undefined}
          className={`w-full rounded-lg border bg-[var(--bg-elevated)] py-2.5 pe-11 ps-3.5 text-sm text-[var(--text)] placeholder:text-[var(--text-faint)] transition focus:border-[var(--accent)]/60 focus:outline-none focus:ring-2 focus:ring-[var(--accent)]/40 ${
            error ? "border-red-500/50" : "border-[var(--border)]"
          }`}
        />
        <button
          type="button"
          onClick={onToggle}
          className="absolute end-2 top-1/2 flex h-8 w-8 -translate-y-1/2 cursor-pointer items-center justify-center rounded-md text-[var(--text-faint)] transition-colors hover:bg-[var(--bg-hover)] hover:text-[var(--text-muted)]"
          aria-label={visible ? hideLabel : showLabel}
        >
          {visible ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
        </button>
      </div>
      {error && (
        <p className="text-xs text-red-400" role="alert">
          {error}
        </p>
      )}
    </div>
  );
}
