import { useCallback, useEffect, useState } from 'react';
import {
  cancelWechatDigest,
  clearWechatRoute,
  getWechatAdminSummary,
  listWechatBindings,
  listWechatDeliveries,
  listWechatDigests,
  listWechatMessages,
  resumeWechatDigest,
} from '../../api/client';
import type {
  WechatAdminSummary,
  WechatBinding,
  WechatDeliveryLog,
  WechatDigestSubscription,
  WechatMessage,
} from '../../types';
import { formatTime } from '../utils/format';

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

function safeSummary(summary: WechatAdminSummary | null) {
  return {
    config: summary?.config ?? {
      mpEnabled: false,
      scheduleEnabled: false,
      reminderWorkerEnabled: false,
      appId: null,
      publicBaseUrl: null,
      bindPath: null,
      tokenEndpointConfigured: false,
      customerServiceEndpointConfigured: false,
    },
    counts: summary?.counts ?? {
      boundUsers: 0,
      routes: { total: 0, active: 0 },
      recentMessages: {},
      digests: {},
      recentDeliveries: {},
    },
  };
}

function statusLabel(status?: string | null) {
  if (!status) return '—';
  return status;
}

function statusClass(status?: string | null) {
  if (status === 'failed') return 'text-error';
  if (status === 'active' || status === 'success' || status === 'done') return 'wechat-ok';
  return 'muted';
}

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

