import { useState, useMemo } from "react";
import { changePassword } from "../api/auth";

interface PasswordRule {
  label: string;
  test: (pw: string) => boolean;
}

const PASSWORD_RULES: PasswordRule[] = [
  { label: "At least 12 characters", test: (pw) => pw.length >= 12 },
  { label: "At least one uppercase letter", test: (pw) => /[A-Z]/.test(pw) },
  { label: "At least one lowercase letter", test: (pw) => /[a-z]/.test(pw) },
  { label: "At least one digit", test: (pw) => /[0-9]/.test(pw) },
  {
    label: "At least one special character (!@#$%^&*…)",
    test: (pw) => /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?`~]/.test(pw),
  },
];

export function PasswordPolicyChecklist({ password }: { password: string }) {
  return (
    <ul className="mt-2 space-y-1 text-xs">
      {PASSWORD_RULES.map((rule) => {
        const ok = password.length > 0 && rule.test(password);
        return (
          <li key={rule.label} className="flex items-center gap-1.5">
            <span className={ok ? "text-green-400" : "text-gray-500"}>
              {ok ? "✓" : "○"}
            </span>
            <span className={ok ? "text-green-300" : "text-gray-400"}>
              {rule.label}
            </span>
          </li>
        );
      })}
    </ul>
  );
}

interface Props {
  onSuccess: () => void;
  isForced?: boolean;
}

export default function ChangePasswordModal({ onSuccess, isForced }: Props) {
  const [currentPw, setCurrentPw] = useState("");
  const [newPw, setNewPw] = useState("");
  const [confirmPw, setConfirmPw] = useState("");
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);

  const allRulesPass = useMemo(
    () => PASSWORD_RULES.every((r) => r.test(newPw)),
    [newPw],
  );

  const canSubmit =
    currentPw.length > 0 &&
    allRulesPass &&
    newPw === confirmPw &&
    !loading;

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (!canSubmit) return;

    setLoading(true);
    setError(null);
    try {
      await changePassword(currentPw, newPw);
      onSuccess();
    } catch (err: unknown) {
      const msg =
        (err as { response?: { data?: { detail?: string } } })?.response?.data
          ?.detail ?? "Failed to change password";
      setError(msg);
    } finally {
      setLoading(false);
    }
  }

  return (
    <div className="fixed inset-0 z-[100] flex items-center justify-center bg-black/70 backdrop-blur-sm">
      <form
        onSubmit={handleSubmit}
        className="w-full max-w-md rounded-xl border border-gray-700 bg-gray-900 p-6 shadow-2xl"
      >
        <h2 className="mb-1 text-lg font-semibold text-white">
          Change Password
        </h2>
        {isForced && (
          <p className="mb-4 text-sm text-amber-400">
            You must change your password before continuing.
          </p>
        )}

        {error && (
          <div className="mb-3 rounded bg-red-900/50 px-3 py-2 text-sm text-red-300">
            {error}
          </div>
        )}

        <label className="mb-1 block text-sm text-gray-400">
          Current password
        </label>
        <input
          type="password"
          className="mb-4 w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-white focus:border-cyan-500 focus:outline-none"
          value={currentPw}
          onChange={(e) => setCurrentPw(e.target.value)}
          autoFocus
        />

        <label className="mb-1 block text-sm text-gray-400">
          New password
        </label>
        <input
          type="password"
          className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-white focus:border-cyan-500 focus:outline-none"
          value={newPw}
          onChange={(e) => setNewPw(e.target.value)}
        />
        <PasswordPolicyChecklist password={newPw} />

        <label className="mb-1 mt-4 block text-sm text-gray-400">
          Confirm new password
        </label>
        <input
          type="password"
          className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 text-sm text-white focus:border-cyan-500 focus:outline-none"
          value={confirmPw}
          onChange={(e) => setConfirmPw(e.target.value)}
        />
        {confirmPw.length > 0 && newPw !== confirmPw && (
          <p className="mt-1 text-xs text-red-400">Passwords do not match</p>
        )}

        <button
          type="submit"
          disabled={!canSubmit}
          className="mt-6 w-full rounded-lg bg-cyan-600 py-2.5 text-sm font-medium text-white transition-colors hover:bg-cyan-500 disabled:cursor-not-allowed disabled:opacity-50"
        >
          {loading ? "Changing…" : "Change Password"}
        </button>
      </form>
    </div>
  );
}
