import React, { useEffect, useState } from "react";
import {
  API_BASE,
  authClientFetchHeaders,
  buildAuthCallbackUrl,
  clearAuthClientContext,
  fetchClientVisitMeta,
  formatAuthBanMessage,
  persistAuthClientFromFlow
} from "../config";
import UserPortalAuthSection from "./userPortal/UserPortalAuthSection";
import UserPortalProfileSection from "./userPortal/UserPortalProfileSection";

export default function UserPortal({ onReady, authFlow, onPreviewImage }) {
  const [account, setAccount] = useState("");
  const [password, setPassword] = useState("");
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");
  const [mode, setMode] = useState("login");

  const [registerForm, setRegisterForm] = useState({
    account: "", password: "", username: "", email: "", code: "", inviteCode: ""
  });
  const [registrationRequireInvite, setRegistrationRequireInvite] = useState(false);
  const [registerSent, setRegisterSent] = useState(false);
  const [registerExpiresAt, setRegisterExpiresAt] = useState("");
  const [registerLoading, setRegisterLoading] = useState(false);
  const [registerError, setRegisterError] = useState("");
  const [registerMessage, setRegisterMessage] = useState("");

  const [resetForm, setResetForm] = useState({
    account: "", email: "", code: "", newPassword: ""
  });
  const [resetSent, setResetSent] = useState(false);
  const [resetExpiresAt, setResetExpiresAt] = useState("");
  const [resetLoading, setResetLoading] = useState(false);
  const [resetError, setResetError] = useState("");
  const [resetMessage, setResetMessage] = useState("");

  const [secondaryForm, setSecondaryForm] = useState({ email: "", code: "" });
  const [secondarySent, setSecondarySent] = useState(false);
  const [secondaryExpiresAt, setSecondaryExpiresAt] = useState("");
  const [secondaryLoading, setSecondaryLoading] = useState(false);
  const [secondaryError, setSecondaryError] = useState("");
  const [secondaryMessage, setSecondaryMessage] = useState("");

  const [profileForm, setProfileForm] = useState({
    username: "", phone: "", avatarUrl: "", websiteUrl: "", bio: "", password: ""
  });
  const [profileLoading, setProfileLoading] = useState(false);
  const [profileError, setProfileError] = useState("");
  const [profileMessage, setProfileMessage] = useState("");
  const [profileEditorOpen, setProfileEditorOpen] = useState(false);
  const [profileEditorFocus, setProfileEditorFocus] = useState("");
  const [secondaryEditorOpen, setSecondaryEditorOpen] = useState(false);

  const [checkInReward, setCheckInReward] = useState(1);
  const [checkInToday, setCheckInToday] = useState(false);
  const [checkInLoading, setCheckInLoading] = useState(false);
  const [checkInError, setCheckInError] = useState("");
  const [checkInMessage, setCheckInMessage] = useState("");

  const isAuthFlow = Boolean(authFlow?.redirectUri);

  const redirectToAuthCallback = (tokenValue, userData, expiresAt = "") => {
    if (!isAuthFlow || !authFlow?.redirectUri || !tokenValue) return;
    const callbackUrl = buildAuthCallbackUrl(authFlow.redirectUri, {
      token: tokenValue,
      account: userData?.account || "",
      username: userData?.username || "",
      expiresAt,
      state: authFlow.state || ""
    });
    window.location.replace(callbackUrl);
  };

  const clearTokenAndUser = () => {
    localStorage.removeItem("sproutgate_token");
    localStorage.removeItem("sproutgate_token_expires_at");
    setUser(null);
  };

  const bearerHeaders = (tokenValue) => ({
    ...authClientFetchHeaders(),
    Authorization: `Bearer ${tokenValue}`
  });

  const syncCurrentUser = async (tokenValue) => {
    const baseHeaders = bearerHeaders(tokenValue);
    const res = await fetch(`${API_BASE}/api/auth/me`, { headers: baseHeaders });
    const data = await res.json();
    if (!res.ok) {
      if (res.status === 403) {
        clearTokenAndUser();
        const msg = formatAuthBanMessage(data);
        setError(msg);
        throw new Error(msg);
      }
      throw new Error(data.error || "加载用户失败");
    }
    if (data.user) setUser(data.user);
    const checkIn = data.checkIn || {};
    setCheckInReward(Number(checkIn.rewardCoins) || 1);
    setCheckInToday(Boolean(checkIn.checkedInToday));

    fetchClientVisitMeta()
      .then((meta) => {
        if (!meta.ip && !meta.displayLocation) return null;
        const h = { ...baseHeaders };
        if (meta.ip) h["X-Visit-Ip"] = meta.ip;
        if (meta.displayLocation) h["X-Visit-Location"] = meta.displayLocation;
        return fetch(`${API_BASE}/api/auth/me`, { headers: h });
      })
      .then(async (r) => {
        if (!r) return null;
        const d = await r.json().catch(() => ({}));
        if (r.status === 403) {
          clearTokenAndUser();
          setError(formatAuthBanMessage(d));
          return null;
        }
        return r.ok ? d : null;
      })
      .then((d) => {
        if (!d) return;
        if (d.user) setUser(d.user);
        const c = d.checkIn;
        if (c) {
          setCheckInReward(Number(c.rewardCoins) || 1);
          setCheckInToday(Boolean(c.checkedInToday));
        }
      })
      .catch(() => {});

    return data;
  };

  useEffect(() => {
    let cancelled = false;
    const done = () => { if (!cancelled && onReady) onReady(); };
    const token = localStorage.getItem("sproutgate_token");
    if (token) {
      syncCurrentUser(token).catch(() => {}).finally(() => done());
    } else {
      done();
    }
    return () => { cancelled = true; };
  }, [onReady]);

  useEffect(() => {
    persistAuthClientFromFlow(authFlow);
  }, [authFlow]);

  useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        const res = await fetch(`${API_BASE}/api/public/registration-policy`);
        const data = await res.json().catch(() => ({}));
        if (!cancelled && res.ok) {
          setRegistrationRequireInvite(Boolean(data.requireInviteCode));
        }
      } catch {
        /* 忽略，默认不要求邀请码 */
      }
    })();
    return () => { cancelled = true; };
  }, []);

  useEffect(() => {
    if (user) {
      setProfileForm({
        username: user.username || "",
        phone: user.phone || "",
        avatarUrl: user.avatarUrl || "",
        websiteUrl: user.websiteUrl || "",
        bio: user.bio || "",
        password: ""
      });
    }
  }, [user]);

  const handleLogin = async (event) => {
    event.preventDefault();
    setLoading(true);
    setError("");
    try {
      const loginPayload = { account, password };
      const cid = (authFlow?.clientId || "").trim();
      const cname = (authFlow?.clientName || "").trim();
      if (cid) {
        loginPayload.clientId = cid;
        if (cname) loginPayload.clientName = cname;
      } else {
        const h = authClientFetchHeaders();
        if (h["X-Auth-Client"]) {
          loginPayload.clientId = h["X-Auth-Client"];
          if (h["X-Auth-Client-Name"]) loginPayload.clientName = h["X-Auth-Client-Name"];
        }
      }
      const res = await fetch(`${API_BASE}/api/auth/login`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(loginPayload)
      });
      const data = await res.json();
      if (!res.ok) {
        throw new Error(
          res.status === 403 ? formatAuthBanMessage(data) : (data.error || "登录失败")
        );
      }
      localStorage.setItem("sproutgate_token", data.token);
      localStorage.setItem("sproutgate_token_expires_at", data.expiresAt || "");
      setUser(data.user);
      syncCurrentUser(data.token).catch(() => {});
      setAccount("");
      setPassword("");
      if (isAuthFlow) {
        redirectToAuthCallback(data.token, data.user, data.expiresAt || "");
        return;
      }
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };

  const handleLogout = () => {
    localStorage.removeItem("sproutgate_token");
    localStorage.removeItem("sproutgate_token_expires_at");
    clearAuthClientContext();
    setUser(null);
    setProfileEditorOpen(false);
    setProfileEditorFocus("");
    setSecondaryEditorOpen(false);
    setCheckInReward(1);
    setCheckInToday(false);
    setCheckInError("");
    setCheckInMessage("");
  };

  const handleContinueAuth = () => {
    const tokenValue = localStorage.getItem("sproutgate_token") || "";
    if (!tokenValue) {
      setError("当前没有可用的登录会话，请先重新登录");
      return;
    }
    redirectToAuthCallback(
      tokenValue, user,
      localStorage.getItem("sproutgate_token_expires_at") || ""
    );
  };

  const handleSwitchAuthAccount = () => {
    handleLogout();
    setMode("login");
    setAccount("");
    setPassword("");
    setError("");
  };

  const handleRegisterChange = (field, value) => {
    setRegisterForm((prev) => ({ ...prev, [field]: value }));
  };

  const resetRegisterFlow = () => {
    setRegisterSent(false);
    setRegisterExpiresAt("");
    setRegisterForm({ account: "", password: "", username: "", email: "", code: "", inviteCode: "" });
  };

  const handleSendCode = async (event) => {
    event.preventDefault();
    setRegisterLoading(true);
    setRegisterError("");
    setRegisterMessage("");
    if (!registerForm.account || !registerForm.password || !registerForm.email) {
      setRegisterError("请填写账户、密码和邮箱");
      setRegisterLoading(false);
      return;
    }
    if (registrationRequireInvite && !String(registerForm.inviteCode || "").trim()) {
      setRegisterError("请输入邀请码");
      setRegisterLoading(false);
      return;
    }
    try {
      const payload = {
        account: registerForm.account,
        password: registerForm.password,
        username: registerForm.username,
        email: registerForm.email
      };
      const inv = String(registerForm.inviteCode || "").trim();
      if (inv) payload.inviteCode = inv;
      const res = await fetch(`${API_BASE}/api/auth/register`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(payload)
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || "发送验证码失败");
      setRegisterSent(true);
      setRegisterExpiresAt(data.expiresAt || "");
      setRegisterMessage("验证码已发送，请检查邮箱");
    } catch (err) {
      setRegisterError(err.message);
    } finally {
      setRegisterLoading(false);
    }
  };

  const handleVerifyRegister = async (event) => {
    event.preventDefault();
    setRegisterLoading(true);
    setRegisterError("");
    setRegisterMessage("");
    if (!registerForm.account || !registerForm.code) {
      setRegisterError("请输入账户与验证码");
      setRegisterLoading(false);
      return;
    }
    try {
      const res = await fetch(`${API_BASE}/api/auth/verify-email`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ account: registerForm.account, code: registerForm.code })
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || "验证失败");
      setRegisterMessage("注册成功，请使用账号登录");
      setRegisterSent(false);
      setRegisterForm({ account: "", password: "", username: "", email: "", code: "", inviteCode: "" });
      setMode("login");
    } catch (err) {
      setRegisterError(err.message);
    } finally {
      setRegisterLoading(false);
    }
  };

  const handleResetChange = (field, value) => {
    setResetForm((prev) => ({ ...prev, [field]: value }));
  };

  const handleSendReset = async (event) => {
    event.preventDefault();
    setResetLoading(true);
    setResetError("");
    setResetMessage("");
    if (!resetForm.account || !resetForm.email) {
      setResetError("请填写账户与邮箱");
      setResetLoading(false);
      return;
    }
    try {
      const res = await fetch(`${API_BASE}/api/auth/forgot-password`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ account: resetForm.account, email: resetForm.email })
      });
      const data = await res.json();
      if (!res.ok) {
        throw new Error(
          res.status === 403 ? formatAuthBanMessage(data) : (data.error || "发送重置邮件失败")
        );
      }
      setResetSent(true);
      setResetExpiresAt(data.expiresAt || "");
      setResetMessage("重置验证码已发送，请检查邮箱");
    } catch (err) {
      setResetError(err.message);
    } finally {
      setResetLoading(false);
    }
  };

  const handleResetPassword = async (event) => {
    event.preventDefault();
    setResetLoading(true);
    setResetError("");
    setResetMessage("");
    if (!resetForm.account || !resetForm.code || !resetForm.newPassword) {
      setResetError("请填写账户、验证码与新密码");
      setResetLoading(false);
      return;
    }
    try {
      const res = await fetch(`${API_BASE}/api/auth/reset-password`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          account: resetForm.account,
          code: resetForm.code,
          newPassword: resetForm.newPassword
        })
      });
      const data = await res.json();
      if (!res.ok) {
        throw new Error(
          res.status === 403 ? formatAuthBanMessage(data) : (data.error || "重置失败")
        );
      }
      setResetMessage("密码已重置，请使用新密码登录");
      setResetSent(false);
      setResetForm({ account: "", email: "", code: "", newPassword: "" });
      setMode("login");
    } catch (err) {
      setResetError(err.message);
    } finally {
      setResetLoading(false);
    }
  };

  const handleSecondaryChange = (field, value) => {
    setSecondaryForm((prev) => ({ ...prev, [field]: value }));
  };

  const handleSendSecondary = async (event) => {
    event.preventDefault();
    setSecondaryLoading(true);
    setSecondaryError("");
    setSecondaryMessage("");
    const token = localStorage.getItem("sproutgate_token");
    if (!token) { setSecondaryError("请先登录"); setSecondaryLoading(false); return; }
    if (!secondaryForm.email) { setSecondaryError("请输入辅助邮箱"); setSecondaryLoading(false); return; }
    try {
      const res = await fetch(`${API_BASE}/api/auth/secondary-email/request`, {
        method: "POST",
        headers: { "Content-Type": "application/json", ...bearerHeaders(token) },
        body: JSON.stringify({ email: secondaryForm.email })
      });
      const data = await res.json();
      if (!res.ok) {
        if (res.status === 403) {
          clearTokenAndUser();
          setSecondaryError(formatAuthBanMessage(data));
        } else {
          throw new Error(data.error || "发送验证码失败");
        }
        return;
      }
      setSecondarySent(true);
      setSecondaryExpiresAt(data.expiresAt || "");
      setSecondaryMessage("验证码已发送，请检查邮箱");
    } catch (err) {
      setSecondaryError(err.message);
    } finally {
      setSecondaryLoading(false);
    }
  };

  const handleVerifySecondary = async (event) => {
    event.preventDefault();
    setSecondaryLoading(true);
    setSecondaryError("");
    setSecondaryMessage("");
    const token = localStorage.getItem("sproutgate_token");
    if (!token) { setSecondaryError("请先登录"); setSecondaryLoading(false); return; }
    if (!secondaryForm.email || !secondaryForm.code) {
      setSecondaryError("请输入邮箱与验证码");
      setSecondaryLoading(false);
      return;
    }
    try {
      const res = await fetch(`${API_BASE}/api/auth/secondary-email/verify`, {
        method: "POST",
        headers: { "Content-Type": "application/json", ...bearerHeaders(token) },
        body: JSON.stringify({ email: secondaryForm.email, code: secondaryForm.code })
      });
      const data = await res.json();
      if (!res.ok) {
        if (res.status === 403) {
          clearTokenAndUser();
          setSecondaryError(formatAuthBanMessage(data));
        } else {
          throw new Error(data.error || "验证失败");
        }
        return;
      }
      if (data.user) setUser(data.user);
      setSecondaryMessage("辅助邮箱验证成功");
      setSecondarySent(false);
      setSecondaryForm({ email: "", code: "" });
      setSecondaryEditorOpen(false);
    } catch (err) {
      setSecondaryError(err.message);
    } finally {
      setSecondaryLoading(false);
    }
  };

  const handleProfileChange = (field, value) => {
    setProfileForm((prev) => ({ ...prev, [field]: value }));
  };

  const handleProfileSave = async (event) => {
    event.preventDefault();
    setProfileLoading(true);
    setProfileError("");
    setProfileMessage("");
    const token = localStorage.getItem("sproutgate_token");
    if (!token) { setProfileError("请先登录"); setProfileLoading(false); return; }
    const payload = {
      username: profileForm.username,
      phone: profileForm.phone,
      avatarUrl: profileForm.avatarUrl,
      websiteUrl: profileForm.websiteUrl,
      bio: profileForm.bio
    };
    if (profileForm.password) payload.password = profileForm.password;
    try {
      const res = await fetch(`${API_BASE}/api/auth/profile`, {
        method: "PUT",
        headers: { "Content-Type": "application/json", ...bearerHeaders(token) },
        body: JSON.stringify(payload)
      });
      const data = await res.json();
      if (!res.ok) {
        if (res.status === 403) {
          clearTokenAndUser();
          setProfileError(formatAuthBanMessage(data));
        } else {
          throw new Error(data.error || "保存失败");
        }
        return;
      }
      setUser(data.user);
      setProfileMessage("保存成功");
      setProfileForm((prev) => ({ ...prev, password: "" }));
      setProfileEditorOpen(false);
      setProfileEditorFocus("");
    } catch (err) {
      setProfileError(err.message);
    } finally {
      setProfileLoading(false);
    }
  };

  const openProfileEditor = (field = "") => {
    setProfileError("");
    setProfileMessage("");
    setProfileEditorFocus(field);
    setProfileEditorOpen(true);
  };

  const openSecondaryEditor = () => {
    setSecondaryError("");
    setSecondaryMessage("");
    setSecondarySent(false);
    setSecondaryForm({ email: "", code: "" });
    setSecondaryEditorOpen(true);
  };

  const closeProfileEditor = () => {
    setProfileEditorOpen(false);
    setProfileEditorFocus("");
  };

  const closeSecondaryEditor = () => {
    setSecondaryEditorOpen(false);
    setSecondarySent(false);
    setSecondaryForm({ email: "", code: "" });
    setSecondaryError("");
    setSecondaryMessage("");
  };

  const profileFocusLabels = {
    phone: "手机号",
    avatarUrl: "头像",
    websiteUrl: "个人主页",
    bio: "简介",
    username: "用户名"
  };
  const profileModalTitle = profileEditorFocus && profileFocusLabels[profileEditorFocus]
    ? `修改${profileFocusLabels[profileEditorFocus]}`
    : "修改资料";

  const handleCheckIn = async () => {
    const token = localStorage.getItem("sproutgate_token");
    if (!token) { setCheckInError("请先登录"); return; }
    setCheckInLoading(true);
    setCheckInError("");
    setCheckInMessage("");
    try {
      const res = await fetch(`${API_BASE}/api/auth/check-in`, {
        method: "POST",
        headers: bearerHeaders(token)
      });
      const data = await res.json();
      if (!res.ok) {
        if (res.status === 403) {
          clearTokenAndUser();
          setCheckInError(formatAuthBanMessage(data));
        } else {
          throw new Error(data.error || "签到失败");
        }
        return;
      }
      if (data.user) setUser(data.user);
      const checkIn = data.checkIn || {};
      setCheckInReward(Number(checkIn.rewardCoins) || 1);
      setCheckInToday(Boolean(checkIn.checkedInToday));
      setCheckInMessage(
        data.message || (data.alreadyCheckedIn ? "今日已签到" : `签到成功，获得 ${data.awardedCoins ?? data.rewardCoins ?? 0} 萌芽币`)
      );
    } catch (err) {
      setCheckInError(err.message);
    } finally {
      setCheckInLoading(false);
    }
  };

  return (
    <section className="panel">
      <UserPortalAuthSection
        isAuthFlow={isAuthFlow}
        user={user}
        onPreviewImage={onPreviewImage}
        handleContinueAuth={handleContinueAuth}
        handleSwitchAuthAccount={handleSwitchAuthAccount}
        mode={mode}
        setMode={setMode}
        account={account}
        setAccount={setAccount}
        password={password}
        setPassword={setPassword}
        loading={loading}
        error={error}
        setError={setError}
        handleLogin={handleLogin}
        registerForm={registerForm}
        handleRegisterChange={handleRegisterChange}
        registerSent={registerSent}
        registerExpiresAt={registerExpiresAt}
        registerLoading={registerLoading}
        registerError={registerError}
        registerMessage={registerMessage}
        handleSendCode={handleSendCode}
        handleVerifyRegister={handleVerifyRegister}
        setRegisterError={setRegisterError}
        setRegisterMessage={setRegisterMessage}
        registrationRequireInvite={registrationRequireInvite}
        resetRegisterFlow={resetRegisterFlow}
        resetForm={resetForm}
        handleResetChange={handleResetChange}
        resetSent={resetSent}
        resetExpiresAt={resetExpiresAt}
        resetLoading={resetLoading}
        resetError={resetError}
        resetMessage={resetMessage}
        handleSendReset={handleSendReset}
        handleResetPassword={handleResetPassword}
        setResetError={setResetError}
        setResetMessage={setResetMessage}
      />
      {user && (
        <UserPortalProfileSection
          user={user}
          onPreviewImage={onPreviewImage}
          handleLogout={handleLogout}
          openProfileEditor={openProfileEditor}
          openSecondaryEditor={openSecondaryEditor}
          profileEditorOpen={profileEditorOpen}
          closeProfileEditor={closeProfileEditor}
          handleProfileSave={handleProfileSave}
          profileForm={profileForm}
          handleProfileChange={handleProfileChange}
          profileLoading={profileLoading}
          profileError={profileError}
          profileMessage={profileMessage}
          profileModalTitle={profileModalTitle}
          secondaryEditorOpen={secondaryEditorOpen}
          closeSecondaryEditor={closeSecondaryEditor}
          handleSendSecondary={handleSendSecondary}
          handleVerifySecondary={handleVerifySecondary}
          secondaryForm={secondaryForm}
          handleSecondaryChange={handleSecondaryChange}
          secondarySent={secondarySent}
          secondaryLoading={secondaryLoading}
          secondaryError={secondaryError}
          secondaryMessage={secondaryMessage}
          secondaryExpiresAt={secondaryExpiresAt}
          checkInReward={checkInReward}
          checkInToday={checkInToday}
          checkInLoading={checkInLoading}
          checkInError={checkInError}
          checkInMessage={checkInMessage}
          handleCheckIn={handleCheckIn}
        />
      )}
    </section>
  );
}