function dateLabel(value?: number | null) {
  return value ? formatTime(value) : '—';
}

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 [loading, setLoading] = useState(true);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const safe = safeSummary(summary);

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const [nextSummary, nextBindings, nextMessages, nextDigests, nextDeliveries] =
        await Promise.all([
          getWechatAdminSummary(),
          listWechatBindings({ search, limit: 80 }),
          listWechatMessages({ status: messageStatus || undefined, limit: 80 }),
          listWechatDigests({ status: digestStatus || undefined, limit: 80 }),
          listWechatDeliveries({ status: deliveryStatus || undefined, limit: 80 }),
        ]);
      setSummary(nextSummary);
      setBindings(nextBindings);
      setMessages(nextMessages);
      setDigests(nextDigests);
      setDeliveries(nextDeliveries);
    } catch (err) {
      setError(err instanceof Error ? err.message : '加载服务号管理失败');
    } finally {
      setLoading(false);
    }
  }, [deliveryStatus, digestStatus, messageStatus, search]);

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

  const runAction = async (action: () => Promise<unknown>) => {
    setBusy(true);
    setError(null);
    try {
      await action();
      await load();
    } catch (err) {
      setError(err instanceof Error ? err.message : '操作失败');
    } finally {
      setBusy(false);
    }
  };

  return (
    <div className="admin-page">
      <div className="admin-page-head">
        <h2>服务号管理</h2>
        <p className="muted">绑定、路由、每日待办推送和投递记录</p>
      </div>

      {error && <p className="banner banner-error">{error}</p>}

      <div className="admin-stat-grid">
        <Stat label="服务号" value={loading ? '—' : safe.config.mpEnabled ? '已启用' : '未启用'} />
        <Stat label="绑定用户" value={loading ? '—' : safe.counts.boundUsers} />
        <Stat
          label="活跃路由"
          value={
            loading
              ? '—'
              : `${safe.counts.routes.active}/${safe.counts.routes.total}`
          }
        />
        <Stat label="每日推送" value={loading ? '—' : count(safe.counts.digests, 'active')} />
        <Stat
          label="24h 消息失败"
          value={loading ? '—' : count(safe.counts.recentMessages, 'failed')}
        />
        <Stat
          label="24h 投递失败"
          value={loading ? '—' : count(safe.counts.recentDeliveries, 'failed')}
        />
      </div>

      {summary && (
        <section className="admin-card">
          <h2>配置状态</h2>
          <dl className="admin-dl">
            <div>
              <dt>AppID</dt>
              <dd>{summary.config.appId ?? '未配置'}</dd>
            </div>
            <div>
              <dt>公网地址</dt>
              <dd>{summary.config.publicBaseUrl ?? '未配置'}</dd>
            </div>
            <div>
              <dt>绑定路径</dt>
              <dd>{summary.config.bindPath ?? '未配置'}</dd>
            </div>
            <div>
              <dt>定时服务</dt>
              <dd>{summary.config.scheduleEnabled ? '已启用' : '未启用'}</dd>
            </div>
            <div>
              <dt>推送 worker</dt>
              <dd>{summary.config.reminderWorkerEnabled ? '已启用' : '未启用'}</dd>
            </div>
          </dl>
        </section>
      )}

      <section className="admin-card">
        <div className="admin-card-head">
          <h2>绑定与会话路由</h2>
          <div className="wechat-toolbar">
            <input
              value={search}
              onChange={(event) => setSearch(event.target.value)}
              placeholder="搜索用户、昵称、openid"
            />
            <button type="button" className="ghost-btn" onClick={() => void load()} disabled={busy}>
              查询
            </button>
          </div>
        </div>
        <div className="admin-table-wrap">
          <table className="admin-table">
            <thead>
              <tr>
                <th>用户</th>
                <th>微信</th>
                <th>路由</th>
                <th>最近登录</th>
                <th>操作</th>
              </tr>
            </thead>
            <tbody>
              {bindings.length === 0 ? (
                <tr><td colSpan={5} className="muted">暂无记录</td></tr>
              ) : (
                bindings.map((binding) => (
                  <tr key={`${binding.userId}-${binding.openidMasked}`}>
                    <td>
                      <div>{userLabel(binding)}</div>
                      <div className="muted">@{binding.username}</div>
                    </td>
                    <td>
                      <div>{binding.nickname || '—'}</div>
                      <div className="mono">{binding.openidMasked}</div>
                    </td>
                    <td>
                      <div className={statusClass(binding.routeStatus)}>
                        {statusLabel(binding.routeStatus)}
                      </div>
                      <div className="mono">{binding.agentSessionId || '无会话'}</div>
                    </td>
                    <td>{dateLabel(binding.lastLoginAt)}</td>
                    <td className="admin-actions">
                      <button
                        type="button"
                        className="ghost-btn"
                        disabled={busy || !binding.routeId}
                        onClick={() => {
                          if (!window.confirm(`确认清除「${userLabel(binding)}」的服务号会话路由？`)) return;
                          void runAction(() => clearWechatRoute(binding.userId));
                        }}
                      >
                        清除路由
                      </button>
                    </td>
                  </tr>
                ))
              )}
            </tbody>
          </table>
        </div>
      </section>

      <section className="admin-card">
        <TableHead
          title="每日待办推送"
          value={digestStatus}
          options={['', 'active', 'locked', 'failed', 'cancelled']}
          onChange={setDigestStatus}
          onRefresh={() => void load()}
          busy={busy}
        />
        <div className="admin-table-wrap">
          <table className="admin-table">
            <thead>
              <tr>
                <th>用户</th>
                <th>时间</th>
                <th>状态</th>
                <th>下次运行</th>
                <th>错误</th>
                <th>操作</th>
              </tr>
            </thead>
            <tbody>
              {digests.length === 0 ? (
                <tr><td colSpan={6} className="muted">暂无记录</td></tr>
              ) : (
                digests.map((digest) => (
                  <tr key={digest.id}>
                    <td>
                      <div>{userLabel(digest)}</div>
                      <div className="muted">@{digest.username}</div>
                    </td>
                    <td>
                      {String(digest.hour).padStart(2, '0')}:{String(digest.minute).padStart(2, '0')}
                      <div className="muted">{digest.timezone}</div>
                    </td>
                    <td className={statusClass(digest.status)}>{digest.status}</td>
                    <td>{dateLabel(digest.nextRunAt)}</td>
                    <td>{digest.lastError || '—'}</td>
                    <td className="admin-actions">
                      {digest.status === 'active' || digest.status === 'locked' ? (
                        <button
                          type="button"
                          className="ghost-btn"
                          disabled={busy}
                          onClick={() => {
                            if (!window.confirm(`确认暂停「${userLabel(digest)}」的每日待办推送？`)) return;
                            void runAction(() => cancelWechatDigest(digest.id));
                          }}
                        >
                          暂停
                        </button>
                      ) : (
                        <button
                          type="button"
                          className="send-btn"
                          disabled={busy}
                          onClick={() => void runAction(() => resumeWechatDigest(digest.id))}
                        >
                          恢复
                        </button>
                      )}
                    </td>
                  </tr>
                ))
              )}
            </tbody>
          </table>
        </div>
      </section>

      <section className="admin-card">
        <TableHead
          title="最近服务号消息"
          value={messageStatus}
          options={['', 'processing', 'done', 'failed']}
          onChange={setMessageStatus}
          onRefresh={() => void load()}
          busy={busy}
        />
        <div className="admin-table-wrap">
          <table className="admin-table">
            <thead>
              <tr>
                <th>用户</th>
                <th>OpenID</th>
                <th>状态</th>
                <th>会话</th>
                <th>更新时间</th>
              </tr>
            </thead>
            <tbody>
              {messages.length === 0 ? (
                <tr><td colSpan={5} className="muted">暂无记录</td></tr>
              ) : (
                messages.map((message) => (
                  <tr key={`${message.openidMasked}-${message.msgId}`}>
                    <td>{userLabel(message)}</td>
                    <td className="mono">{message.openidMasked}</td>
                    <td className={statusClass(message.status)}>{message.status}</td>
                    <td className="mono">{message.agentSessionId || '—'}</td>
                    <td>{dateLabel(message.updatedAt)}</td>
                  </tr>
                ))
              )}
            </tbody>
          </table>
        </div>
      </section>

      <section className="admin-card">
        <TableHead
          title="推送投递日志"
          value={deliveryStatus}
          options={['', 'success', 'failed']}
          onChange={setDeliveryStatus}
          onRefresh={() => void load()}
          busy={busy}
        />
        <div className="admin-table-wrap">
          <table className="admin-table">
            <thead>
              <tr>
                <th>用户</th>
                <th>类型</th>
                <th>状态</th>
                <th>错误/回执</th>
                <th>时间</th>
              </tr>
            </thead>
            <tbody>
              {deliveries.length === 0 ? (
                <tr><td colSpan={5} className="muted">暂无记录</td></tr>
              ) : (
                deliveries.map((delivery) => (
                  <tr key={delivery.id}>
                    <td>{userLabel(delivery)}</td>
                    <td>{delivery.digestType ?? (delivery.reminderId ? 'reminder' : '—')}</td>
                    <td className={statusClass(delivery.status)}>{delivery.status}</td>
                    <td>{delivery.errorMessage || delivery.errorCode || delivery.providerMessageId || '—'}</td>
                    <td>{dateLabel(delivery.createdAt)}</td>
                  </tr>
                ))
              )}
            </tbody>
          </table>
        </div>
      </section>
    </div>
  );
}

function Stat({ label, value }: { label: string; value: string | number }) {
  return (
    <div className="admin-stat-card">
      <div className="admin-stat-label">{label}</div>
      <div className="admin-stat-value">{value}</div>
    </div>
  );
}

function TableHead({
  title,
  value,
  options,
  onChange,
  onRefresh,
  busy,
}: {
  title: string;
  value: string;
  options: string[];
  onChange: (value: string) => void;
  onRefresh: () => void;
  busy: boolean;
}) {
  return (
    <div className="admin-card-head">
      <h2>{title}</h2>
      <div className="wechat-toolbar">
        <select value={value} onChange={(event) => onChange(event.target.value)}>
          {options.map((option) => (
            <option key={option || 'all'} value={option}>
              {option || '全部状态'}
            </option>
          ))}
        </select>
        <button type="button" className="ghost-btn" onClick={onRefresh} disabled={busy}>
          刷新
        </button>
      </div>
    </div>
  );
}
