import React, { useState, useEffect } from 'react';
import axios from 'axios';

const UserLevelExperience = ({ userId }) => {
  const [experienceInfo, setExperienceInfo] = useState(null);
  const [error, setError] = useState(null);
  const [isLoading, setIsLoading] = useState(false);
  const [upgradeResult, setUpgradeResult] = useState(null);
  const [hasCheckedIn, setHasCheckedIn] = useState(false);
  const [isUpgrading, setIsUpgrading] = useState(false);
  const [lastUpgradeTime, setLastUpgradeTime] = useState(null);
  const [justUpgraded, setJustUpgraded] = useState(false); // 新增

  useEffect(() => {
    if (!userId) return;
    fetchAllLevelData();
  }, [userId]);

  useEffect(() => {
    if (
      experienceInfo &&
      experienceInfo.current_experience >= experienceInfo.next_level_experience &&
      !isUpgrading &&
      !justUpgraded &&
      (!lastUpgradeTime || Date.now() - lastUpgradeTime > 2000)
    ) {
    }
  }, [experienceInfo, isUpgrading, lastUpgradeTime, justUpgraded]);

  const fetchAllLevelData = async () => {
    try {
      setIsLoading(true);
      setError(null);

      const { data } = await axios.get('/echo/level/getExperience', {
        params: { user_id: userId },
      });

      const normalizedData = {
        ...data,
        current_level: data.current_level || data.level,
      };

      setExperienceInfo(normalizedData);

      const today = new Date().toDateString();
      const lastCheckIn = localStorage.getItem('lastCheckIn');
      setHasCheckedIn(lastCheckIn === today);
    } catch (err) {
      console.error('经验信息获取失败:', err);
      setError('获取经验信息失败');
    } finally {
      setIsLoading(false);
    }
  };

  const updateExperience = async (source, amount = 10) => {
    try {
      setIsLoading(true);
      setError(null);

      const { data } = await axios.post('/echo/level/updateExperience', {
        user_id: userId,
        experience: amount,
        source: source,
      });

      setExperienceInfo((prev) => ({
        ...prev,
        current_experience: data.current_experience,
      }));

      alert(`获得${amount}点经验值！来源：${source}`);

      if (source === 'check-in') {
        localStorage.setItem('lastCheckIn', new Date().toDateString());
        setHasCheckedIn(true);
      }
    } catch (err) {
      console.error('更新经验失败:', err);
      setError(err.response?.data?.message || '更新经验失败');
    } finally {
      setIsLoading(false);
    }
  };

  const checkUpgrade = async () => {
    if (isUpgrading) return;

    try {
      setIsLoading(true);
      setIsUpgrading(true);
      setError(null);

      const { data } = await axios.get('/echo/level/upgrade-check', {
        params: { user_id: userId },
      });

      if (data.can_upgrade) {
        if (window.confirm('您已满足升级条件，是否要升级？')) {
          await performUpgrade();
        }
      } else {
        if (data.is_max_level) {
          alert('您已达到最高等级！');
        } else {
          alert(`还不能升级，还需要${data.next_level_experience - data.current_experience}点经验值`);
        }
      }
    } catch (err) {
      console.error('检查升级失败:', err);
      setError(err.response?.data?.message || '检查升级失败');
    } finally {
      setIsLoading(false);
      setIsUpgrading(false);
    }
  };

  const performUpgrade = async () => {
    try {
      setIsUpgrading(true);
      setIsLoading(true);
      setError(null);

      const { data } = await axios.post('/echo/level/upgrades', {
        user_id: userId,
        can_upgrade: true,
      });

      console.log('升级响应数据:', data);

      if (data.status === 'success') {
        setExperienceInfo((prev) => ({ 
          // 更新就会进入useEffect,又执行了checkUpgrade,循环
          ...prev,
          current_level: data.new_level,
          current_experience: data.current_experience || 0,
          next_level_experience: data.next_level_experience || prev.next_level_experience * 2,
        }));

        setUpgradeResult(data);
        setLastUpgradeTime(Date.now());
        setJustUpgraded(true); // 标记为刚升级过
        setTimeout(() => setJustUpgraded(false), 3000); // 3 秒冷却期
        alert(`恭喜！您已升级到等级 ${data.new_level}！`);

        // 再次拉取最新经验数据，避免经验值仍然满足升级条件
        await fetchAllLevelData();
      } else {
        throw new Error(data.message || '升级失败');
      }
    } catch (err) {
      console.error('升级失败:', err);
      setError(err.message || '升级失败');
      alert(err.message || '升级失败，请稍后再试');
    } finally {
      setIsLoading(false);
      setIsUpgrading(false);
    }
  };

  if (error) return <p className="error">{error}</p>;
  if (isLoading) return <p>加载中...</p>;
  if (!experienceInfo) return <p>加载经验信息中...</p>;

  const { current_experience, next_level_experience, current_level } = experienceInfo;
  const progressPercent = Math.min(
    100,
    (current_experience / (next_level_experience || 1)) * 100
  ).toFixed(2);

  const expToNextLevel = Math.max(0, next_level_experience - current_experience);

  return (
    <div style={{ padding: '20px', marginTop: '-80px', marginLeft: '70px' }}>
      {/* <h3>等级与经验</h3> */}
      <div style={{ fontSize: '20px', marginBottom: '10px' }}><strong>当前等级：</strong>lv{current_level || '未知'}</div>
      <div style={{ fontSize: '20px', marginBottom: '10px' }}><strong>当前经验：</strong>{current_experience}</div>
      {/* <p><strong>距离下一等级还需：</strong>{expToNextLevel} 经验值</p> */}

      <div className="exp-bar-wrapper">
        <div className="exp-bar" style={{ width: `${progressPercent}%` }} />
      </div>
      <p className="exp-progress-text">{progressPercent}%</p>

      {upgradeResult && (
        <div className="upgrade-success">
          <p>恭喜！您已成功升级到等级 {upgradeResult.new_level}！</p>
        </div>
      )}

      {error && (
        <div className="upgrade-error">
          <p>{error}</p>
        </div>
      )}

      <div className="level-actions">
        {/* <button onClick={() => updateExperience('check-in', 15)} disabled={hasCheckedIn}>
          {hasCheckedIn ? '今日已签到' : '每日签到 (+15经验)'}
        </button> */}
        {/* <button onClick={() => updateExperience('task', 30)}>完成任务 (+30经验)</button> */}
        {/* <button onClick={() => updateExperience('upload', 50)}>上传种子 (+20经验)</button> */}
        {/* <button onClick={checkUpgrade} disabled={isUpgrading}>
          {isUpgrading ? '升级中...' : '检查升级'}
        </button> */}
      </div>
    </div>
  );
};

export default UserLevelExperience;

