"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import { Alert, Button, CloseButton, Input, Label, Spinner, TextField, toast } from "@heroui/react";
import { Fingerprint, Lock, Pencil, Person, TrashBin, Xmark, Check } from "@gravity-ui/icons";
import { authClient, useSession } from "@/lib/auth-client";
import dayjs from "@/lib/dayjs";

type Passkey = {
  id: string;
  name?: string | null;
  createdAt: Date | string;
  deviceType?: string | null;
};

export default function SettingsPage() {
  const { data: session, refetch: refetchSession } = useSession();

  // ── Profile ──────────────────────────────────────────────────────────────
  const [profileName, setProfileName] = useState("");
  const [savingProfile, setSavingProfile] = useState(false);

  // sync name from session once loaded
  useEffect(() => {
    if (session?.user.name) setProfileName(session.user.name);
  }, [session?.user.name]);

  const handleSaveProfile = async () => {
    setSavingProfile(true);
    try {
      const res = await authClient.updateUser({ name: profileName.trim() });
      if (res?.error) {
        toast.danger(res.error.message ?? "保存失败");
      } else {
        toast.success("显示名称已更新");
        await refetchSession();
      }
    } catch {
      toast.danger("保存失败，请重试");
    } finally {
      setSavingProfile(false);
    }
  };

  // ── Password ─────────────────────────────────────────────────────────────
  const [currentPassword, setCurrentPassword] = useState("");
  const [newPassword, setNewPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");
  const [savingPw, setSavingPw] = useState(false);
  const [pwError, setPwError] = useState("");
  const [pwSuccess, setPwSuccess] = useState("");

  const handleChangePassword = async () => {
    setPwError("");
    setPwSuccess("");
    if (newPassword !== confirmPassword) {
      setPwError("两次输入的新密码不一致");
      return;
    }
    if (newPassword.length < 8) {
      setPwError("新密码至少需要 8 位");
      return;
    }
    setSavingPw(true);
    try {
      const res = await authClient.changePassword({
        currentPassword,
        newPassword,
        revokeOtherSessions: false,
      });
      if (res?.error) {
        setPwError(res.error.message ?? "修改密码失败");
      } else {
        setPwSuccess("密码已修改成功");
        setCurrentPassword("");
        setNewPassword("");
        setConfirmPassword("");
      }
    } catch {
      setPwError("修改密码失败，请重试");
    } finally {
      setSavingPw(false);
    }
  };

  // ── Passkey ───────────────────────────────────────────────────────────────
  const [passkeys, setPasskeys] = useState<Passkey[]>([]);
  const [loading, setLoading] = useState(true);
  const [addingName, setAddingName] = useState<string | null>(null); // null = collapsed
  const [registering, setRegistering] = useState(false);
  const [deletingId, setDeletingId] = useState<string | null>(null);
  const [renamingId, setRenamingId] = useState<string | null>(null);
  const [renameValue, setRenameValue] = useState("");
  const [renameSaving, setRenameSaving] = useState(false);
  const renameInputRef = useRef<HTMLInputElement>(null);

  const loadPasskeys = useCallback(async () => {
    setLoading(true);
    try {
      const res = await authClient.passkey.listUserPasskeys();
      setPasskeys((res.data as Passkey[] | null) ?? []);
    } catch {
      toast.danger("获取 Passkey 列表失败");
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    void loadPasskeys();
  }, [loadPasskeys]);

  const handleStartAdd = () => {
    setAddingName("");
  };

  const handleCancelAdd = () => setAddingName(null);

  const handleRegister = async () => {
    setRegistering(true);
    try {
      const res = await authClient.passkey.addPasskey({
        name: addingName?.trim() || undefined,
      });
      if (res?.error) {
        toast.danger(res.error.message ?? "注册 Passkey 失败");
      } else {
        toast.success("Passkey 注册成功");
        setAddingName(null);
        await loadPasskeys();
      }
    } catch {
      toast.danger("注册 Passkey 失败，请重试");
    } finally {
      setRegistering(false);
    }
  };

  const handleDelete = async (id: string) => {
    setDeletingId(id);
    try {
      const res = await authClient.passkey.deletePasskey({ id });
      if (res?.error) {
        toast.danger(res.error.message ?? "删除 Passkey 失败");
      } else {
        setPasskeys((prev) => prev.filter((p) => p.id !== id));
        toast.success("Passkey 已删除");
      }
    } catch {
      toast.danger("删除 Passkey 失败，请重试");
    } finally {
      setDeletingId(null);
    }
  };

  const startRename = (pk: Passkey) => {
    setRenamingId(pk.id);
    setRenameValue(pk.name ?? "");
    setTimeout(() => renameInputRef.current?.focus(), 50);
  };

  const cancelRename = () => {
    setRenamingId(null);
    setRenameValue("");
  };

  const handleRename = async (id: string) => {
    setRenameSaving(true);
    try {
      const res = await (authClient.passkey as any).updatePasskey({
        id,
        name: renameValue.trim() || undefined,
      });
      if (res?.error) {
        toast.danger(res.error.message ?? "重命名失败");
      } else {
        setPasskeys((prev) =>
          prev.map((p) => (p.id === id ? { ...p, name: renameValue.trim() || null } : p)),
        );
        setRenamingId(null);
      }
    } catch {
      toast.danger("重命名失败，请重试");
    } finally {
      setRenameSaving(false);
    }
  };

  return (
    <div className="mx-auto max-w-2xl space-y-6">
      <div>
        <h1 className="text-xl font-semibold text-foreground">账号设置</h1>
        <p className="mt-0.5 text-sm text-muted">管理您的个人信息和安全凭据</p>
      </div>

      {/* ── Profile section ─────────────────────────────────────────────── */}
      <div className="rounded-xl border border-border bg-surface-secondary">
        <div className="flex items-center gap-3 border-b border-border px-5 py-4">
          <div className="flex size-9 items-center justify-center rounded-lg bg-accent/10">
            <Person className="size-5 text-accent" />
          </div>
          <div>
            <p className="text-sm font-semibold text-foreground">个人信息</p>
            <p className="text-xs text-muted">修改您的显示名称</p>
          </div>
        </div>
        <div className="space-y-4 px-5 py-4">
          <TextField fullWidth>
            <Label className="text-sm font-medium">显示名称</Label>
            <Input
              placeholder="对外显示的名称"
              value={profileName}
              onChange={(e) => setProfileName(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === "Enter") void handleSaveProfile();
              }}
            />
          </TextField>
          <div className="flex justify-end">
            <Button
              size="sm"
              isDisabled={
                savingProfile || !profileName.trim() || profileName === session?.user.name
              }
              onPress={handleSaveProfile}
            >
              {savingProfile ? <Spinner size="sm" color="current" /> : "保存"}
            </Button>
          </div>
        </div>
      </div>

      {/* ── Password section ─────────────────────────────────────────────── */}
      <div className="rounded-xl border border-border bg-surface-secondary">
        <div className="flex items-center gap-3 border-b border-border px-5 py-4">
          <div className="flex size-9 items-center justify-center rounded-lg bg-accent/10">
            <Lock className="size-5 text-accent" />
          </div>
          <div>
            <p className="text-sm font-semibold text-foreground">修改密码</p>
            <p className="text-xs text-muted">建议定期更换密码以保护账号安全</p>
          </div>
        </div>
        <div className="space-y-4 px-5 py-4">
          <TextField fullWidth>
            <Label className="text-sm font-medium">当前密码</Label>
            <Input
              type="password"
              autoComplete="current-password"
              placeholder="输入当前密码"
              value={currentPassword}
              onChange={(e) => setCurrentPassword(e.target.value)}
            />
          </TextField>
          <TextField fullWidth>
            <Label className="text-sm font-medium">新密码</Label>
            <Input
              type="password"
              autoComplete="new-password"
              placeholder="至少 8 位"
              value={newPassword}
              onChange={(e) => setNewPassword(e.target.value)}
            />
          </TextField>
          <TextField fullWidth>
            <Label className="text-sm font-medium">确认新密码</Label>
            <Input
              type="password"
              autoComplete="new-password"
              placeholder="再次输入新密码"
              value={confirmPassword}
              onChange={(e) => setConfirmPassword(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === "Enter") void handleChangePassword();
              }}
            />
          </TextField>
          {pwError && (
            <Alert status="danger">
              <Alert.Indicator />
              <Alert.Content>
                <Alert.Description>{pwError}</Alert.Description>
              </Alert.Content>
              <CloseButton onPress={() => setPwError("")} />
            </Alert>
          )}
          {pwSuccess && (
            <Alert status="success">
              <Alert.Indicator />
              <Alert.Content>
                <Alert.Description>{pwSuccess}</Alert.Description>
              </Alert.Content>
              <CloseButton onPress={() => setPwSuccess("")} />
            </Alert>
          )}
          <div className="flex justify-end">
            <Button
              size="sm"
              isDisabled={savingPw || !currentPassword || !newPassword || !confirmPassword}
              onPress={handleChangePassword}
            >
              {savingPw ? <Spinner size="sm" color="current" /> : "确认修改"}
            </Button>
          </div>
        </div>
      </div>

      {/* ── Passkey section ──────────────────────────────────────────────── */}
      <div className="rounded-xl border border-border bg-surface-secondary">
        <div className="flex items-center justify-between border-b border-border px-5 py-4">
          <div className="flex items-center gap-3">
            <div className="flex size-9 items-center justify-center rounded-lg bg-accent/10">
              <Fingerprint className="size-5 text-accent" />
            </div>
            <div>
              <p className="text-sm font-semibold text-foreground">Passkey</p>
              <p className="text-xs text-muted">使用设备生物识别或 PIN 免密登录</p>
            </div>
          </div>
          {addingName === null && (
            <Button size="sm" variant="secondary" onPress={handleStartAdd}>
              添加 Passkey
            </Button>
          )}
        </div>

        {/* Inline add form */}
        {addingName !== null && (
          <div className="flex items-end gap-2 border-b border-border px-5 py-4">
            <TextField fullWidth>
              <Label className="text-sm font-medium">Passkey 名称</Label>
              <Input
                autoFocus
                placeholder="例如：MacBook Touch ID"
                value={addingName}
                onChange={(e) => setAddingName(e.target.value)}
                onKeyDown={(e) => {
                  if (e.key === "Enter") void handleRegister();
                  if (e.key === "Escape") handleCancelAdd();
                }}
              />
            </TextField>
            <Button isDisabled={registering} onPress={handleRegister}>
              {registering ? <Spinner size="sm" color="current" /> : "注册"}
            </Button>
            <Button variant="ghost" isDisabled={registering} onPress={handleCancelAdd}>
              取消
            </Button>
          </div>
        )}

        {loading ? (
          <div className="flex justify-center py-8">
            <Spinner />
          </div>
        ) : passkeys.length === 0 ? (
          <div className="py-8 text-center text-sm text-muted">尚未添加任何 Passkey</div>
        ) : (
          <ul className="divide-y divide-border">
            {passkeys.map((pk) => (
              <li key={pk.id} className="group flex items-center justify-between px-5 py-3.5">
                <div className="flex min-w-0 flex-1 items-center gap-3">
                  <Fingerprint className="size-4 shrink-0 text-muted" />
                  <div className="min-w-0 flex-1">
                    {/* Name row: text+pencil or inline input */}
                    <div className="flex items-center gap-1.5">
                      {renamingId === pk.id ? (
                        <>
                          <input
                            ref={renameInputRef}
                            className="min-w-0 max-w-48 rounded-md border border-border bg-transparent px-2 py-0.5 text-sm text-foreground outline-none focus:border-accent"
                            value={renameValue}
                            onChange={(e) => setRenameValue(e.target.value)}
                            onKeyDown={(e) => {
                              if (e.key === "Enter") void handleRename(pk.id);
                              if (e.key === "Escape") cancelRename();
                            }}
                            placeholder="输入名称"
                          />
                          <button
                            type="button"
                            disabled={renameSaving}
                            className="flex size-5 items-center justify-center rounded text-accent hover:bg-accent/10 disabled:opacity-50"
                            onClick={() => void handleRename(pk.id)}
                          >
                            {renameSaving ? <Spinner size="sm" /> : <Check className="size-3" />}
                          </button>
                          <button
                            type="button"
                            disabled={renameSaving}
                            className="flex size-5 items-center justify-center rounded text-muted hover:bg-surface-tertiary disabled:opacity-50"
                            onClick={cancelRename}
                          >
                            <Xmark className="size-3" />
                          </button>
                        </>
                      ) : (
                        <>
                          <p className="text-sm font-medium text-foreground">
                            {pk.name ?? pk.deviceType ?? "Passkey"}
                          </p>
                          <button
                            type="button"
                            className="flex size-5 items-center justify-center rounded text-muted opacity-0 transition-opacity hover:bg-surface-tertiary hover:text-foreground group-hover:opacity-100"
                            onClick={() => startRename(pk)}
                          >
                            <Pencil className="size-3" />
                          </button>
                        </>
                      )}
                    </div>
                    {/* Date row: always visible */}
                    <p className="text-xs text-muted">
                      添加于{" "}
                      {dayjs(pk.createdAt).format("YYYY年M月D日")}
                    </p>
                  </div>
                </div>
                <Button
                  isIconOnly
                  size="sm"
                  variant="danger-soft"
                  isDisabled={deletingId === pk.id || renamingId === pk.id}
                  onPress={() => handleDelete(pk.id)}
                >
                  {deletingId === pk.id ? <Spinner size="sm" /> : <TrashBin className="size-4" />}
                </Button>
              </li>
            ))}
          </ul>
        )}
      </div>
    </div>
  );
}
