import { useState, useCallback, useEffect, useMemo } from 'react';
import { Card, Row, Col, Statistic, Tag, List, Select, Badge, Typography, Space, Empty, Result, Descriptions, Button, Timeline } from 'antd';
import { AlertOutlined, CheckCircleOutlined } from '@ant-design/icons';
import { useVitalSSE } from '../../hooks/useVitalSSE';
import { usePermission } from '../../hooks/usePermission';
import { alertApi, type Alert } from '../../api/health/alerts';
import { PageContainer } from '../../components/PageContainer';
import { VITAL_CARD_METRICS } from '../../constants/health';
import { formatDateTime } from '../../utils/format';
import { translateAlertTitle, DEVICE_TYPE_OPTIONS } from '../../constants/health';

interface PatientAlertSummary {
  patient_id: string;
  patient_name: string;
  critical: number;
  high: number;
  medium: number;
  low: number;
  alerts: Alert[];
}

const SEVERITY_CONFIG: Record<string, { color: string; label: string }> = {
  critical: { color: 'red', label: '危急' },
  high: { color: 'volcano', label: '高危' },
  medium: { color: 'orange', label: '中等' },
  low: { color: 'default', label: '低危' },
};

function SeverityTag({ severity }: { severity: string }) {
  const cfg = SEVERITY_CONFIG[severity] ?? SEVERITY_CONFIG.low;
  return <Tag color={cfg.color}>{cfg.label}</Tag>;
}

const METRIC_LABEL: Record<string, { name: string; unit: string }> = {
  systolic_bp: { name: '收缩压', unit: 'mmHg' },
  diastolic_bp: { name: '舒张压', unit: 'mmHg' },
  heart_rate: { name: '心率', unit: '次/分' },
  blood_glucose: { name: '血糖', unit: 'mg/dL' },
  blood_oxygen: { name: '血氧', unit: '%' },
  temperature: { name: '体温', unit: '°C' },
  steps: { name: '步数', unit: '步' },
  weight: { name: '体重', unit: 'kg' },
};

const CONDITION_TYPE_LABEL: Record<string, string> = {
  single_threshold: '单次阈值',
  consecutive: '连续触发',
  trend: '趋势变化',
};

const DEVICE_GUIDANCE: Record<string, string[]> = {
  blood_pressure: ['建议立即核实患者血压', '检查是否按时服用降压药物', '如收缩压≥180或舒张压≥110，建议紧急就医'],
  blood_glucose: ['建议立即复查血糖', '询问近期饮食和用药情况', '如血糖>33.3 mmol/L 或 <2.8 mmol/L，建议紧急处理'],
  heart_rate: ['建议核实心率数据准确性', '询问是否有心悸、胸闷等症状', '心率>150或<40次/分时建议紧急处理'],
  blood_oxygen: ['建议核实血氧测量是否正确', '检查患者呼吸状况', '血氧<90%时建议立即给氧并就医'],
  temperature: ['建议复测体温确认', '检查是否有感染迹象', '体温>39.5°C或<35°C时建议紧急处理'],
};

function deviceTypeLabel(dt: string): string {
  return DEVICE_TYPE_OPTIONS.find((o) => o.value === dt)?.label ?? dt;
}

