import React, { useEffect, useState } from 'react';
import axios from 'axios';
import { useUser } from '../../context/UserContext';
import { useLocation } from 'wouter';
import toast from 'react-hot-toast';
import { confirmAlert } from 'react-confirm-alert';
import 'react-confirm-alert/src/react-confirm-alert.css';

const DEFAULT_AVATAR_URL = `${process.env.PUBLIC_URL}/default-avatar.png`;

const UserProfileBase = ({ onLoadExperienceInfo }) => {
  const { user, loading, logout ,saveUser} = useUser();
  const [userProfile, setUserProfile] = useState(null);
  const [error, setError] = useState(null);

  const [showPwdModal, setShowPwdModal] = useState(false);
  const [oldPassword, setOldPassword] = useState('');
  const [newPassword, setNewPassword] = useState('');
  const [confirmPassword, setConfirmPassword] = useState('');

  const [, setLocation] = useLocation();

  useEffect(() => {
    if (loading) return;
    if (!user || !user.userId) {
      setError('未登录或用户信息缺失');
      setUserProfile(null);
      return;
    }

    const fetchUserProfile = async () => {
      try {
        setError(null);
        const { data: raw } = await axios.get(`/echo/user/${user.userId}/getProfile`);
        if (!raw) {
          setError('用户数据为空');
          setUserProfile(null);
          return;
        }

        const profile = {
          avatarUrl: raw.avatarUrl
            ? `${process.env.REACT_APP_AVATAR_BASE_URL}${raw.avatarUrl}`
            : DEFAULT_AVATAR_URL,
          nickname: raw.username || '未知用户',
          email: raw.email || '未填写',
          gender: raw.gender || '保密',
          bio: raw.description || '无',
          interests: raw.hobbies ? raw.hobbies.split(',') : [],
          level: raw.level || '未知',
          experience: raw.experience ?? 0,
          uploadAmount: raw.uploadCount ?? 0,
          downloadAmount: raw.downloadCount ?? 0,
          shareRate: raw.shareRate ?? 0,
          joinedDate: raw.registrationTime,
        };

        setUserProfile(profile);
        if (onLoadExperienceInfo) onLoadExperienceInfo(user.userId);
      } catch (err) {
        setError(err.response?.status === 404 ? '用户不存在' : '请求失败，请稍后再试');
        setUserProfile(null);
      }
    };

    fetchUserProfile();
  }, [user, loading, onLoadExperienceInfo]);

const handleAvatarUpload = async (e) => {
  const file = e.target.files[0];
  if (!file) return;

  const formData = new FormData();
  formData.append('file', file);

  try {
    const { data } = await axios.post(
      `/echo/user/${user.userId}/uploadAvatar`,
      formData,
      { headers: { 'Content-Type': 'multipart/form-data' } }
    );

    if (data?.avatarUrl) {
      // 加时间戳避免缓存
      const newAvatarUrl = `${process.env.REACT_APP_AVATAR_BASE_URL}${data.avatarUrl}?t=${Date.now()}`;

      setUserProfile((prev) => ({
        ...prev,
        avatarUrl: newAvatarUrl,
      }));

      saveUser({
        ...user,
        avatarUrl: newAvatarUrl,
      });

      toast.success('头像上传成功');
    } else {
      toast.success('头像上传成功，但未返回新头像地址');
    }
  } catch (err) {
    console.error('上传失败:', err);
    toast.error('头像上传失败，请重试');
  }
};


  const handleLogout = () => {
    logout();
    setLocation('/auth');
  };

  const confirmPasswordChange = () => {
    confirmAlert({
      title: '确认修改密码',
      message: '确定要修改密码吗？修改成功后将自动登出。',
      buttons: [
        {
          label: '确认',
          onClick: handleChangePassword,
        },
        {
          label: '取消',
        },
      ],
    });
  };

  const handleChangePassword = async () => {
    if (!oldPassword || !newPassword || !confirmPassword) {
      toast.error('请填写所有字段');
      return;
    }
    if (newPassword !== confirmPassword) {
      toast.error('两次输入的新密码不一致');
      return;
    }

    try {
      await axios.post('/echo/user/password', {
        user_id: user.userId,
        old_password: oldPassword,
        new_password: newPassword,
        confirm_password: confirmPassword,
      });

      toast.success('密码修改成功，请重新登录');
      logout();
      setTimeout(() => {
        window.location.reload();
      }, 1500);
    } catch (err) {
      toast.error(err.response?.data?.message || '密码修改失败，请检查原密码是否正确');
    }
  };

  if (loading) return <p>正在加载用户信息...</p>;
  if (error) return <p className="error">{error}</p>;
  if (!userProfile) return null;

  const {
    avatarUrl,
    nickname,
    email,
    gender,
    bio,
    interests,
    level,
    experience,
    uploadAmount,
    downloadAmount,
    shareRate,
    joinedDate,
  } = userProfile;

  return (
    <div className="common-card">
      <div className="right-content">
        <div className="profile-header">
          <div className="avatar-wrapper">
            <img src={avatarUrl} alt={nickname} className="avatar" />
            <label htmlFor="avatar-upload" className="avatar-upload-label">
              上传头像
            </label>
            <input
              type="file"
              id="avatar-upload"
              accept="image/*"
              style={{ display: 'none' }}
              onChange={handleAvatarUpload}
            />
          </div>
          <h1>{nickname}</h1>
        </div>

        <div className="profile-details">
          <p><strong>邮箱：</strong>{email}</p>
          <p><strong>性别：</strong>{gender}</p>
          <p><strong>个人简介：</strong>{bio}</p>
          <p><strong>兴趣：</strong>{interests.length > 0 ? interests.join(', ') : '无'}</p>
          <p><strong>上传量：</strong>{uploadAmount}</p>
          <p><strong>下载量：</strong>{downloadAmount}</p>
          <p><strong>分享率：</strong>{(shareRate * 100).toFixed(2)}%</p>
          <p><strong>加入时间：</strong>{new Date(joinedDate).toLocaleDateString()}</p>

          <div className="profile-actions">
            <button onClick={() => setShowPwdModal(true)}>修改密码</button>
            <button onClick={handleLogout}>退出登录</button>
          </div>

          {showPwdModal && (
            <div className="user-modal">
              <div className="user-modal-content">
                <h3>修改密码</h3>
                <input
                  type="password"
                  placeholder="原密码"
                  value={oldPassword}
                  onChange={(e) => setOldPassword(e.target.value)}
                />
                <input
                  type="password"
                  placeholder="新密码"
                  value={newPassword}
                  onChange={(e) => setNewPassword(e.target.value)}
                />
                <input
                  type="password"
                  placeholder="确认新密码"
                  value={confirmPassword}
                  onChange={(e) => setConfirmPassword(e.target.value)}
                />
                <div className="user-modal-buttons">
                  <button onClick={confirmPasswordChange}>确认修改</button>
                  <button onClick={() => setShowPwdModal(false)}>取消</button>
                </div>
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

export default UserProfileBase;
