import { useCallback, useEffect, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import { api, ApiError } from '../api/client';
import { useToast } from '../components/Toast';
import { useAutoRefresh } from '../lib/useAutoRefresh';
import type { PatientSummary, RiskLevel } from '../api/types';
import { riskBadgeClass, riskLabel } from '../lib/format';

const RISK_ORDER: Record<RiskLevel, number> = { high: 0, medium: 1, low: 2 };
const PAGE_SIZE = 10;

export function WorklistPage(): JSX.Element {
  const navigate = useNavigate();
  const { show } = useToast();
  const [patients, setPatients] = useState<PatientSummary[]>([]);
  const [loading, setLoading] = useState(true);
  const [query, setQuery] = useState('');
  const [riskFilter, setRiskFilter] = useState<'all' | RiskLevel>('all');
  const [page, setPage] = useState(1);

  const load = useCallback(
    (silent = false) => {
      if (!silent) setLoading(true);
      api
        .listPatients()
        .then(setPatients)
        .catch((err) => {
          if (!silent) show(err instanceof ApiError ? err.message : '加载孕妇列表失败');
        })
        .finally(() => setLoading(false));
    },
    [show],
  );

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

  // 多端一致：新建档/风险变化近实时反映到工作列表
  useAutoRefresh(() => load(true));

  const rows = useMemo(() => {
    const q = query.trim();
    return patients
      .filter((p) => (riskFilter === 'all' ? true : p.initialRiskLevel === riskFilter))
      .filter((p) => (q ? p.name.includes(q) || (p.patientNo ?? '').toUpperCase().includes(q.toUpperCase()) : true))
      .sort((a, b) => RISK_ORDER[a.initialRiskLevel] - RISK_ORDER[b.initialRiskLevel]);
  }, [patients, query, riskFilter]);

  // 过滤条件变化时回到第一页
  useEffect(() => {
    setPage(1);
  }, [query, riskFilter]);

  const totalPages = Math.max(1, Math.ceil(rows.length / PAGE_SIZE));
  const currentPage = Math.min(page, totalPages);
  const pageRows = rows.slice((currentPage - 1) * PAGE_SIZE, currentPage * PAGE_SIZE);

  const stats = useMemo(() => {
    return {
      total: patients.length,
      high: patients.filter((p) => p.initialRiskLevel === 'high').length,
      medium: patients.filter((p) => p.initialRiskLevel === 'medium').length,
    };
  }, [patients]);

  return (
    <div className="stack">
      <div className="spread">
        <div>
          <h1 style={{ fontSize: 'var(--font-xxl)' }}>工作列表</h1>
          <p className="muted">在管孕妇 {stats.total} 人 · 高风险 {stats.high} · 中风险 {stats.medium}</p>
        </div>
      </div>

      <div className="card">
        <div className="row" style={{ marginBottom: 'var(--space-4)' }}>
          <input
            placeholder="搜索姓名 / 编号…"
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            style={{ maxWidth: 260, padding: '8px 12px', borderRadius: 'var(--radius-md)', border: '1px solid var(--color-border-strong)' }}
          />
          <select
            value={riskFilter}
            onChange={(e) => setRiskFilter(e.target.value as 'all' | RiskLevel)}
            style={{ padding: '8px 12px', borderRadius: 'var(--radius-md)', border: '1px solid var(--color-border-strong)' }}
          >
            <option value="all">全部风险</option>
            <option value="high">高风险</option>
            <option value="medium">中风险</option>
            <option value="low">低风险</option>
          </select>
        </div>

        {loading ? (
          <p className="empty">加载中…</p>
        ) : rows.length === 0 ? (
          <p className="empty">暂无匹配的孕妇。建档后将出现在此列表。</p>
        ) : (
          <>
            <table className="table">
              <thead>
                <tr>
                  <th>编号</th>
                  <th>姓名</th>
                  <th>年龄</th>
                  <th>孕周</th>
                  <th>分期</th>
                  <th>初始风险</th>
                  <th>风险因素</th>
                </tr>
              </thead>
              <tbody>
                {pageRows.map((p) => (
                  <tr key={p.id} className="clickable" onClick={() => navigate(`/patients/${p.id}`)}>
                    <td style={{ fontFamily: 'ui-monospace, Menlo, monospace', fontSize: 'var(--font-sm)' }}>
                      {p.patientNo || '—'}
                    </td>
                    <td style={{ fontWeight: 600 }}>{p.name}</td>
                    <td>{p.age}</td>
                    <td>
                      {p.gestationalWeeks}周{p.gestationalDays}天
                    </td>
                    <td>{trimesterLabel(p.trimester)}</td>
                    <td>
                      <span className={`badge ${riskBadgeClass(p.initialRiskLevel)}`}>
                        {riskLabel(p.initialRiskLevel)}
                      </span>
                    </td>
                    <td className="muted">{p.initialRiskFactors.join('、') || '—'}</td>
                  </tr>
                ))}
              </tbody>
            </table>

            <div className="pager">
              <span className="muted">
                共 {rows.length} 条 · 第 {currentPage}/{totalPages} 页
              </span>
              <div className="pager__btns">
                <button
                  className="btn btn-ghost btn-sm"
                  onClick={() => setPage((p) => Math.max(1, p - 1))}
                  disabled={currentPage <= 1}
                  type="button"
                >
                  <ChevronLeft size={16} strokeWidth={1.9} /> 上一页
                </button>
                <button
                  className="btn btn-ghost btn-sm"
                  onClick={() => setPage((p) => Math.min(totalPages, p + 1))}
                  disabled={currentPage >= totalPages}
                  type="button"
                >
                  下一页 <ChevronRight size={16} strokeWidth={1.9} />
                </button>
              </div>
            </div>
          </>
        )}
      </div>
    </div>
  );
}

function trimesterLabel(t: string): string {
  return { first: '孕早期', second: '孕中期', third: '孕晚期' }[t] ?? t;
}