/** 根据 detail 中的 condition_params + actual_value 生成人类可读的触发原因描述 */
function buildAlertReason(detail: Record<string, unknown> | undefined): string {
  if (!detail) return '未知原因';

  // 兜底：如果有现成 message 就直接用
  if (typeof detail.message === 'string') return detail.message;
  if (typeof detail.description === 'string') return detail.description;

  const params = detail.condition_params;
  const conditionType = String(detail.condition_type ?? '');
  const deviceType = String(detail.device_type ?? '');
  const deviceLabel = deviceTypeLabel(deviceType);
  const actualValue = typeof detail.actual_value === 'number' ? detail.actual_value : null;

  if (!params || typeof params !== 'object') {
    return `${deviceLabel}监测触发告警`;
  }

  const p = params as Record<string, unknown>;
  const metric = typeof p.metric === 'string' ? p.metric : '';
  const metricInfo = METRIC_LABEL[metric];
  const metricName = metricInfo?.name ?? '';
  const metricUnit = metricInfo?.unit ?? '';
  const direction = String(p.direction ?? '');
  const threshold = p.value;

  if (conditionType === 'single_threshold') {
    if (metricName && threshold != null) {
      const dirText = direction === 'above' ? '超过' : '低于';
      const actualPart = actualValue != null ? `（当前 ${actualValue}${metricUnit ? ' ' + metricUnit : ''}）` : '';
      return `${deviceLabel} — ${metricName}${dirText}阈值 ${threshold}${metricUnit ? ' ' + metricUnit : ''}${actualPart}`;
    }
    if (threshold != null) {
      const dirText = direction === 'above' ? '超过' : '低于';
      const actualPart = actualValue != null ? `（当前 ${actualValue}）` : '';
      return `${deviceLabel}${dirText}阈值 ${threshold}${actualPart}`;
    }
    return `${deviceLabel}单次阈值触发`;
  }

  if (conditionType === 'consecutive') {
    const count = p.count ?? '?';
    const window = p.window_hours;
    const windowText = window ? `（${window}小时内）` : '';
    if (metricName && threshold != null) {
      const dirText = direction === 'above' ? '偏高' : '偏低';
      const actualPart = actualValue != null ? `，最近一次 ${actualValue}${metricUnit ? ' ' + metricUnit : ''}` : '';
      return `${deviceLabel} — ${metricName}连续 ${count} 次${dirText}（阈值 ${threshold}${metricUnit ? ' ' + metricUnit : ''}）${actualPart}${windowText}`;
    }
    return `${deviceLabel}连续 ${count} 次异常${windowText}`;
  }

  if (conditionType === 'trend') {
    const delta = p.delta;
    const window = p.window_hours ?? 168;
    const dirText = direction === 'up' ? '上升' : '下降';
    const trendStart = typeof detail.trend_start_value === 'number' ? detail.trend_start_value : null;
    const trendEnd = typeof detail.trend_end_value === 'number' ? detail.trend_end_value : null;
    if (trendStart != null && trendEnd != null) {
      return `${deviceLabel} — ${metricName || deviceLabel}在 ${window} 小时内从 ${trendStart}${metricUnit ? ' ' + metricUnit : ''}${dirText}至 ${trendEnd}${metricUnit ? ' ' + metricUnit : ''}（变化 ${Math.abs(trendEnd - trendStart).toFixed(1)}）`;
    }
    if (delta != null) {
      return `${deviceLabel} — ${metricName || deviceLabel}在 ${window} 小时内${dirText}幅度超过 ${delta}${metricUnit ? ' ' + metricUnit : ''}`;
    }
    return `${deviceLabel}趋势异常（${dirText}）`;
  }

  return `${deviceLabel}${CONDITION_TYPE_LABEL[conditionType] ?? '异常'}触发`;
}

/** 根据严重度升级信息生成补充说明 */
function buildSeverityNote(detail: Record<string, unknown> | undefined): string | null {
  if (!detail) return null;
  const original = detail.original_severity;
  const escalated = detail.escalated_to;
  if (typeof original === 'string' && typeof escalated === 'string' && original !== escalated) {
    const o = SEVERITY_CONFIG[original]?.label ?? original;
    const e = SEVERITY_CONFIG[escalated]?.label ?? escalated;
    return `（因该患者多次告警，严重度已由「${o}」升级为「${e}」）`;
  }
  return null;
}

/** 根据设备类型返回处理建议 */
function getGuidance(deviceType: string | undefined): string[] {
  if (!deviceType) return [];
  return DEVICE_GUIDANCE[deviceType] ?? [];
}

