"use client";

import { useState, useEffect, useCallback } from "react";
import { useRouter } from "next/navigation";
import { motion, AnimatePresence } from "framer-motion";
import {
  ArrowLeft,
  Mail,
  Clock,
  Star,
  MapPin,
  Trash2,
  Loader2,
  ChevronDown,
  LogOut,
  Lock,
  Edit3,
  Check,
  X,
  Eye,
  EyeOff,
} from "lucide-react";
import { getUserId, getCachedProfile, setCachedProfile, setCachedPreferences, logout } from "@/lib/userId";
import { getAvatarBg, AVATARS } from "@/lib/avatars";
import type { UserProfile, UserPreferences, DecisionRecord, FavoriteRecord, Restaurant } from "@/types";

function firstImage(r: Restaurant): string {
  if (r.images?.length > 0) return r.images[0];
  const legacy = (r as unknown as Record<string, unknown>).image;
  return typeof legacy === "string" ? legacy : "";
}

export default function ProfilePage() {
  const router = useRouter();
  const [userId, setUserId] = useState("");
  const [profile, setProfile] = useState<(UserProfile & { email?: string; preferences?: UserPreferences }) | null>(null);
  const [loading, setLoading] = useState(true);

  const [history, setHistory] = useState<DecisionRecord[]>([]);
  const [favorites, setFavorites] = useState<FavoriteRecord[]>([]);
  const [historyLoading, setHistoryLoading] = useState(false);
  const [favLoading, setFavLoading] = useState(false);

  const [editingUsername, setEditingUsername] = useState(false);
  const [newUsername, setNewUsername] = useState("");
  const [usernameSaving, setUsernameSaving] = useState(false);
  const [usernameMsg, setUsernameMsg] = useState("");

  const [editingPassword, setEditingPassword] = useState(false);
  const [currentPassword, setCurrentPassword] = useState("");
  const [newPassword, setNewPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");
  const [showPassword, setShowPassword] = useState(false);
  const [passwordSaving, setPasswordSaving] = useState(false);
  const [passwordMsg, setPasswordMsg] = useState("");

  const [editingAvatar, setEditingAvatar] = useState(false);

  const [email, setEmail] = useState("");
  const [emailSaving, setEmailSaving] = useState(false);
  const [emailMsg, setEmailMsg] = useState("");

  const [showHistory, setShowHistory] = useState(true);
  const [showFavorites, setShowFavorites] = useState(true);
  const [toast, setToast] = useState("");

  const showToast = useCallback((msg: string) => {
    setToast(msg);
    setTimeout(() => setToast(""), 2200);
  }, []);

  useEffect(() => {
    const cached = getCachedProfile();
    if (!cached) {
      router.push("/");
      return;
    }

    const id = getUserId();
    setUserId(id);

    fetch(`/api/user?id=${id}`)
      .then((r) => r.json())
      .then((data) => {
        if (data) {
          setProfile(data);
          setEmail(data.email ?? "");
          setCachedProfile({ id: data.id, username: data.username, avatar: data.avatar });
          if (data.preferences) setCachedPreferences(data.preferences);
        } else {
          router.push("/");
        }
      })
      .catch(() => {
        setProfile({ ...cached });
      })
      .finally(() => setLoading(false));
  }, [router]);

  useEffect(() => {
    if (!userId) return;

    setHistoryLoading(true);
    fetch(`/api/user/history?userId=${userId}`)
      .then((r) => r.json())
      .then(setHistory)
      .catch(() => {})
      .finally(() => setHistoryLoading(false));

    setFavLoading(true);
    fetch(`/api/user/favorite?userId=${userId}`)
      .then((r) => r.json())
      .then(setFavorites)
      .catch(() => {})
      .finally(() => setFavLoading(false));
  }, [userId]);

  const handleSaveUsername = async () => {
    const trimmed = newUsername.trim();
    if (trimmed.length < 2 || trimmed.length > 16) {
      setUsernameMsg("用户名需要 2-16 个字符");
      return;
    }

    setUsernameSaving(true);
    setUsernameMsg("");
    try {
      const res = await fetch("/api/user", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ userId, username: trimmed }),
      });
      const data = await res.json();
      if (res.ok) {
        setProfile((prev) => prev ? { ...prev, username: trimmed } : prev);
        setCachedProfile({ id: userId, username: trimmed, avatar: profile!.avatar });
        setEditingUsername(false);
        showToast("用户名已更新");
      } else {
        setUsernameMsg(data.error ?? "更新失败");
      }
    } catch {
      setUsernameMsg("网络错误");
    } finally {
      setUsernameSaving(false);
    }
  };

  const handleSavePassword = async () => {
    if (!currentPassword) {
      setPasswordMsg("请输入当前密码");
      return;
    }
    if (newPassword.length < 6) {
      setPasswordMsg("新密码至少 6 个字符");
      return;
    }
    if (newPassword !== confirmPassword) {
      setPasswordMsg("两次密码不一致");
      return;
    }

    setPasswordSaving(true);
    setPasswordMsg("");
    try {
      const res = await fetch("/api/user", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ userId, currentPassword, newPassword }),
      });
      const data = await res.json();
      if (res.ok) {
        setEditingPassword(false);
        setCurrentPassword("");
        setNewPassword("");
        setConfirmPassword("");
        showToast("密码已更新");
      } else {
        setPasswordMsg(data.error ?? "更新失败");
      }
    } catch {
      setPasswordMsg("网络错误");
    } finally {
      setPasswordSaving(false);
    }
  };

  const handleSaveAvatar = async (emoji: string) => {
    try {
      const res = await fetch("/api/user", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ userId, avatar: emoji }),
      });
      if (res.ok) {
        setProfile((prev) => prev ? { ...prev, avatar: emoji } : prev);
        setCachedProfile({ id: userId, username: profile!.username, avatar: emoji });
        setEditingAvatar(false);
        showToast("头像已更新");
      }
    } catch {
      showToast("更新失败");
    }
  };

  const handleSaveEmail = async () => {
    if (email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
      setEmailMsg("邮箱格式不正确");
      return;
    }

    setEmailSaving(true);
    setEmailMsg("");
    try {
      const res = await fetch("/api/user", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ userId, email: email || null }),
      });
      if (res.ok) {
        setEmailMsg(email ? "邮箱已绑定" : "邮箱已解绑");
      } else {
        const data = await res.json().catch(() => ({}));
        setEmailMsg(data.error ?? "保存失败");
      }
    } catch {
      setEmailMsg("网络错误");
    } finally {
      setEmailSaving(false);
    }
  };

  const handleRemoveFavorite = async (favId: string) => {
    try {
      await fetch("/api/user/favorite", {
        method: "DELETE",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ userId, favoriteId: favId }),
      });
      setFavorites((f) => f.filter((x) => x.id !== favId));
      showToast("已取消收藏");
    } catch {
      showToast("操作失败");
    }
  };

  const handleLogout = () => {
    logout();
    router.push("/");
  };

  if (loading) {
    return (
      <div className="flex min-h-dvh items-center justify-center bg-background">
        <Loader2 size={24} className="animate-spin text-muted" />
      </div>
    );
  }

  if (!profile) return null;

  const amapNavUrl = (r: Restaurant) =>
    r.location
      ? `https://uri.amap.com/marker?position=${r.location}&name=${encodeURIComponent(r.name)}&callnative=1`
      : `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(r.name)}`;

  return (
    <div className="min-h-dvh bg-background pb-16 overflow-y-auto scrollbar-none">
      <nav className="sticky top-0 z-10 flex h-14 items-center gap-3 bg-background/80 px-4 backdrop-blur-sm">
        <button
          onClick={() => router.push("/")}
          className="flex h-8 w-8 items-center justify-center rounded-full text-muted transition-colors active:bg-elevated"
        >
          <ArrowLeft size={20} />
        </button>
        <h1 className="text-base font-bold text-white">个人中心</h1>
      </nav>

      <div className="mx-auto max-w-sm px-5">
        {/* Profile card */}
        <motion.div
          className="rounded-2xl bg-surface p-4 ring-1 ring-border"
          initial={{ y: 10, opacity: 0 }}
          animate={{ y: 0, opacity: 1 }}
        >
          <div className="flex items-center gap-4">
            <button
              onClick={() => setEditingAvatar(!editingAvatar)}
              className={`relative flex h-14 w-14 items-center justify-center rounded-2xl text-2xl transition-transform active:scale-95 ${getAvatarBg(profile.avatar)}`}
            >
              {profile.avatar}
              <span className="absolute -bottom-0.5 -right-0.5 flex h-5 w-5 items-center justify-center rounded-full bg-surface text-muted shadow-sm ring-1 ring-border">
                <Edit3 size={10} />
              </span>
            </button>
            <div className="flex-1">
              {editingUsername ? (
                <div className="flex items-center gap-2">
                  <input
                    type="text"
                    value={newUsername}
                    onChange={(e) => {
                      setNewUsername(e.target.value.slice(0, 16));
                      setUsernameMsg("");
                    }}
                    maxLength={16}
                    autoFocus
                    className="h-8 flex-1 rounded-lg border-none bg-elevated px-2 text-sm text-white outline-none ring-1 ring-border focus:ring-2 focus:ring-accent/50"
                  />
                  <button
                    onClick={handleSaveUsername}
                    disabled={usernameSaving}
                    className="flex h-8 w-8 items-center justify-center rounded-lg bg-accent text-white disabled:opacity-50"
                  >
                    {usernameSaving ? <Loader2 size={14} className="animate-spin" /> : <Check size={14} />}
                  </button>
                  <button
                    onClick={() => { setEditingUsername(false); setUsernameMsg(""); }}
                    className="flex h-8 w-8 items-center justify-center rounded-lg bg-elevated text-muted"
                  >
                    <X size={14} />
                  </button>
                </div>
              ) : (
                <div className="flex items-center gap-2">
                  <h2 className="text-lg font-bold text-white">{profile.username}</h2>
                  <button
                    onClick={() => { setEditingUsername(true); setNewUsername(profile.username); }}
                    className="text-muted transition-colors active:text-gray-300"
                  >
                    <Edit3 size={13} />
                  </button>
                </div>
              )}
              {usernameMsg && <p className="mt-1 text-xs text-rose-400">{usernameMsg}</p>}
            </div>
          </div>

          {/* Avatar picker */}
          <AnimatePresence>
            {editingAvatar && (
              <motion.div
                initial={{ height: 0, opacity: 0 }}
                animate={{ height: "auto", opacity: 1 }}
                exit={{ height: 0, opacity: 0 }}
                transition={{ duration: 0.2 }}
                className="overflow-hidden"
              >
                <div className="mt-4 grid grid-cols-6 gap-2">
                  {AVATARS.map((a) => (
                    <button
                      key={a.emoji}
                      onClick={() => handleSaveAvatar(a.emoji)}
                      className={`flex h-11 w-11 items-center justify-center rounded-xl text-xl transition-all ${
                        profile.avatar === a.emoji
                          ? `${a.bg} scale-110 ring-2 ring-accent ring-offset-1 ring-offset-surface`
                          : "bg-elevated hover:bg-subtle"
                      }`}
                    >
                      {a.emoji}
                    </button>
                  ))}
                </div>
              </motion.div>
            )}
          </AnimatePresence>
        </motion.div>

        {/* Change password */}
        <motion.div
          className="mt-4 rounded-2xl bg-surface p-4 ring-1 ring-border"
          initial={{ y: 10, opacity: 0 }}
          animate={{ y: 0, opacity: 1 }}
          transition={{ delay: 0.05 }}
        >
          <button
            onClick={() => { setEditingPassword(!editingPassword); setPasswordMsg(""); }}
            className="flex w-full items-center gap-2"
          >
            <Lock size={15} className="text-muted" />
            <h3 className="text-sm font-semibold text-gray-300">修改密码</h3>
          </button>

          <AnimatePresence>
            {editingPassword && (
              <motion.div
                initial={{ height: 0, opacity: 0 }}
                animate={{ height: "auto", opacity: 1 }}
                exit={{ height: 0, opacity: 0 }}
                transition={{ duration: 0.2 }}
                className="overflow-hidden"
              >
                <div className="mt-3 flex flex-col gap-3">
                  <div>
                    <p className="text-xs text-muted">当前密码</p>
                    <div className="relative mt-1">
                      <input
                        type={showPassword ? "text" : "password"}
                        value={currentPassword}
                        onChange={(e) => { setCurrentPassword(e.target.value); setPasswordMsg(""); }}
                        className="h-9 w-full rounded-lg border-none bg-elevated px-3 pr-9 text-sm text-white outline-none ring-1 ring-border focus:ring-2 focus:ring-accent/50"
                      />
                      <button
                        type="button"
                        onClick={() => setShowPassword(!showPassword)}
                        className="absolute right-2.5 top-1/2 -translate-y-1/2 text-muted"
                      >
                        {showPassword ? <EyeOff size={14} /> : <Eye size={14} />}
                      </button>
                    </div>
                  </div>
                  <div>
                    <p className="text-xs text-muted">新密码</p>
                    <input
                      type={showPassword ? "text" : "password"}
                      value={newPassword}
                      onChange={(e) => { setNewPassword(e.target.value); setPasswordMsg(""); }}
                      placeholder="至少 6 个字符"
                      className="mt-1 h-9 w-full rounded-lg border-none bg-elevated px-3 text-sm text-white outline-none ring-1 ring-border placeholder:text-dim focus:ring-2 focus:ring-accent/50"
                    />
                  </div>
                  <div>
                    <p className="text-xs text-muted">确认新密码</p>
                    <input
                      type={showPassword ? "text" : "password"}
                      value={confirmPassword}
                      onChange={(e) => { setConfirmPassword(e.target.value); setPasswordMsg(""); }}
                      placeholder="再次输入新密码"
                      className="mt-1 h-9 w-full rounded-lg border-none bg-elevated px-3 text-sm text-white outline-none ring-1 ring-border placeholder:text-dim focus:ring-2 focus:ring-accent/50"
                    />
                  </div>

                  {passwordMsg && (
                    <p className={`text-xs ${passwordMsg.includes("错误") || passwordMsg.includes("失败") || passwordMsg.includes("不一致") || passwordMsg.includes("至少") ? "text-rose-400" : "text-accent"}`}>
                      {passwordMsg}
                    </p>
                  )}

                  <button
                    onClick={handleSavePassword}
                    disabled={passwordSaving}
                    className="flex h-9 items-center justify-center gap-1.5 rounded-lg bg-accent text-xs font-semibold text-white transition-colors hover:bg-accent-hover disabled:opacity-50"
                  >
                    {passwordSaving ? <Loader2 size={14} className="animate-spin" /> : "保存新密码"}
                  </button>
                </div>
              </motion.div>
            )}
          </AnimatePresence>
        </motion.div>

        {/* Email binding */}
        <motion.div
          className="mt-4 rounded-2xl bg-surface p-4 ring-1 ring-border"
          initial={{ y: 10, opacity: 0 }}
          animate={{ y: 0, opacity: 1 }}
          transition={{ delay: 0.1 }}
        >
          <div className="flex items-center gap-2">
            <Mail size={15} className="text-muted" />
            <h3 className="text-sm font-semibold text-gray-300">绑定邮箱</h3>
            <span className="text-[10px] text-dim">（可选）</span>
          </div>
          <div className="mt-3 flex gap-2">
            <input
              type="email"
              placeholder="your@email.com"
              value={email}
              onChange={(e) => {
                setEmail(e.target.value);
                setEmailMsg("");
              }}
              className="h-9 flex-1 rounded-lg border-none bg-elevated px-3 text-sm text-white outline-none ring-1 ring-border placeholder:text-dim focus:ring-2 focus:ring-accent/50"
            />
            <button
              onClick={handleSaveEmail}
              disabled={emailSaving}
              className="flex h-9 items-center gap-1 rounded-lg bg-accent px-3 text-xs font-semibold text-white transition-colors hover:bg-accent-hover disabled:opacity-50"
            >
              {emailSaving ? <Loader2 size={13} className="animate-spin" /> : "保存"}
            </button>
          </div>
          {emailMsg && (
            <p className={`mt-2 text-xs ${emailMsg.includes("失败") || emailMsg.includes("不正确") ? "text-rose-400" : "text-accent"}`}>
              {emailMsg}
            </p>
          )}
        </motion.div>

        {/* Decision History */}
        <motion.div
          className="mt-4 rounded-2xl bg-surface p-4 ring-1 ring-border"
          initial={{ y: 10, opacity: 0 }}
          animate={{ y: 0, opacity: 1 }}
          transition={{ delay: 0.15 }}
        >
          <button
            onClick={() => setShowHistory((v) => !v)}
            className="flex w-full items-center justify-between"
          >
            <div className="flex items-center gap-2">
              <Clock size={15} className="text-muted" />
              <h3 className="text-sm font-semibold text-gray-300">
                决策记录 {history.length > 0 && `(${history.length})`}
              </h3>
            </div>
            <motion.span
              animate={{ rotate: showHistory ? 180 : 0 }}
              transition={{ duration: 0.2 }}
              className="text-muted"
            >
              <ChevronDown size={16} />
            </motion.span>
          </button>

          <AnimatePresence>
            {showHistory && (
              <motion.div
                initial={{ height: 0, opacity: 0 }}
                animate={{ height: "auto", opacity: 1 }}
                exit={{ height: 0, opacity: 0 }}
                transition={{ duration: 0.2 }}
                className="overflow-hidden"
              >
                {historyLoading ? (
                  <div className="flex justify-center py-6">
                    <Loader2 size={18} className="animate-spin text-muted" />
                  </div>
                ) : history.length === 0 ? (
                  <p className="py-6 text-center text-xs text-muted">
                    还没有决策记录
                  </p>
                ) : (
                  <div className="mt-3 flex flex-col gap-2">
                    {history.map((d) => (
                      <a
                        key={d.id}
                        href={amapNavUrl(d.restaurantData)}
                        target="_blank"
                        rel="noopener noreferrer"
                        className="flex gap-3 rounded-xl bg-elevated p-2.5 transition-colors active:bg-subtle"
                      >
                        {firstImage(d.restaurantData) && (
                          <img
                            src={firstImage(d.restaurantData)}
                            alt={d.restaurantName}
                            className="h-12 w-12 shrink-0 rounded-lg object-cover"
                            referrerPolicy="no-referrer"
                          />
                        )}
                        <div className="flex min-w-0 flex-1 flex-col justify-center">
                          <p className="truncate text-sm font-semibold text-white">{d.restaurantName}</p>
                          <div className="mt-0.5 flex items-center gap-2 text-[11px] text-muted">
                            <span>{d.matchType === "unanimous" ? "全员一致" : "最佳匹配"}</span>
                            <span>{d.participants} 人参与</span>
                            <span>{new Date(d.createdAt).toLocaleDateString("zh-CN", { month: "short", day: "numeric" })}</span>
                          </div>
                        </div>
                      </a>
                    ))}
                  </div>
                )}
              </motion.div>
            )}
          </AnimatePresence>
        </motion.div>

        {/* Favorites */}
        <motion.div
          className="mt-4 rounded-2xl bg-surface p-4 ring-1 ring-border"
          initial={{ y: 10, opacity: 0 }}
          animate={{ y: 0, opacity: 1 }}
          transition={{ delay: 0.2 }}
        >
          <button
            onClick={() => setShowFavorites((v) => !v)}
            className="flex w-full items-center justify-between"
          >
            <div className="flex items-center gap-2">
              <Star size={15} className="text-muted" />
              <h3 className="text-sm font-semibold text-gray-300">
                收藏餐厅 {favorites.length > 0 && `(${favorites.length})`}
              </h3>
            </div>
            <motion.span
              animate={{ rotate: showFavorites ? 180 : 0 }}
              transition={{ duration: 0.2 }}
              className="text-muted"
            >
              <ChevronDown size={16} />
            </motion.span>
          </button>

          <AnimatePresence>
            {showFavorites && (
              <motion.div
                initial={{ height: 0, opacity: 0 }}
                animate={{ height: "auto", opacity: 1 }}
                exit={{ height: 0, opacity: 0 }}
                transition={{ duration: 0.2 }}
                className="overflow-hidden"
              >
                {favLoading ? (
                  <div className="flex justify-center py-6">
                    <Loader2 size={18} className="animate-spin text-muted" />
                  </div>
                ) : favorites.length === 0 ? (
                  <p className="py-6 text-center text-xs text-muted">
                    还没有收藏的餐厅
                  </p>
                ) : (
                  <div className="mt-3 flex flex-col gap-2">
                    {favorites.map((f) => {
                      const r = f.restaurantData;
                      return (
                        <div
                          key={f.id}
                          className="flex gap-3 rounded-xl bg-elevated p-2.5"
                        >
                          {firstImage(r) && (
                            <img
                              src={firstImage(r)}
                              alt={r.name}
                              className="h-12 w-12 shrink-0 rounded-lg object-cover"
                              referrerPolicy="no-referrer"
                            />
                          )}
                          <div className="flex min-w-0 flex-1 flex-col justify-center">
                            <p className="truncate text-sm font-semibold text-white">{r.name}</p>
                            <div className="mt-0.5 flex items-center gap-2 text-[11px] text-muted">
                              <span className="flex items-center gap-0.5">
                                <Star size={10} className="fill-amber-400 text-amber-400" />
                                {r.rating}
                              </span>
                              <span>{r.price}</span>
                              {r.distance && (
                                <span className="flex items-center gap-0.5">
                                  <MapPin size={10} />
                                  {r.distance}
                                </span>
                              )}
                            </div>
                          </div>
                          <button
                            onClick={() => handleRemoveFavorite(f.id)}
                            className="flex h-8 w-8 shrink-0 items-center justify-center self-center rounded-full text-muted transition-colors active:bg-subtle active:text-rose-400"
                          >
                            <Trash2 size={14} />
                          </button>
                        </div>
                      );
                    })}
                  </div>
                )}
              </motion.div>
            )}
          </AnimatePresence>
        </motion.div>

        {/* Logout */}
        <motion.div
          className="mt-6 flex justify-center"
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          transition={{ delay: 0.25 }}
        >
          <button
            onClick={handleLogout}
            className="flex items-center gap-1.5 text-xs font-medium text-muted transition-colors hover:text-rose-400"
          >
            <LogOut size={13} />
            退出登录
          </button>
        </motion.div>
      </div>

      <AnimatePresence>
        {toast && (
          <motion.div
            className="fixed left-1/2 top-10 z-60 -translate-x-1/2 rounded-xl bg-elevated px-4 py-2.5 text-xs font-medium text-white shadow-lg ring-1 ring-subtle"
            initial={{ opacity: 0, y: -12, x: "-50%" }}
            animate={{ opacity: 1, y: 0, x: "-50%" }}
            exit={{ opacity: 0, y: -12, x: "-50%" }}
            transition={{ type: "spring", stiffness: 400, damping: 25 }}
          >
            {toast}
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}
