import { useEffect, useState } from "react";
import { Button, Input, Text, View } from "@tarojs/components";
import Taro from "@tarojs/taro";
import {
  bindAccountEmail,
  bindAccountPhone,
  changeAccountPassword,
  getAccountSecurityStatus,
  sendAccountPhoneCode
} from "../../api/me";
import { useAuthGuard } from "../../hooks/useAuthGuard";
import "./index.scss";

type SecurityStatus = {
  phoneBound?: boolean;
  phone?: string;
  phoneMasked?: string;
  emailBound?: boolean;
  email?: string;
  emailMasked?: string;
  passwordSet?: boolean;
  lastLoginAt?: string;
  mfaReady?: boolean;
};

const phonePattern = /^1\d{10}$/;
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

export default function AccountSecurityPage() {
  useAuthGuard();

  const [status, setStatus] = useState<SecurityStatus | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [message, setMessage] = useState("");
  const [error, setError] = useState("");
  const [phoneCountdown, setPhoneCountdown] = useState(0);
  const [form, setForm] = useState({
    phone: "",
    phoneCode: "",
    email: "",
    oldPassword: "",
    newPassword: "",
    confirmPassword: ""
  });

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

  useEffect(() => {
    if (phoneCountdown <= 0) return undefined;
    const timer = setInterval(() => {
      setPhoneCountdown((value) => Math.max(0, value - 1));
    }, 1000);
    return () => clearInterval(timer);
  }, [phoneCountdown]);

  const setField = (key: string, value: string) => {
    setForm((prev) => ({ ...prev, [key]: value }));
  };

  async function load() {
    setLoading(true);
    setError("");
    try {
      const data = await getAccountSecurityStatus();
      setStatus(data || {});
      setForm((prev) => ({ ...prev, email: data?.email || "" }));
    } catch (e: any) {
      setError(e?.message || "账号安全信息加载失败");
    } finally {
      setLoading(false);
    }
  }

  async function run(action: () => Promise<any>, success: string) {
    if (saving) return null;
    setSaving(true);
    setMessage("");
    setError("");
    try {
      const result = await action();
      if (result && typeof result === "object" && "phoneBound" in result) {
        setStatus(result);
      }
      const hint = result?.debugCode ? `${success}，验证码：${result.debugCode}` : result?.message || success;
      setMessage(hint);
      Taro.showToast({ title: success, icon: "none" });
      return result;
    } catch (e: any) {
      setError(e?.message || "操作失败，请稍后再试");
      return null;
    } finally {
      setSaving(false);
    }
  }

  async function sendPhoneCode() {
    const phone = form.phone.trim();
    if (!phonePattern.test(phone)) {
      setError("请输入正确手机号");
      return;
    }
    const result = await run(() => sendAccountPhoneCode(phone), "验证码已发送");
    if (result) setPhoneCountdown(60);
  }

  async function bindPhone() {
    const phone = form.phone.trim();
    const code = form.phoneCode.trim();
    if (!phonePattern.test(phone) || !code) {
      setError("请输入手机号和验证码");
      return;
    }
    const result = await run(() => bindAccountPhone(phone, code), "手机号已更新");
    if (result) {
      setForm((prev) => ({ ...prev, phone: "", phoneCode: "" }));
    }
  }

  async function bindEmail() {
    const email = form.email.trim();
    if (!emailPattern.test(email)) {
      setError("请输入正确邮箱地址");
      return;
    }
    await run(() => bindAccountEmail(email), "邮箱已更新");
  }

  async function changePassword() {
    const oldPassword = form.oldPassword;
    const newPassword = form.newPassword;
    if (status?.passwordSet && !oldPassword) {
      setError("请输入当前密码");
      return;
    }
    if (newPassword.length < 8) {
      setError("新密码至少 8 位");
      return;
    }
    if (!/[a-zA-Z]/.test(newPassword) || !/\d/.test(newPassword)) {
      setError("新密码需同时包含字母和数字");
      return;
    }
    if (newPassword !== form.confirmPassword) {
      setError("两次输入的新密码不一致");
      return;
    }
    const result = await run(
      () => changeAccountPassword(oldPassword, newPassword),
      status?.passwordSet ? "密码已修改" : "密码已设置"
    );
    if (result) {
      setForm((prev) => ({ ...prev, oldPassword: "", newPassword: "", confirmPassword: "" }));
    }
  }

  const phoneText = status?.phone || status?.phoneMasked || "未绑定";
  const emailText = status?.email || status?.emailMasked || "未绑定";

  return (
    <View className="page-shell account-security-page">
      <View className="account-security-page__body">
        <View className="account-security-header">
          <Text className="account-security-header__title">账号安全</Text>
          <Text className="account-security-header__desc">管理手机号、邮箱、登录密码和多因素登录状态。</Text>
        </View>

        {loading ? <Text className="account-security-state">加载中...</Text> : null}
        {!loading && error && !status ? <Text className="account-security-state error">{error}</Text> : null}

        {status ? (
          <>
            <View className="account-security-metrics">
              <Metric label="安全状态" value={status.mfaReady ? "已完成" : "待补全"} ready={!!status.mfaReady} />
              <Metric label="手机号" value={status.phoneBound ? phoneText : "未绑定"} ready={!!status.phoneBound} />
              <Metric label="邮箱" value={status.emailBound ? emailText : "未绑定"} ready={!!status.emailBound} />
              <Metric label="密码" value={status.passwordSet ? "已设置" : "未设置"} ready={!!status.passwordSet} />
            </View>

            {message || error ? (
              <View className={error ? "account-security-alert error" : "account-security-alert"}>
                <Text>{error || message}</Text>
              </View>
            ) : null}

            <SecurityPanel title="手机号" desc="用于验证码登录、账号找回和重要通知。">
              <Input className="account-security-input" value={form.phone} type="number" maxlength={11} placeholder="请输入新手机号" onInput={(e) => setField("phone", e.detail.value)} />
              <View className="account-security-code-row">
                <Input className="account-security-input" value={form.phoneCode} type="number" maxlength={6} placeholder="短信验证码" onInput={(e) => setField("phoneCode", e.detail.value)} />
                <Button className="account-security-code-btn" disabled={saving || phoneCountdown > 0} onClick={() => void sendPhoneCode()}>
                  {phoneCountdown > 0 ? `${phoneCountdown}s` : "获取验证码"}
                </Button>
              </View>
              <Button className="account-security-submit" type="primary" loading={saving} disabled={saving} onClick={() => void bindPhone()}>绑定手机号</Button>
            </SecurityPanel>

            <SecurityPanel title="邮箱" desc="用于账号通知和合规联系信息。">
              <Input className="account-security-input" value={form.email} placeholder="请输入邮箱地址" onInput={(e) => setField("email", e.detail.value)} />
              <Button className="account-security-submit" type="primary" loading={saving} disabled={saving} onClick={() => void bindEmail()}>绑定邮箱</Button>
            </SecurityPanel>

            <SecurityPanel title={status.passwordSet ? "修改密码" : "设置密码"} desc="密码至少 8 位，并同时包含字母和数字。">
              {status.passwordSet ? (
                <Input className="account-security-input" value={form.oldPassword} password placeholder="当前密码" onInput={(e) => setField("oldPassword", e.detail.value)} />
              ) : null}
              <Input className="account-security-input" value={form.newPassword} password placeholder="新密码" onInput={(e) => setField("newPassword", e.detail.value)} />
              <Input className="account-security-input" value={form.confirmPassword} password placeholder="确认新密码" onInput={(e) => setField("confirmPassword", e.detail.value)} />
              <Button className="account-security-submit" type="primary" loading={saving} disabled={saving} onClick={() => void changePassword()}>{status.passwordSet ? "修改密码" : "设置密码"}</Button>
            </SecurityPanel>

            <View className="account-security-panel">
              <Text className="account-security-panel__title">最近登录</Text>
              <Text className="account-security-panel__desc">最近登录时间：{status.lastLoginAt || "暂无记录"}。如发现异常，请先修改密码并联系管理员核查账号状态。</Text>
            </View>
          </>
        ) : null}
      </View>
    </View>
  );
}

function Metric({ label, value, ready }: { label: string; value: string; ready: boolean }) {
  return (
    <View className={ready ? "account-security-metric" : "account-security-metric warning"}>
      <Text className="account-security-metric__label">{label}</Text>
      <Text className="account-security-metric__value">{value}</Text>
    </View>
  );
}

function SecurityPanel({ title, desc, children }: { title: string; desc: string; children: React.ReactNode }) {
  return (
    <View className="account-security-panel">
      <Text className="account-security-panel__title">{title}</Text>
      <Text className="account-security-panel__desc">{desc}</Text>
      <View className="account-security-form">{children}</View>
    </View>
  );
}