export default function RealtimeMonitor() {
  const { hasPermission } = usePermission('health.alerts.list');
  const [, setAlerts] = useState<Alert[]>([]);
  const [loading, setLoading] = useState(true);
  const [selectedPatientId, setSelectedPatientId] = useState<string | null>(null);
  const [alertSummary, setAlertSummary] = useState<PatientAlertSummary[]>([]);

  const { connected, patientVitals } = useVitalSSE({ enabled: true });

  const fetchAlerts = useCallback(async () => {
    try {
      setLoading(true);
      const result = await alertApi.list({ page: 1, page_size: 200, status: 'pending' });
      setAlerts(result.data);

      const summaryMap = new Map<string, PatientAlertSummary>();
      for (const alert of result.data) {
        const existing = summaryMap.get(alert.patient_id) ?? {
          patient_id: alert.patient_id,
          patient_name: alert.patient_name ?? '未知患者',
          critical: 0, high: 0, medium: 0, low: 0,
          alerts: [],
        };
        const sev = alert.severity;
        if (sev === 'critical') existing.critical++;
        else if (sev === 'high') existing.high++;
        else if (sev === 'medium') existing.medium++;
        else existing.low++;
        existing.alerts.push(alert);
        if (alert.patient_name) existing.patient_name = alert.patient_name;
        summaryMap.set(alert.patient_id, existing);
      }

      const summaries = Array.from(summaryMap.values());
      for (const s of summaries) {
        s.alerts.sort((a, b) => {
          const order: Record<string, number> = { critical: 0, high: 1, medium: 2, low: 3 };
          return (order[a.severity] ?? 4) - (order[b.severity] ?? 4);
        });
      }
      setAlertSummary(summaries);
    } catch {
      // 静默降级
    } finally {
      setLoading(false);
    }
  }, []);

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

  const sortedPatients = useMemo(() =>
    [...alertSummary].sort((a, b) => {
      const score = (s: PatientAlertSummary) => s.critical * 4 + s.high * 3 + s.medium * 2 + s.low;
      return score(b) - score(a);
    }),
  [alertSummary]);

  const totalCritical = alertSummary.reduce((s, a) => s + a.critical, 0);
  const totalHigh = alertSummary.reduce((s, a) => s + a.high, 0);
  const totalMedium = alertSummary.reduce((s, a) => s + a.medium, 0);
  const totalLow = alertSummary.reduce((s, a) => s + a.low, 0);

  const selectedPatient = selectedPatientId
    ? sortedPatients.find((p) => p.patient_id === selectedPatientId)
    : null;

  const handleAcknowledge = useCallback(async (alert: Alert) => {
    try {
      await alertApi.acknowledge(alert.id, alert.version);
      fetchAlerts();
    } catch {
      // 静默降级
    }
  }, [fetchAlerts]);

  if (!hasPermission) {
    return <Result status="403" title="权限不足" subTitle="您没有访问实时体征监控的权限" />;
  }

  return (
    <PageContainer
      title="实时体征监控"
      actions={
        <Space>
          <Badge status={connected ? 'success' : 'error'} text={connected ? '已连接' : '断开'} />
          <Select
            placeholder="筛选患者"
            allowClear
            showSearch
            optionFilterProp="label"
            style={{ width: 220 }}
            value={selectedPatientId}
            onChange={(v) => setSelectedPatientId(v ?? null)}
            options={sortedPatients.map((p) => ({
              value: p.patient_id,
              label: p.patient_name,
            }))}
          />
        </Space>
      }
    >
      <Row gutter={16} style={{ marginBottom: 16 }}>
        <Col span={6}><Card><Statistic title="危急" value={totalCritical} styles={{ content: { color: '#cf1322' } }} prefix={<AlertOutlined />} /></Card></Col>
        <Col span={6}><Card><Statistic title="高危" value={totalHigh} styles={{ content: { color: '#ff4d4f' } }} prefix={<AlertOutlined />} /></Card></Col>
        <Col span={6}><Card><Statistic title="中等" value={totalMedium} styles={{ content: { color: '#fa8c16' } }} prefix={<AlertOutlined />} /></Card></Col>
        <Col span={6}><Card><Statistic title="低危" value={totalLow} styles={{ content: { color: '#8c8c8c' } }} prefix={<AlertOutlined />} /></Card></Col>
      </Row>

      <Row gutter={16}>
        <Col span={selectedPatient ? 12 : 24}>
          <Card title={`患者列表（${sortedPatients.length} 人有活跃告警）`} loading={loading}>
            {sortedPatients.length === 0 ? (
              <Empty description="暂无活跃告警" />
            ) : (
              <List
                dataSource={selectedPatientId ? sortedPatients.filter((p) => p.patient_id === selectedPatientId) : sortedPatients}
                renderItem={(item) => {
                  const vitalKeys = Array.from(patientVitals.entries())
                    .filter(([key]) => key.startsWith(item.patient_id));
                  const latestVitals = vitalKeys.map(([, v]) => v);
                  const isSelected = selectedPatientId === item.patient_id;

                  return (
                    <List.Item
                      style={{
                        cursor: 'pointer',
                        padding: '12px 16px',
                        background: isSelected ? 'var(--ant-color-bg-container)' : undefined,
                        borderLeft: isSelected ? '3px solid var(--ant-color-primary)' : '3px solid transparent',
                      }}
                      onClick={() => setSelectedPatientId(
                        isSelected ? null : item.patient_id,
                      )}
                    >
                      <List.Item.Meta
                        title={
                          <Space>
                            <Typography.Text strong>{item.patient_name}</Typography.Text>
                            <Typography.Text type="secondary" style={{ fontSize: 12 }}>
                              ({item.patient_id.slice(0, 8)}...)
                            </Typography.Text>
                            {item.critical > 0 && <Tag color="red">{item.critical} 危急</Tag>}
                            {item.high > 0 && <Tag color="volcano">{item.high} 高危</Tag>}
                            {item.medium > 0 && <Tag color="orange">{item.medium} 中等</Tag>}
                            {item.low > 0 && <Tag color="default">{item.low} 低危</Tag>}
                          </Space>
                        }
                        description={
                          <Space wrap>
                            {latestVitals.map((v) => {
                              const metric = VITAL_CARD_METRICS.find((m) => m.key === v.device_type);
                              if (!metric) return null;
                              return (
                                <Tag key={v.device_type} color="blue">
                                  {metric.label}: {v.latest_value ?? '-'} {metric.unit}
                                </Tag>
                              );
                            })}
                            {latestVitals.length === 0 && <Typography.Text type="secondary">暂无实时数据</Typography.Text>}
                          </Space>
                        }
                      />
                    </List.Item>
                  );
                }}
              />
            )}
          </Card>
        </Col>

        {selectedPatient && (
          <Col span={12}>
            <Card
              title={`${selectedPatient.patient_name} — 告警详情`}
              extra={
                <Button size="small" onClick={() => setSelectedPatientId(null)}>
                  关闭
                </Button>
              }
            >
              <Descriptions column={2} size="small" style={{ marginBottom: 16 }}>
                <Descriptions.Item label="患者ID">
                  <Typography.Text copyable style={{ fontSize: 12 }}>{selectedPatient.patient_id}</Typography.Text>
                </Descriptions.Item>
                <Descriptions.Item label="活跃告警">
                  <Space>
                    {selectedPatient.critical > 0 && <Tag color="red">{selectedPatient.critical} 危急</Tag>}
                    {selectedPatient.high > 0 && <Tag color="volcano">{selectedPatient.high} 高危</Tag>}
                    {selectedPatient.medium > 0 && <Tag color="orange">{selectedPatient.medium} 中等</Tag>}
                    {selectedPatient.low > 0 && <Tag color="default">{selectedPatient.low} 低危</Tag>}
                  </Space>
                </Descriptions.Item>
              </Descriptions>

              <Typography.Text strong style={{ display: 'block', marginBottom: 12 }}>
                告警时间线
              </Typography.Text>
              <Timeline
                items={selectedPatient.alerts.map((alert) => {
                  const detail = alert.detail as Record<string, unknown> | undefined;
                  const reason = buildAlertReason(detail);
                  const severityNote = buildSeverityNote(detail);
                  const guidance = getGuidance(detail?.device_type as string | undefined);

                  return {
                    color: SEVERITY_CONFIG[alert.severity]?.color ?? 'gray',
                    children: (
                      <div style={{ paddingBottom: 12 }}>
                        <Space style={{ marginBottom: 4 }}>
                          <SeverityTag severity={alert.severity} />
                          <Typography.Text strong>{translateAlertTitle(alert.title)}</Typography.Text>
                        </Space>
                        <div>
                          <Typography.Text type="secondary" style={{ fontSize: 12 }}>
                            {formatDateTime(alert.created_at)}
                          </Typography.Text>
                        </div>
                        <div style={{ marginTop: 6, padding: '6px 10px', background: 'var(--ant-color-fill-quaternary)', borderRadius: 6 }}>
                          <Typography.Text type="secondary">触发原因：</Typography.Text>
                          <Typography.Text>{reason}</Typography.Text>
                          {severityNote && (
                            <div style={{ marginTop: 2 }}>
                              <Typography.Text type="warning" style={{ fontSize: 12 }}>{severityNote}</Typography.Text>
                            </div>
                          )}
                        </div>
                        {guidance.length > 0 && (
                          <div style={{ marginTop: 6 }}>
                            <Typography.Text type="secondary" style={{ fontSize: 12 }}>处理建议：</Typography.Text>
                            <ul style={{ margin: '2px 0 0 16px', padding: 0 }}>
                              {guidance.map((g, i) => (
                                <li key={i}><Typography.Text style={{ fontSize: 12 }}>{g}</Typography.Text></li>
                              ))}
                            </ul>
                          </div>
                        )}
                        <div style={{ marginTop: 6 }}>
                          <Button
                            type="link"
                            size="small"
                            icon={<CheckCircleOutlined />}
                            onClick={(e) => { e.stopPropagation(); handleAcknowledge(alert); }}
                          >
                            确认已处理
                          </Button>
                        </div>
                      </div>
                    ),
                  };
                })}
              />
            </Card>
          </Col>
        )}
      </Row>
    </PageContainer>
  );
}
