import { useEffect, useState, type CSSProperties, type ReactNode } from 'react';
import {
  cancelWechatDigest,
  clearWechatRoute,
  fetchWechatBindings,
  fetchWechatDeliveries,
  fetchWechatDigests,
  fetchWechatMessages,
  fetchWechatSummary,
  resumeWechatDigest,
  type WechatAdminSummary,
  type WechatBinding,
  type WechatDeliveryLog,
  type WechatDigestSubscription,
  type WechatMessage,
} from '../../api/admin';

function time(value?: number | null) {
  if (!value) return '—';
  return new Date(value).toLocaleString('zh-CN', { hour12: false });
}

function count(record: Record<string, number>, key: string) {
  return record[key] ?? 0;
}

function badge(status?: string | null) {
  if (!status) return <span style={{ color: '#68716c' }}>—</span>;
  const color =
    status === 'active' || status === 'success' || status === 'done'
      ? '#2f6f57'
      : status === 'failed'
        ? '#b42318'
        : '#68716c';
  return <strong style={{ color, fontSize: 12 }}>{status}</strong>;
}

function userName(row: { displayName?: string | null; username?: string | null }) {
  return row.displayName || row.username || '—';
}

const tableStyle = {
  width: '100%',
  borderCollapse: 'collapse',
  fontSize: 13,
} satisfies CSSProperties;

const thStyle = {
  textAlign: 'left',
  color: '#68716c',
  fontWeight: 600,
  borderBottom: '1px solid #e7dfd1',
  padding: '8px 6px',
  whiteSpace: 'nowrap',
} satisfies CSSProperties;

const tdStyle = {
  borderBottom: '1px solid #eee7da',
  padding: '9px 6px',
  verticalAlign: 'top',
} satisfies CSSProperties;

