import { useState, useEffect, useCallback } from 'react';
import { listLinks, updateLink, deleteLink, type ClientRule, type IpRule, type LinkItem, type GeoRule } from '../api';
import EditDrawer from './EditDrawer';

const PAGE_SIZE = 20;

function formatDate(ts: number | null): string {
  if (!ts) return '—';
  return new Date(ts * 1000).toLocaleString('zh-CN', {
    year: 'numeric', month: '2-digit', day: '2-digit',
    hour: '2-digit', minute: '2-digit',
  });
}

function geoBadge(item: LinkItem): JSX.Element | null {
  if (!item.geo_rule) return null;
  let rule: GeoRule;
  try { rule = JSON.parse(item.geo_rule); } catch { return null; }
  const label = rule.mode === 'allow'
    ? `仅 ${rule.countries.join('/')}`
    : `屏蔽 ${rule.countries.join('/')}`;
  return <span className="tag tag-mute" style={{ marginLeft: '0.3rem' }} title={label}>{label}</span>;
}

function clientBadge(item: LinkItem): JSX.Element | null {
  if (!item.client_rule) return null;
  let r: ClientRule;
  try { r = JSON.parse(item.client_rule); } catch { return null; }
  const parts: string[] = [];
  if (r.device === 'mobile') parts.push('仅手机');
  if (r.device === 'desktop') parts.push('仅电脑');
  if (r.browsers && r.browsers.length) {
    const m: Record<string, string> = { chrome: 'Chrome', edge: 'Edge', safari: 'Safari', firefox: 'Fx', opera: 'Op', other: '其他' };
    parts.push(r.browsers.map(b => m[b] || b).join('+'));
  }
  if (!parts.length) return null;
  const label = [r.device && (r.device === 'mobile' ? '手机' : '电脑'), r.browsers?.length ? `浏览器: ${r.browsers.join(',')}` : ''].filter(Boolean).join(' · ');
  return (
    <span
      className="tag tag-mute"
      style={{ marginLeft: '0.3rem', maxWidth: 200, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}
      title={label}
    >
      {parts.join(' · ')}
    </span>
  );
}

function ipBadge(item: LinkItem): JSX.Element | null {
  if (!item.ip_rule) return null;
  let r: IpRule;
  try { r = JSON.parse(item.ip_rule); } catch { return null; }
  const n = r.ips?.length ?? 0;
  if (!n) return null;
  const short = r.mode === 'allow' ? `白${n}条` : `黑${n}条`;
  return (
    <span
      className="tag tag-mute"
      style={{ marginLeft: '0.3rem' }}
      title={r.mode === 'allow' ? 'IP 白名单' : 'IP 黑名单'}
    >
      {short}
    </span>
  );
}

function expiredBadge(item: LinkItem): JSX.Element {
  const now = Math.floor(Date.now() / 1000);
  if (item.expires_at && now > item.expires_at) {
    return <span className="tag tag-void">已过期</span>;
  }
  if (item.max_clicks !== null && item.clicks >= item.max_clicks) {
    return <span className="tag tag-void">已满</span>;
  }
  if (item.deleted) return <span className="tag tag-mute">停用</span>;
  return <span className="tag tag-ok">有效</span>;
}

export default function AdminPanel() {
  const [items, setItems] = useState<LinkItem[]>([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');
  const [editing, setEditing] = useState<LinkItem | null>(null);
  const [confirmDelete, setConfirmDelete] = useState<string | null>(null);

  const load = useCallback(async (p: number) => {
    setLoading(true);
    setError('');
    try {
      const data = await listLinks(p, PAGE_SIZE);
      setItems(data.items);
      setTotal(data.total);
    } catch (e) {
      setError(String(e));
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => { load(page); }, [page, load]);

  const handleDelete = async (code: string) => {
    try {
      await deleteLink(code);
      setConfirmDelete(null);
      load(page);
    } catch (e) {
      setError(String(e));
    }
  };

  const handleToggleDeleted = async (item: LinkItem) => {
    try {
      await updateLink(item.code, { deleted: item.deleted ? 0 : 1 });
      load(page);
    } catch (e) {
      setError(String(e));
    }
  };

  const handleSave = async () => {
    setEditing(null);
    load(page);
  };

  const totalPages = Math.max(1, Math.ceil(total / PAGE_SIZE));

  return (
    <div>
      <div className="admin-toolbar">{total}</div>

      {error && <div className="error-msg" style={{ marginBottom: '1rem' }}>{error}</div>}

      {loading && <p className="link-muted" style={{ fontSize: '0.8rem', marginBottom: '0.75rem' }}>加载中</p>}

      {editing && (
        <EditDrawer
          item={editing}
          onSave={handleSave}
          onClose={() => setEditing(null)}
        />
      )}

      <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
        <div className="link-table-wrap">
          <table className="link-table">
            <thead>
              <tr>
                <th>短码</th>
                <th>目标链接</th>
                <th>状态</th>
                <th>点击</th>
                <th>过期时间</th>
                <th>创建时间</th>
                <th>操作</th>
              </tr>
            </thead>
            <tbody>
              {items.length === 0 && !loading && (
                <tr>
                  <td colSpan={7} style={{ textAlign: 'center', color: 'var(--muted)', padding: '2rem' }}>
                    暂无数据
                  </td>
                </tr>
              )}
              {items.map(item => (
                <tr key={item.id}>
                  <td style={{ maxWidth: 200, wordBreak: 'break-all' }}>
                    <code style={{ fontFamily: 'ui-monospace, monospace', fontSize: '0.88rem', fontWeight: 500, color: 'var(--ink)' }}>
                      {item.code}
                    </code>
                    {item.has_password ? (
                      <span className="tag tag-mute" style={{ marginLeft: '0.35rem' }}>密</span>
                    ) : null}
                    {geoBadge(item)}
                    {clientBadge(item)}
                    {ipBadge(item)}
                  </td>
                  <td>
                    <a
                      href={item.target_url}
                      target="_blank"
                      rel="noopener noreferrer"
                      style={{ fontSize: '0.82rem', color: 'var(--muted)', wordBreak: 'break-all' }}
                    >
                      {item.target_url.length > 45 ? item.target_url.slice(0, 45) + '…' : item.target_url}
                    </a>
                  </td>
                  <td>{expiredBadge(item)}</td>
                  <td style={{ fontSize: '0.85rem' }}>
                    {item.clicks}
                    {item.max_clicks !== null && (
                      <span style={{ color: 'var(--muted)' }}> / {item.max_clicks}</span>
                    )}
                  </td>
                  <td style={{ fontSize: '0.8rem', color: 'var(--muted)', whiteSpace: 'nowrap' }}>
                    {formatDate(item.expires_at)}
                  </td>
                  <td style={{ fontSize: '0.8rem', color: 'var(--muted)', whiteSpace: 'nowrap' }}>
                    {formatDate(item.created_at)}
                  </td>
                  <td>
                    <div style={{ display: 'flex', gap: '0.35rem', flexWrap: 'wrap' }}>
                      <button
                        className="btn-ghost"
                        onClick={() => setEditing(item)}
                        disabled={!!editing}
                      >
                        编辑
                      </button>
                      <button
                        className="btn-ghost"
                        onClick={() => handleToggleDeleted(item)}
                        style={{ fontSize: '0.78rem' }}
                      >
                        {item.deleted ? '恢复' : '禁用'}
                      </button>
                      {confirmDelete === item.code ? (
                        <>
                          <button
                            className="btn-danger"
                            onClick={() => handleDelete(item.code)}
                          >
                            确认
                          </button>
                          <button
                            className="btn-ghost"
                            onClick={() => setConfirmDelete(null)}
                          >
                            取消
                          </button>
                        </>
                      ) : (
                        <button
                          className="btn-danger"
                          onClick={() => setConfirmDelete(item.code)}
                        >
                          删除
                        </button>
                      )}
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>

      {totalPages > 1 && (
        <div className="pagination">
          <button
            type="button"
            className="btn-ghost"
            disabled={page <= 1}
            onClick={() => setPage(p => p - 1)}
          >
            ←
          </button>
          {Array.from({ length: totalPages }, (_, i) => i + 1)
            .filter(p => Math.abs(p - page) <= 2 || p === 1 || p === totalPages)
            .reduce<(number | '...')[]>((acc, p, idx, arr) => {
              if (idx > 0 && (arr[idx - 1] as number) < p - 1) acc.push('...');
              acc.push(p);
              return acc;
            }, [])
            .map((p, i) =>
              p === '...'
                ? <span key={`ellipsis-${i}`} style={{ padding: '0.3rem 0.5rem', color: 'var(--muted)' }}>…</span>
                : (
                  <button
                    type="button"
                    key={p}
                    className={`btn-ghost page-num ${p === page ? 'is-active' : ''}`}
                    onClick={() => setPage(p as number)}
                  >
                    {p}
                  </button>
                )
            )
          }
          <button
            type="button"
            className="btn-ghost"
            disabled={page >= totalPages}
            onClick={() => setPage(p => p + 1)}
          >
            →
          </button>
        </div>
      )}
    </div>
  );
}
