/* rx-auth.jsx — 인증 + 권한 관리
   requires: firebase (전역), window.isUnlocked (rx-core.jsx)
   exports:  AuthContext, AuthProvider, getVisibleDepts, ProfileDrawer */

const AuthContext = React.createContext(null);

function resolveEffectivePlan(dbPlan, planExpiry) {
  if (!dbPlan) return 'free';
  if ((dbPlan === 'vip' || dbPlan === 'trial') && planExpiry) {
    const expiryTime = planExpiry.seconds ? planExpiry.seconds * 1000 : new Date(planExpiry).getTime();
    if (Date.now() > expiryTime) {
      return 'free';
    }
  }
  return dbPlan;
}

function AuthProvider({ children }) {
  const [currentUser, setCurrentUser] = React.useState(null);
  const [plan, setPlan] = React.useState('free');
  const [planExpiry, setPlanExpiry] = React.useState(null);
  const [trialUsed, setTrialUsed] = React.useState(false);
  const [authLoading, setAuthLoading] = React.useState(true);

  React.useEffect(() => {
    let unsubscribeFirestore = null;

    const unsubscribeAuth = firebase.auth().onAuthStateChanged(async (user) => {
      if (unsubscribeFirestore) {
        unsubscribeFirestore();
        unsubscribeFirestore = null;
      }

      if (user) {
        setCurrentUser(user);
        const db = firebase.firestore();
        const userRef = db.collection('users').doc(user.uid);

        try {
          const doc = await userRef.get();
          if (!doc.exists) {
            await userRef.set({
              email: user.email,
              displayName: user.displayName || '',
              plan: 'free',
              planExpiry: null,
              trialUsed: false,
              createdAt: firebase.firestore.FieldValue.serverTimestamp()
            });
          }
        } catch (e) {
          console.error('사용자 문서 생성/조회 실패:', e);
        }

        unsubscribeFirestore = userRef.onSnapshot((snapshot) => {
          if (snapshot.exists) {
            const data = snapshot.data();
            const dbPlan = data.role === 'admin' || data.plan === 'admin' ? 'admin' : (data.plan || 'free');
            const resolved = resolveEffectivePlan(dbPlan, data.planExpiry);
            setPlan(resolved);
            setPlanExpiry(data.planExpiry);
            setTrialUsed(data.trialUsed || false);
          } else {
            setPlan('free');
            setPlanExpiry(null);
            setTrialUsed(false);
          }
          setAuthLoading(false);
        }, (err) => {
          console.error('Firestore snapshot 에러:', err);
          setAuthLoading(false);
        });
      } else {
        setCurrentUser(null);
        setPlan('free');
        setPlanExpiry(null);
        setTrialUsed(false);
        setAuthLoading(false);
      }
    });

    return () => {
      unsubscribeAuth();
      if (unsubscribeFirestore) unsubscribeFirestore();
    };
  }, []);

  const startTrial = async () => {
    alert('무료 체험 시작은 서버 검증 기능 연결 후 제공됩니다.');
  };

  return (
    <AuthContext.Provider value={{ currentUser, plan, planExpiry, trialUsed, authLoading, startTrial }}>
      {children}
    </AuthContext.Provider>
  );
}

function getVisibleDepts(plan) {
  const unlocked = window.isUnlocked(plan);
  return [
    { id: 'all', label: '통합', enabled: true, locked: false },
    { id: 'CV', label: '순환기', enabled: true, locked: false },
    { id: 'PM', label: '호흡기', enabled: unlocked, locked: !unlocked },
    { id: 'ED', label: '내분비', enabled: unlocked, locked: !unlocked },
  ];
}

