import React, { useState, useEffect, useRef, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import './App.css';
import ProfileSection from './components/ProfileSection';
import TechStackSection from './components/TechStackSection';
import ProjectsSection from './components/ProjectsSection';
import ContactsSection from './components/ContactsSection';
import ClickParticle from './components/ClickParticle';
import { ADMIN_TOKEN_KEY, adminFetch, adminPing, getApiBase, getFaviconUrlForSite } from './api';

const RANDOM_BG_JSON = 'https://randbg.api.smyhub.com/api/random?format=json';
const AVATAR_TAP_RESET_MS = 2000;
const AVATAR_TAPS_REQUIRED = 5;

function formatVisitorGeoLine(geo) {
  if (!geo) return null;
  const parts = [
    geo.countryName || geo.country,
    geo.regionName || geo.region,
    geo.cityName || geo.city
  ].filter(Boolean);
  return parts.length ? parts.join(' · ') : null;
}

function VisitorIpLine({ ip, geo }) {
  const geoLine = formatVisitorGeoLine(geo);
  return (
    <span>
      访客 IP：{ip}
      {geoLine ? <> · {geoLine}</> : null}
    </span>
  );
}

export default function HomePage() {
  const navigate = useNavigate();
  const [data, setData] = useState({
    profile: null,
    techstack: null,
    projects: null,
    contacts: null
  });
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [backgroundImage, setBackgroundImage] = useState(null);
  const [visitorInfo, setVisitorInfo] = useState(null);
  const [visitorInfoLoading, setVisitorInfoLoading] = useState(true);
  const [tokenModalOpen, setTokenModalOpen] = useState(false);
  const [tokenInput, setTokenInput] = useState('');
  const [tokenError, setTokenError] = useState('');
  const avatarTapRef = useRef({ count: 0, lastAt: 0 });

  useEffect(() => {
    const token = sessionStorage.getItem(ADMIN_TOKEN_KEY);
    if (!token) return;
    adminFetch('/admin/ping').then((r) => {
      if (!r.ok) sessionStorage.removeItem(ADMIN_TOKEN_KEY);
    });
  }, []);

  useEffect(() => {
    const apiBaseUrl = getApiBase();
    fetch(`${apiBaseUrl}/all`)
      .then((response) => {
        if (!response.ok) throw new Error('网络响应失败');
        return response.json();
      })
      .then((d) => {
        setData(d);
        const applyFavicon = (url) => {
          let faviconTag = document.querySelector('link[rel="icon"]');
          if (!faviconTag) {
            faviconTag = document.createElement('link');
            faviconTag.rel = 'icon';
            document.head.appendChild(faviconTag);
          }
          faviconTag.href = url;
        };
        const fallbackFavicon = d.profile?.favicon || '';
        const siteUrl =
          d.profile?.site ||
          d.profile?.homepage ||
          d.contacts?.contacts?.find((c) => c.type === 'personprofile')?.link ||
          d.contacts?.contacts?.find((c) => c.link?.startsWith('https://'))?.link ||
          window.location.origin;
        const apiFaviconUrl = getFaviconUrlForSite(siteUrl);
        const img = new Image();
        img.onload = () => applyFavicon(apiFaviconUrl);
        img.onerror = () => {
          if (fallbackFavicon) applyFavicon(fallbackFavicon);
        };
        img.src = apiFaviconUrl;
        if (fallbackFavicon && !siteUrl) applyFavicon(fallbackFavicon);
        setLoading(false);
      })
      .catch((err) => {
        console.error('获取数据失败:', err);
        setError(err.message);
        setLoading(false);
      });
  }, []);

  useEffect(() => {
    const ac = new AbortController();
    fetch(RANDOM_BG_JSON, { signal: ac.signal })
      .then((r) => {
        if (!r.ok) throw new Error(`HTTP ${r.status}`);
        return r.json();
      })
      .then((j) => {
        if (j?.url) setBackgroundImage(j.url);
      })
      .catch((err) => {
        if (err?.name === 'AbortError') return;
        console.warn('随机背景加载失败:', err);
      });
    return () => ac.abort();
  }, []);

  useEffect(() => {
    const controller = new AbortController();
    setVisitorInfoLoading(true);
    fetch('https://cf-ip-geo.smyhub.com/api', {
      signal: controller.signal,
      headers: { Accept: 'application/json' },
      cache: 'no-store'
    })
      .then((res) => {
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        return res.json();
      })
      .then((payload) => {
        setVisitorInfo(payload);
        setVisitorInfoLoading(false);
      })
      .catch((err) => {
        if (err?.name === 'AbortError') return;
        console.warn('获取访客 IP/地理位置失败:', err);
        setVisitorInfo(null);
        setVisitorInfoLoading(false);
      });
    return () => controller.abort();
  }, []);

  const onAvatarAdminTap = useCallback(() => {
    const now = Date.now();
    if (now - avatarTapRef.current.lastAt > AVATAR_TAP_RESET_MS) {
      avatarTapRef.current.count = 0;
    }
    avatarTapRef.current.lastAt = now;
    avatarTapRef.current.count += 1;
    if (avatarTapRef.current.count >= AVATAR_TAPS_REQUIRED) {
      avatarTapRef.current.count = 0;
      setTokenInput('');
      setTokenError('');
      setTokenModalOpen(true);
    }
  }, []);

  const submitAdminToken = async () => {
    const t = tokenInput.trim();
    if (!t) {
      setTokenError('请输入 token');
      return;
    }
    const ok = await adminPing(t);
    if (!ok) {
      setTokenError('token 无效');
      return;
    }
    sessionStorage.setItem(ADMIN_TOKEN_KEY, t);
    setTokenModalOpen(false);
    navigate('/admin');
  };

  if (loading) {
    return (
      <div className="pwa-launch">
        <div className="pwa-launch-bg" />
        <div className="pwa-launch-content">
          <div className="pwa-launch-logo-wrap">
            <img
              src={`${process.env.PUBLIC_URL || ''}/logo192.png`}
              alt="萌芽"
              className="pwa-launch-logo"
            />
            <div className="pwa-launch-ring pwa-launch-ring-1" />
            <div className="pwa-launch-ring pwa-launch-ring-2" />
            <div className="pwa-launch-ring pwa-launch-ring-3" />
          </div>
          <h1 className="pwa-launch-title">萌芽主页</h1>
          <p className="pwa-launch-subtitle">加载中</p>
          <div className="pwa-launch-dots">
            <span className="pwa-launch-dot" />
            <span className="pwa-launch-dot" />
            <span className="pwa-launch-dot" />
          </div>
        </div>
      </div>
    );
  }

  if (error) {
    return (
      <div className="error-container">
        <h2>加载失败</h2>
        <p>{error}</p>
        <p className="error-hint">请确保后端服务已启动（运行 python app.py）</p>
      </div>
    );
  }

  return (
    <div className="App">
      {backgroundImage ? (
        <div
          className="app-background"
          style={{ backgroundImage: `url(${backgroundImage})` }}
          aria-hidden
        />
      ) : null}
      <ClickParticle />

      <div className="container">
        {data.profile && (
          <ProfileSection profile={data.profile} onAvatarAdminTap={onAvatarAdminTap} />
        )}
        {data.techstack && <TechStackSection techstack={data.techstack} />}
        {data.projects && (
          <ProjectsSection
            projects={data.projects.projects}
            techStackItems={data.techstack?.items || []}
          />
        )}
        {data.contacts && <ContactsSection contacts={data.contacts.contacts} />}
      </div>

      <footer className="footer">
        <p>
          <strong>
            {data.profile?.footer || '© 2025 萌芽个人主页. All rights reserved.'}
          </strong>
        </p>
        <div className="footer-visitor">
          {visitorInfoLoading ? (
            <span>访客信息加载中</span>
          ) : visitorInfo?.ip ? (
            <VisitorIpLine ip={visitorInfo.ip} geo={visitorInfo.geo} />
          ) : (
            <span>访客信息获取失败</span>
          )}
        </div>
      </footer>

      {tokenModalOpen ? (
        <div
          className="admin-token-backdrop"
          role="dialog"
          aria-modal="true"
          aria-label="管理入口"
          onMouseDown={(e) => {
            if (e.target === e.currentTarget) setTokenModalOpen(false);
          }}
        >
          <div className="admin-token-box">
            <p className="admin-token-title">管理验证</p>
            <input
              type="password"
              className="admin-token-input"
              placeholder="Token"
              value={tokenInput}
              onChange={(e) => setTokenInput(e.target.value)}
              onKeyDown={(e) => e.key === 'Enter' && submitAdminToken()}
              autoFocus
            />
            {tokenError ? <p className="admin-token-err">{tokenError}</p> : null}
            <div className="admin-token-actions">
              <button type="button" className="admin-token-btn secondary" onClick={() => setTokenModalOpen(false)}>
                取消
              </button>
              <button type="button" className="admin-token-btn primary" onClick={submitAdminToken}>
                进入
              </button>
            </div>
          </div>
        </div>
      ) : null}
    </div>
  );
}
