import { useCallback, useEffect, useMemo, useState } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
import {
  addCategory,
  authCheck,
  deleteCategory,
  deleteSite,
  fetchCategories,
  fetchSiteById,
  fetchSites,
  renameCategory,
  saveSite,
} from '../api/client';
import { AdminSiteCard } from '../components/AdminSiteCard';
import { Toast } from '../components/Toast';
import { SITE_NAME } from '../config/site';
import { useServiceWorker } from '../hooks/useServiceWorker';
import type { Site } from '../types/site';
import '../styles/admin.css';

const ADMIN_SESSION_KEY = 'mengya_nav_admin_session';

export default function Admin() {
  useServiceWorker();
  const navigate = useNavigate();
  const [searchParams] = useSearchParams();

  const [authToken, setAuthToken] = useState<string | null>(null);
  const [checking, setChecking] = useState(true);

  const [categories, setCategories] = useState<string[]>([]);
  const [allSites, setAllSites] = useState<Site[]>([]);
  const [categoryFilter, setCategoryFilter] = useState('');
  const [newCategoryName, setNewCategoryName] = useState('');

  const [editOpen, setEditOpen] = useState(false);
  const [editId, setEditId] = useState('');
  const [editName, setEditName] = useState('');
  const [editUrl, setEditUrl] = useState('');
  const [editDescription, setEditDescription] = useState('');
  const [editCategory, setEditCategory] = useState('');
  const [editTags, setEditTags] = useState('');

  const [toast, setToast] = useState<{ message: string; type: 'success' | 'error'; visible: boolean }>({
    message: '',
    type: 'success',
    visible: false,
  });

  const showToast = useCallback((message: string, type: 'success' | 'error' = 'success') => {
    setToast({ message, type, visible: true });
    window.setTimeout(() => setToast((t) => ({ ...t, visible: false })), 3000);
  }, []);

  function redirectHome() {
    try {
      sessionStorage.removeItem(ADMIN_SESSION_KEY);
    } catch (_) {}
    navigate('/', { replace: true });
  }

  useEffect(() => {
    let token = searchParams.get('token');
    try {
      if (!token) token = sessionStorage.getItem(ADMIN_SESSION_KEY);
    } catch (_) {}

    if (!token) {
      redirectHome();
      setChecking(false);
      return;
    }

    let cancelled = false;
    (async () => {
      const ok = await authCheck(token!);
      if (cancelled) return;
      if (!ok) {
        redirectHome();
        setChecking(false);
        return;
      }
      setAuthToken(token!);
      setChecking(false);
    })();

    return () => {
      cancelled = true;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps -- 仅在挂载时校验入口 token
  }, []);

  const loadSites = useCallback(async () => {
    if (!authToken) return;
    try {
      const sites = await fetchSites({ headers: { Authorization: `Bearer ${authToken}` } });
      setAllSites(sites || []);
    } catch {
      showToast('加载网站列表失败', 'error');
    }
  }, [authToken, showToast]);

  const loadCategoriesData = useCallback(async () => {
    if (!authToken) return;
    try {
      const c = await fetchCategories(authToken);
      setCategories(c);
    } catch (e) {
      if ((e as Error)?.message === 'unauthorized') redirectHome();
      else setCategories([]);
    }
  }, [authToken]);

  useEffect(() => {
    if (!authToken) return;
    void loadSites();
    void loadCategoriesData();
  }, [authToken, loadSites, loadCategoriesData]);

  const mergedCategoryOptions = useMemo(() => {
    const fromSites = (allSites || []).map((s) => s.category || '默认').filter(Boolean);
    return Array.from(new Set(['默认', ...categories, ...fromSites]));
  }, [categories, allSites]);

  const filterSelectOptions = useMemo(() => {
    return Array.from(new Set(['默认', ...categories, ...(allSites || []).map((s) => s.category || '默认')]));
  }, [categories, allSites]);

  const displayedSites = useMemo(() => {
    if (!categoryFilter) return allSites;
    return allSites.filter((s) => (s.category || '默认') === categoryFilter);
  }, [allSites, categoryFilter]);

  const sitesByCategory = useMemo(() => {
    const map: Record<string, Site[]> = {};
    for (const site of displayedSites) {
      const c = site.category || '未分类';
      if (!map[c]) map[c] = [];
      map[c].push(site);
    }
    return map;
  }, [displayedSites]);

  const sortedCategoryKeys = useMemo(() => Object.keys(sitesByCategory).sort(), [sitesByCategory]);

  function openAddModal() {
    if (!authToken) return;
    setEditId('');
    setEditName('');
    setEditUrl('');
    setEditDescription('');
    setEditTags('');
    setEditCategory('');
    setEditOpen(true);
  }

  function openAddModalForCategory(sectionTitle: string) {
    if (!authToken) return;
    setEditId('');
    setEditName('');
    setEditUrl('');
    setEditDescription('');
    setEditTags('');
    setEditCategory(sectionTitle === '未分类' ? '' : sectionTitle);
    setEditOpen(true);
  }

  async function openEditModal(id: string) {
    if (!authToken) return;
    try {
      const site = await fetchSiteById(id);
      setEditId(site.id);
      setEditName(site.name);
      setEditUrl(site.url);
      setEditDescription(site.description || '');
      setEditCategory(site.category || '');
      setEditTags(site.tags?.join(', ') || '');
      setEditOpen(true);
    } catch {
      showToast('加载网站信息失败', 'error');
    }
  }

  async function onDeleteSite(id: string) {
    if (!authToken || !confirm('确定要删除这个网站吗？')) return;
    const ok = await deleteSite(authToken, id);
    if (ok) {
      showToast('网站删除成功');
      await loadSites();
    } else showToast('删除失败', 'error');
  }

  async function submitSite(e: React.FormEvent) {
    e.preventDefault();
    if (!authToken) return;
    let url = editUrl.trim();
    if (!url.startsWith('http://') && !url.startsWith('https://')) url = 'https://' + url;

    const site: Partial<Site> = {
      name: editName.trim(),
      url,
      description: editDescription.trim(),
      category: editCategory,
      tags: editTags
        .split(',')
        .map((x) => x.trim())
        .filter(Boolean),
    };

    const ok = await saveSite(authToken, site, editId || undefined);
    if (ok) {
      showToast(editId ? '网站更新成功' : '网站添加成功');
      setEditOpen(false);
      await loadSites();
      await loadCategoriesData();
    } else showToast('保存失败', 'error');
  }

  async function onAddCategory() {
    const name = newCategoryName.trim();
    if (!authToken || !name) return;
    const ok = await addCategory(authToken, name);
    if (ok) {
      setNewCategoryName('');
      await loadCategoriesData();
      showToast('分类添加成功');
    } else showToast('分类添加失败', 'error');
  }

  async function onRenameCategory(oldName: string) {
    if (!authToken) return;
    const next = prompt('请输入新的分类名称', oldName);
    if (!next || next.trim() === oldName) return;
    const ok = await renameCategory(authToken, oldName, next.trim());
    if (ok) {
      await loadCategoriesData();
      await loadSites();
      showToast('分类更新成功');
    } else showToast('分类更新失败', 'error');
  }

  async function onDeleteCategory(name: string) {
    if (!authToken || !confirm(`确定删除分类「${name}」吗？`)) return;
    const ok = await deleteCategory(authToken, name);
    if (ok) {
      await loadCategoriesData();
      showToast('分类删除成功');
    } else showToast('分类删除失败', 'error');
  }

  if (checking || !authToken) {
    return null;
  }

  return (
    <div className="container admin-page">
      <div className="admin-container visible" id="admin-container">
        <div className="admin-header">
          <h1 id="admin-title">{SITE_NAME}-管理后台</h1>
          <button
            type="button"
            className="exit-btn"
            id="logout-btn"
            onClick={() => {
              try {
                sessionStorage.removeItem(ADMIN_SESSION_KEY);
              } catch (_) {}
              navigate('/');
            }}
          >
            退出
          </button>
        </div>

        <div className="categories-panel">
          <div className="panel-header">
            <h2>📁 分类管理</h2>
            <div className="category-add">
              <input
                type="text"
                id="new-category-name"
                placeholder="新增分类"
                value={newCategoryName}
                onChange={(e) => setNewCategoryName(e.target.value)}
              />
              <button type="button" className="btn-edit" id="add-category-btn" onClick={() => void onAddCategory()}>
                添加分类
              </button>
            </div>
          </div>
          <div className="category-list" id="category-list">
            {!categories.length ? (
              <div style={{ color: '#64748b' }}>暂无分类</div>
            ) : (
              categories.map((name) => (
                <div key={name} className="category-item">
                  <span>{name}</span>
                  <span className="category-actions">
                    <button type="button" onClick={() => void onRenameCategory(name)}>
                      编辑
                    </button>
                    <button type="button" onClick={() => void onDeleteCategory(name)}>
                      删除
                    </button>
                  </span>
                </div>
              ))
            )}
          </div>
        </div>

        <div style={{ marginBottom: 20 }}>
          <button type="button" className="add-site-btn" id="add-new-site" onClick={openAddModal}>
            ✚ 添加新网站
          </button>
        </div>

        <div className="admin-sites-board">
          <div className="sites-table-header">
            <h2>网站预览</h2>
            <div className="sites-filter">
              <label htmlFor="site-category-filter">按分类筛选：</label>
              <select
                id="site-category-filter"
                title="选择分类可快速筛选网站"
                value={categoryFilter}
                onChange={(e) => setCategoryFilter(e.target.value)}
              >
                <option value="">全部</option>
                {filterSelectOptions.map((name) => (
                  <option key={name} value={name}>
                    {name}
                  </option>
                ))}
              </select>
            </div>
          </div>
          {displayedSites.length === 0 ? (
            <div className="empty-state">
              <div style={{ fontSize: '3rem', marginBottom: 12 }}>📭</div>
              <p>{categoryFilter ? '该分类下暂无网站' : '暂无网站，点击上方添加'}</p>
            </div>
          ) : (
            <div className="categories-container admin-preview-categories">
              {sortedCategoryKeys.map((categoryName) => (
                <div key={categoryName} className="category-section">
                  <h2 className="category-title">
                    <span className="category-title-label">{categoryName}</span>
                    <button
                      type="button"
                      className="admin-category-quick-add"
                      title={`在此分类下添加网站：${categoryName}`}
                      aria-label={`在「${categoryName}」下添加网站`}
                      onClick={() => openAddModalForCategory(categoryName)}
                    >
                      +
                    </button>
                  </h2>
                  <div className="sites-grid">
                    {sitesByCategory[categoryName].map((site) => (
                      <AdminSiteCard
                        key={site.id}
                        site={site}
                        onEdit={(id) => void openEditModal(id)}
                        onDelete={(id) => void onDeleteSite(id)}
                      />
                    ))}
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
      </div>

      <Toast message={toast.message} type={toast.type} visible={toast.visible} />

      <div
        className={`modal-overlay${editOpen ? ' active' : ''}`}
        id="edit-modal"
        onClick={(e) => {
          if ((e.target as HTMLElement).id === 'edit-modal') setEditOpen(false);
        }}
      >
        <div className="modal-content">
          <div className="modal-header">
            <h2 id="modal-title">{editId ? '编辑网站' : '添加网站'}</h2>
            <button type="button" className="close-modal" id="close-edit-modal" onClick={() => setEditOpen(false)}>
              &times;
            </button>
          </div>
          <div className="modal-body">
            <form id="edit-site-form" onSubmit={(e) => void submitSite(e)}>
              <input type="hidden" id="edit-site-id" value={editId} readOnly />
              <div className="form-group">
                <label htmlFor="edit-site-name">网站名称 *</label>
                <input type="text" id="edit-site-name" required value={editName} onChange={(e) => setEditName(e.target.value)} />
              </div>
              <div className="form-group">
                <label htmlFor="edit-site-url">网站地址 *</label>
                <input type="url" id="edit-site-url" required value={editUrl} onChange={(e) => setEditUrl(e.target.value)} />
              </div>
              <div className="form-group">
                <label htmlFor="edit-site-description">网站描述</label>
                <textarea id="edit-site-description" value={editDescription} onChange={(e) => setEditDescription(e.target.value)} />
              </div>
              <div className="form-row">
                <div className="form-group">
                  <label htmlFor="edit-site-category">网站分类</label>
                  <select id="edit-site-category" value={editCategory} onChange={(e) => setEditCategory(e.target.value)}>
                    <option value="">未分类</option>
                    {mergedCategoryOptions
                      .filter((name) => name !== '未分类')
                      .map((name) => (
                        <option key={name} value={name}>
                          {name}
                        </option>
                      ))}
                  </select>
                </div>
                <div className="form-group">
                  <label htmlFor="edit-site-tags">网站标签</label>
                  <input id="edit-site-tags" type="text" placeholder="用逗号分隔" value={editTags} onChange={(e) => setEditTags(e.target.value)} />
                </div>
              </div>
              <button type="submit" className="submit-btn">
                保存
              </button>
            </form>
          </div>
        </div>
      </div>
    </div>
  );
}