export function WechatPage() {
  const [summary, setSummary] = useState<WechatAdminSummary | null>(null);
  const [bindings, setBindings] = useState<WechatBinding[]>([]);
  const [messages, setMessages] = useState<WechatMessage[]>([]);
  const [digests, setDigests] = useState<WechatDigestSubscription[]>([]);
  const [deliveries, setDeliveries] = useState<WechatDeliveryLog[]>([]);
  const [search, setSearch] = useState('');
  const [messageStatus, setMessageStatus] = useState('');
  const [digestStatus, setDigestStatus] = useState('');
  const [deliveryStatus, setDeliveryStatus] = useState('');
  const [error, setError] = useState<string | null>(null);
  const [busy, setBusy] = useState(false);

  const load = async () => {
    setError(null);
    try {
      const [summaryResult, bindingResult, messageResult, digestResult, deliveryResult] =
        await Promise.all([
          fetchWechatSummary(),
          fetchWechatBindings({ search, limit: 80 }),
          fetchWechatMessages({ status: messageStatus || undefined, limit: 80 }),
          fetchWechatDigests({ status: digestStatus || undefined, limit: 80 }),
          fetchWechatDeliveries({ status: deliveryStatus || undefined, limit: 80 }),
        ]);
      setSummary(summaryResult);
      setBindings(bindingResult.bindings);
      setMessages(messageResult.messages);
      setDigests(digestResult.digests);
      setDeliveries(deliveryResult.deliveries);
    } catch (err) {
      setError(err instanceof Error ? err.message : '加载失败');
    }
  };

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

  const handleClearRoute = async (binding: WechatBinding) => {
    if (!window.confirm(`确认清除「${userName(binding)}」的服务号会话路由？下一次用户发消息会重建路由。`)) return;
    setBusy(true);
    try {
      await clearWechatRoute(binding.userId);
      await load();
    } catch (err) {
      setError(err instanceof Error ? err.message : '清除失败');
    } finally {
      setBusy(false);
    }
  };

  const handleCancelDigest = async (digest: WechatDigestSubscription) => {
    if (!window.confirm(`确认暂停「${userName(digest)}」的每日待办推送？`)) return;
    setBusy(true);
    try {
      await cancelWechatDigest(digest.id);
      await load();
    } catch (err) {
      setError(err instanceof Error ? err.message : '暂停失败');
    } finally {
      setBusy(false);
    }
  };

  const handleResumeDigest = async (digest: WechatDigestSubscription) => {
    setBusy(true);
    try {
      await resumeWechatDigest(digest.id);
      await load();
    } catch (err) {
      setError(err instanceof Error ? err.message : '恢复失败');
    } finally {
      setBusy(false);
    }
  };

  if (!summary && !error) return <p>加载中...</p>;

  return (
    <div className="grid">
      {error ? <p className="alert">{error}</p> : null}

      {summary ? (
        <div
          className="card"
          style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(170px, 1fr))', gap: 12 }}
        >
          <Metric label="服务号" value={summary.config.mpEnabled ? '已启用' : '未启用'} />
          <Metric label="绑定用户" value={summary.counts.boundUsers} />
          <Metric label="活跃路由" value={`${summary.counts.routes.active}/${summary.counts.routes.total}`} />
          <Metric label="每日订阅" value={count(summary.counts.digests, 'active')} />
          <Metric label="24h 消息失败" value={count(summary.counts.recentMessages, 'failed')} danger />
          <Metric label="24h 投递失败" value={count(summary.counts.recentDeliveries, 'failed')} danger />
          <div style={{ gridColumn: '1 / -1', color: '#68716c', fontSize: 12 }}>
            AppID {summary.config.appId ?? '未配置'} · {summary.config.publicBaseUrl ?? '未配置公网地址'}
            {summary.config.bindPath ? ` · 绑定路径 ${summary.config.bindPath}` : ''}
          </div>
        </div>
      ) : null}

      <section className="card grid">
        <div style={{ display: 'flex', justifyContent: 'space-between', gap: 12, flexWrap: 'wrap' }}>
          <h3 style={{ margin: 0 }}>绑定与会话路由</h3>
          <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
            <input
              value={search}
              onChange={(event) => setSearch(event.target.value)}
              placeholder="搜索用户、昵称、openid"
              style={{ width: 220 }}
            />
            <button type="button" className="btn secondary" onClick={() => void load()} disabled={busy}>
              查询
            </button>
          </div>
        </div>
        <TableShell empty={bindings.length === 0}>
          <table style={tableStyle}>
            <thead>
              <tr>
                <th style={thStyle}>用户</th>
                <th style={thStyle}>微信</th>
                <th style={thStyle}>路由</th>
                <th style={thStyle}>最近绑定登录</th>
                <th style={thStyle}>操作</th>
              </tr>
            </thead>
            <tbody>
              {bindings.map((binding) => (
                <tr key={`${binding.userId}-${binding.openidMasked}`}>
                  <td style={tdStyle}>
                    <strong>{userName(binding)}</strong>
                    <div style={{ color: '#68716c', fontSize: 12 }}>{binding.username}</div>
                  </td>
                  <td style={tdStyle}>
                    <div>{binding.nickname || '—'}</div>
                    <div style={{ color: '#68716c', fontSize: 12 }}>{binding.openidMasked}</div>
                  </td>
                  <td style={tdStyle}>
                    {badge(binding.routeStatus)}
                    <div style={{ color: '#68716c', fontSize: 12 }}>{binding.agentSessionId || '无会话'}</div>
                  </td>
                  <td style={tdStyle}>{time(binding.lastLoginAt)}</td>
                  <td style={tdStyle}>
                    <button
                      type="button"
                      className="btn secondary"
                      style={{ padding: '4px 10px', fontSize: 12 }}
                      onClick={() => void handleClearRoute(binding)}
                      disabled={busy || !binding.routeId}
                    >
                      清除路由
                    </button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </TableShell>
      </section>

      <section className="card grid">
        <SectionHead
          title="每日待办推送"
          value={digestStatus}
          options={['', 'active', 'locked', 'failed', 'cancelled']}
          onChange={setDigestStatus}
          onRefresh={() => void load()}
          busy={busy}
        />
        <TableShell empty={digests.length === 0}>
          <table style={tableStyle}>
            <thead>
              <tr>
                <th style={thStyle}>用户</th>
                <th style={thStyle}>时间</th>
                <th style={thStyle}>状态</th>
                <th style={thStyle}>下次运行</th>
                <th style={thStyle}>错误</th>
                <th style={thStyle}>操作</th>
              </tr>
            </thead>
            <tbody>
              {digests.map((digest) => (
                <tr key={digest.id}>
                  <td style={tdStyle}>
                    <strong>{userName(digest)}</strong>
                    <div style={{ color: '#68716c', fontSize: 12 }}>{digest.username}</div>
                  </td>
                  <td style={tdStyle}>
                    {String(digest.hour).padStart(2, '0')}:{String(digest.minute).padStart(2, '0')}
                    <div style={{ color: '#68716c', fontSize: 12 }}>{digest.timezone}</div>
                  </td>
                  <td style={tdStyle}>{badge(digest.status)}</td>
                  <td style={tdStyle}>{time(digest.nextRunAt)}</td>
                  <td style={{ ...tdStyle, maxWidth: 260 }}>{digest.lastError || '—'}</td>
                  <td style={tdStyle}>
                    {digest.status === 'active' || digest.status === 'locked' ? (
                      <button
                        type="button"
                        className="btn secondary"
                        style={{ padding: '4px 10px', fontSize: 12 }}
                        onClick={() => void handleCancelDigest(digest)}
                        disabled={busy}
                      >
                        暂停
                      </button>
                    ) : (
                      <button
                        type="button"
                        className="btn"
                        style={{ padding: '4px 10px', fontSize: 12 }}
                        onClick={() => void handleResumeDigest(digest)}
                        disabled={busy}
                      >
                        恢复
                      </button>
                    )}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </TableShell>
      </section>

      <section className="card grid">
        <SectionHead
          title="最近服务号消息"
          value={messageStatus}
          options={['', 'processing', 'done', 'failed']}
          onChange={setMessageStatus}
          onRefresh={() => void load()}
          busy={busy}
        />
        <TableShell empty={messages.length === 0}>
          <table style={tableStyle}>
            <thead>
              <tr>
                <th style={thStyle}>用户</th>
                <th style={thStyle}>OpenID</th>
                <th style={thStyle}>状态</th>
                <th style={thStyle}>会话</th>
                <th style={thStyle}>更新时间</th>
              </tr>
            </thead>
            <tbody>
              {messages.map((message) => (
                <tr key={`${message.openidMasked}-${message.msgId}`}>
                  <td style={tdStyle}>{userName(message)}</td>
                  <td style={tdStyle}>{message.openidMasked}</td>
                  <td style={tdStyle}>{badge(message.status)}</td>
                  <td style={tdStyle}>{message.agentSessionId || '—'}</td>
                  <td style={tdStyle}>{time(message.updatedAt)}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </TableShell>
      </section>

      <section className="card grid">
        <SectionHead
          title="推送投递日志"
          value={deliveryStatus}
          options={['', 'success', 'failed']}
          onChange={setDeliveryStatus}
          onRefresh={() => void load()}
          busy={busy}
        />
        <TableShell empty={deliveries.length === 0}>
          <table style={tableStyle}>
            <thead>
              <tr>
                <th style={thStyle}>用户</th>
                <th style={thStyle}>类型</th>
                <th style={thStyle}>状态</th>
                <th style={thStyle}>错误</th>
                <th style={thStyle}>时间</th>
              </tr>
            </thead>
            <tbody>
              {deliveries.map((delivery) => (
                <tr key={delivery.id}>
                  <td style={tdStyle}>{userName(delivery)}</td>
                  <td style={tdStyle}>{delivery.digestType ?? (delivery.reminderId ? 'reminder' : '—')}</td>
                  <td style={tdStyle}>{badge(delivery.status)}</td>
                  <td style={{ ...tdStyle, maxWidth: 320 }}>
                    {delivery.errorMessage || delivery.errorCode || delivery.providerMessageId || '—'}
                  </td>
                  <td style={tdStyle}>{time(delivery.createdAt)}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </TableShell>
      </section>
    </div>
  );
}

function Metric({ label, value, danger = false }: { label: string; value: string | number; danger?: boolean }) {
  return (
    <div>
      <p style={{ color: '#68716c', marginBottom: 4 }}>{label}</p>
      <strong style={{ fontSize: 26, color: danger && Number(value) > 0 ? '#b42318' : undefined }}>{value}</strong>
    </div>
  );
}

function SectionHead({
  title,
  value,
  options,
  onChange,
  onRefresh,
  busy,
}: {
  title: string;
  value: string;
  options: string[];
  onChange: (value: string) => void;
  onRefresh: () => void;
  busy: boolean;
}) {
  return (
    <div style={{ display: 'flex', justifyContent: 'space-between', gap: 12, flexWrap: 'wrap' }}>
      <h3 style={{ margin: 0 }}>{title}</h3>
      <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
        <select value={value} onChange={(event) => onChange(event.target.value)} style={{ width: 160 }}>
          {options.map((option) => (
            <option key={option || 'all'} value={option}>
              {option || '全部状态'}
            </option>
          ))}
        </select>
        <button type="button" className="btn secondary" onClick={onRefresh} disabled={busy}>
          刷新
        </button>
      </div>
    </div>
  );
}

function TableShell({ empty, children }: { empty: boolean; children: ReactNode }) {
  if (empty) return <p style={{ color: '#68716c', margin: 0 }}>暂无记录</p>;
  return <div style={{ overflowX: 'auto' }}>{children}</div>;
}