function AdminVipPanel() {
  const [targetEmail, setTargetEmail] = React.useState('');
  const [duration, setDuration] = React.useState('30');
  const [customDuration, setCustomDuration] = React.useState('');
  const [memo, setMemo] = React.useState('');
  const [actionLoading, setActionLoading] = React.useState(false);
  const [grants, setGrants] = React.useState([]);

  const { plan } = React.useContext(AuthContext);

  React.useEffect(() => {
    if (plan !== 'admin') return;
    const db = firebase.firestore();
    const unsub = db.collection('vip_grants')
      .orderBy('createdAt', 'desc').limit(20)
      .onSnapshot(snap => {
        setGrants(snap.docs.map(d => ({ id: d.id, ...d.data() })));
      }, err => {
        console.error('vip_grants 구독 에러:', err);
      });
    return unsub;
  }, [plan]);

  const formatTime = (ts) => {
    if (!ts) return '무제한';
    const date = ts.seconds ? new Date(ts.seconds * 1000) : new Date(ts);
    return date.toLocaleDateString() + ' ' + date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
  };

  const handleGrantVip = async () => {
    const email = targetEmail.trim();
    if (!email) { alert('이메일을 입력해주세요.'); return; }

    let expiry = null;
    if (duration !== 'unlimited') {
      const days = duration === 'custom' ? parseInt(customDuration, 10) : parseInt(duration, 10);
      if (isNaN(days) || days <= 0) { alert('올바른 일수를 입력해주세요.'); return; }
      const expiryDate = new Date();
      expiryDate.setDate(expiryDate.getDate() + days);
      expiry = firebase.firestore.Timestamp.fromDate(expiryDate);
    }

    setActionLoading(true);
    try {
      const db = firebase.firestore();
      const userQuery = await db.collection('users').where('email', '==', email).limit(1).get();
      if (userQuery.empty) {
        alert('가입되지 않은 이메일입니다. 사용자가 최소 1회 로그인해야 합니다.');
        return;
      }
      const uid = userQuery.docs[0].id;

      const batch = db.batch();
      batch.update(db.collection('users').doc(uid), { plan: 'vip', planExpiry: expiry });
      batch.set(db.collection('vip_grants').doc(), {
        targetEmail: email,
        targetUid: uid,
        grantedByUid: firebase.auth().currentUser.uid,
        expiry: expiry,
        memo: memo.trim(),
        createdAt: firebase.firestore.FieldValue.serverTimestamp()
      });
      await batch.commit();

      alert(`[${email}] 님에게 VIP를 부여했습니다.`);
      setTargetEmail('');
      setMemo('');
      setDuration('30');
      setCustomDuration('');
    } catch (e) {
      console.error('VIP 부여 오류:', e);
      alert('오류: ' + e.message);
    } finally {
      setActionLoading(false);
    }
  };

  const inputStyle = {
    flex: 1, minWidth: 0, padding: '6px 8px', borderRadius: 6,
    border: '1px solid rgba(175,128,0,0.3)', font: 'inherit', fontSize: 10.5,
    background: '#fff', outline: 'none', boxSizing: 'border-box'
  };

  return (
    <div style={{
      marginTop: 8, padding: '12px', borderRadius: 10,
      background: 'rgba(175,128,0,0.06)', border: '1.5px solid rgba(175,128,0,0.2)',
      boxSizing: 'border-box'
    }}>
      <div style={{ fontSize: 11.5, fontWeight: 800, color: '#af8000', marginBottom: 8 }}>
        👑 VIP 권한 부여 (수동)
      </div>
      <div style={{ marginBottom: 6 }}>
        <input
          type="email" placeholder="대상 이메일 입력"
          value={targetEmail} onChange={e => setTargetEmail(e.target.value)}
          disabled={actionLoading} style={{ ...inputStyle, width: '100%' }}
        />
      </div>
      <div style={{ display: 'flex', gap: 6, marginBottom: 6 }}>
        <select
          value={duration} onChange={e => setDuration(e.target.value)}
          disabled={actionLoading}
          style={{ ...inputStyle, flex: 'none', width: 'auto', cursor: 'pointer' }}
        >
          <option value="7">7일</option>
          <option value="30">30일</option>
          <option value="90">90일</option>
          <option value="custom">직접 입력</option>
          <option value="unlimited">무제한</option>
        </select>
        {duration === 'custom' && (
          <input
            type="number" placeholder="일수 입력" min="1"
            value={customDuration} onChange={e => setCustomDuration(e.target.value)}
            disabled={actionLoading} style={{ ...inputStyle, width: 80, flex: 'none' }}
          />
        )}
      </div>
      <div style={{ marginBottom: 6 }}>
        <input
          type="text" placeholder="메모 (선택)"
          value={memo} onChange={e => setMemo(e.target.value)}
          disabled={actionLoading} style={{ ...inputStyle, width: '100%' }}
        />
      </div>
      <button
        onClick={handleGrantVip} disabled={actionLoading}
        style={{
          width: '100%', padding: '7px 0', borderRadius: 6, border: 'none',
          background: '#af8000', color: '#fff', font: 'inherit', fontSize: 10.5,
          fontWeight: 800, cursor: actionLoading ? 'default' : 'pointer'
        }}
      >
        {actionLoading ? '처리 중…' : 'VIP 부여'}
      </button>
      {grants.length > 0 && (
        <div style={{ marginTop: 10 }}>
          <div style={{ fontSize: 10.5, fontWeight: 700, color: '#af8000', marginBottom: 4 }}>최근 부여 내역</div>
          <div style={{ overflowX: 'auto' }}>
            <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 10 }}>
              <thead>
                <tr style={{ background: 'rgba(175,128,0,0.1)' }}>
                  <th style={{ padding: '4px 6px', textAlign: 'left', fontWeight: 700 }}>이메일</th>
                  <th style={{ padding: '4px 6px', textAlign: 'left', fontWeight: 700 }}>만료일</th>
                  <th style={{ padding: '4px 6px', textAlign: 'left', fontWeight: 700 }}>메모</th>
                  <th style={{ padding: '4px 6px', textAlign: 'left', fontWeight: 700 }}>부여일</th>
                </tr>
              </thead>
              <tbody>
                {grants.map(g => {
                  const isExpired = g.expiry && (g.expiry.seconds ? g.expiry.seconds * 1000 : new Date(g.expiry).getTime()) < Date.now();
                  return (
                    <tr key={g.id} style={{ borderTop: '1px solid rgba(175,128,0,0.1)', opacity: isExpired ? 0.5 : 1 }}>
                      <td style={{ padding: '4px 6px', color: isExpired ? '#bbb' : 'inherit' }}>{g.targetEmail}</td>
                      <td style={{ padding: '4px 6px', whiteSpace: 'nowrap', color: isExpired ? '#f00a' : 'inherit' }}>{formatTime(g.expiry)}{isExpired ? ' (만료)' : ''}</td>
                      <td style={{ padding: '4px 6px', color: '#888' }}>{g.memo || '-'}</td>
                      <td style={{ padding: '4px 6px', whiteSpace: 'nowrap' }}>{formatTime(g.createdAt)}</td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </div>
      )}
    </div>
  );
}

function ProfileDrawer({ open, onClose }) {
  const { currentUser, plan, planExpiry, trialUsed, startTrial, authLoading } = React.useContext(AuthContext || {});
  const [loading, setLoading] = React.useState(false);

  const handleGoogleLogin = async () => {
    setLoading(true);
    try {
      const provider = new firebase.auth.GoogleAuthProvider();
      await firebase.auth().signInWithPopup(provider);
    } catch (e) {
      console.error('Google 로그인 실패:', e);
    } finally {
      setLoading(false);
    }
  };

  const handleLogout = async () => {
    try {
      await firebase.auth().signOut();
    } catch (e) {
      console.error('로그아웃 실패:', e);
    }
  };

  return (
    <>
      {open && (
        <div onClick={onClose} style={{
          position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.22)',
          zIndex: 80, backdropFilter: 'blur(1px)',
        }} />
      )}
      <div style={{
        position: 'absolute', top: 0, right: 0, bottom: 0, zIndex: 81,
        width: '33.33%',
        backdropFilter: 'blur(24px) saturate(160%)',
        WebkitBackdropFilter: 'blur(24px) saturate(160%)',
        background: 'rgba(255,255,255,0.82)',
        borderLeft: '0.5px solid rgba(255,255,255,0.6)',
        boxShadow: '-6px 0 24px rgba(20,40,34,0.14)',
        transform: open ? 'translateX(0)' : 'translateX(100%)',
        transition: 'transform .26s cubic-bezier(.4,0,.2,1)',
        display: 'flex', flexDirection: 'column',
      }}>
        <div style={{ padding: '16px 12px 10px', borderBottom: '1px solid rgba(0,0,0,0.08)', flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
          <span style={{ fontSize: 12, fontWeight: 800, color: RX.ink }}>계정</span>
          <button onClick={onClose} style={{ background: 'none', border: 'none', cursor: 'pointer', color: RX.faint, fontSize: 16, lineHeight: 1, padding: '0 2px' }}>×</button>
        </div>
        <div style={{ flex: 1, overflowY: 'auto', padding: '14px 10px' }}>
          {authLoading ? (
            <div style={{ display: 'flex', justifyContent: 'center', padding: '20px 0' }}>
              <svg width="20" height="20" viewBox="0 0 24 24" fill="none" style={{ animation: 'drawerSpin 1s linear infinite' }}>
                <circle cx="12" cy="12" r="9" stroke={RX.line} strokeWidth="2" />
                <path d="M12 3a9 9 0 019 9" stroke={RX.teal} strokeWidth="2.2" strokeLinecap="round" />
              </svg>
            </div>
          ) : !currentUser ? (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
              <p style={{ margin: 0, fontSize: 10.5, color: RX.sub, lineHeight: 1.65 }}>
                로그인하면 즐겨찾기·메모 등 개인화 기능을 이용할 수 있습니다.
              </p>
              <button onClick={handleGoogleLogin} disabled={loading} style={{
                display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 7,
                padding: '9px 8px', borderRadius: 9,
                border: `1.5px solid ${RX.line}`, background: 'rgba(255,255,255,0.9)',
                cursor: loading ? 'default' : 'pointer', font: 'inherit',
                fontSize: 11, fontWeight: 700, color: '#3c4043',
                boxShadow: '0 1px 3px rgba(0,0,0,0.08)',
                opacity: loading ? 0.7 : 1,
              }}>
                {loading ? (
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" style={{ animation: 'drawerSpin 1s linear infinite' }}>
                    <circle cx="12" cy="12" r="9" stroke={RX.line} strokeWidth="2" />
                    <path d="M12 3a9 9 0 019 9" stroke={RX.teal} strokeWidth="2.2" strokeLinecap="round" />
                  </svg>
                ) : (
                  <svg width="14" height="14" viewBox="0 0 18 18">
                    <path d="M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.717v2.258h2.908c1.702-1.567 2.684-3.874 2.684-6.615z" fill="#4285F4" />
                    <path d="M9 18c2.43 0 4.467-.806 5.956-2.18l-2.908-2.259c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711H.957v2.332A8.997 8.997 0 009 18z" fill="#34A853" />
                    <path d="M3.964 10.71A5.41 5.41 0 013.682 9c0-.593.102-1.17.282-1.71V4.958H.957A8.996 8.996 0 000 9c0 1.452.348 2.827.957 4.042l3.007-2.332z" fill="#FBBC05" />
                    <path d="M9 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.463.891 11.426 0 9 0A8.997 8.997 0 00.957 4.958L3.964 7.29C4.672 5.163 6.656 3.58 9 3.58z" fill="#EA4335" />
                  </svg>
                )}
                {loading ? '로그인 중…' : 'Google 로그인'}
              </button>
              <div style={{ fontSize: 9, color: RX.faint, lineHeight: 1.5, textAlign: 'center' }}>
                로그인 시 이용약관에 동의하게 됩니다.
              </div>
            </div>
          ) : (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
              <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 7, padding: '4px 0 8px', borderBottom: '1px solid rgba(0,0,0,0.07)' }}>
                <div style={{ width: 36, height: 36, borderRadius: '50%', background: RX.teal, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                  <span style={{ fontSize: 15, fontWeight: 800, color: '#fff' }}>{(currentUser.displayName || currentUser.email)[0].toUpperCase()}</span>
                </div>
                <div style={{ textAlign: 'center' }}>
                  <div style={{ fontSize: 12, fontWeight: 800, color: RX.ink }}>{currentUser.displayName || '사용자'}</div>
                  <div style={{ fontSize: 9.5, color: RX.faint }}>{currentUser.email}</div>
                  {plan === 'admin' && (
                    <div style={{ marginTop: 6, display: 'inline-block', fontSize: 10, fontWeight: 800, color: '#fff', background: RX.rose, borderRadius: 4, padding: '2px 6px' }}>
                      관리자
                    </div>
                  )}
                </div>
              </div>
              {[{ icon: '☆', label: '즐겨찾기' }, { icon: '📝', label: '내 메모' }, { icon: '⚙️', label: '설정' }].map(item => (
                <button key={item.label} style={{
                  display: 'flex', alignItems: 'center', gap: 8, padding: '9px 10px',
                  borderRadius: 9, border: `1px solid ${RX.line}`, background: 'rgba(255,255,255,0.7)',
                  font: 'inherit', fontSize: 11.5, fontWeight: 700, color: RX.ink, cursor: 'pointer', textAlign: 'left',
                }}>
                  <span style={{ fontSize: 13 }}>{item.icon}</span>{item.label}
                </button>
              ))}
              {plan === 'admin' && <AdminVipPanel />}
              <button onClick={handleLogout} style={{
                marginTop: 2, padding: '8px', borderRadius: 8,
                border: '1px solid #fcd5d5', background: 'rgba(255,245,245,0.8)',
                font: 'inherit', fontSize: 11, fontWeight: 700, color: '#c53030', cursor: 'pointer',
              }}>로그아웃</button>
            </div>
          )}
        </div>
        <style>{`@keyframes drawerSpin{to{transform:rotate(360deg)}}`}</style>
      </div>
    </>
  );
}

Object.assign(window, { AuthContext, AuthProvider, getVisibleDepts, ProfileDrawer });
