import { useEffect, useState } from 'react';
import { Activity } from 'lucide-react';
import { statsApi, type InpatientClinicalResponse } from '@/services/api';
import { Card, LoadingState, EmptyState } from '@/components/ui';
import { ErrorBanner } from '@/components/ErrorBanner';
import { TESTIDS } from '@/utils/testids';
import { ClinicalKpiRow } from '@/components/clinical/ClinicalKpiRow';
import { HistogramChart } from '@/components/clinical/HistogramChart';
import { BoxPlotRows, type BoxRow } from '@/components/clinical/BoxPlotRows';
import { DonutChart, type DonutSlice } from '@/components/clinical/DonutChart';
import { CLINICAL_COLORS } from '@/components/clinical/chartColors';

/** 数据是否完全为空（KPI 0 人次且各序列均空）。 */
function isEmpty(d: InpatientClinicalResponse): boolean {
  return (
    (!d.kpis || d.kpis.total_admissions === 0) &&
    (d.los_histogram?.length ?? 0) === 0 &&
    (d.outcome_counts?.length ?? 0) === 0
  );
}

export function ClinicalAnalysis() {
  const [data, setData] = useState<InpatientClinicalResponse | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    let cancelled = false;

    const fetchData = async () => {
      setIsLoading(true);
      setError(null);
      try {
        const res = await statsApi.getInpatientClinical();
        if (cancelled) return;
        setData(res);
      } catch {
        if (cancelled) return;
        setError('住院临床数据加载失败');
      } finally {
        if (!cancelled) setIsLoading(false);
      }
    };

    fetchData();

    return () => {
      cancelled = true;
    };
  }, []);

  const header = (
    <div>
      <h1 className="font-display text-[18px] font-semibold mb-1 flex items-center gap-2">
        <Activity className="w-5 h-5 text-primary" />
        住院临床分析
      </h1>
      <p className="text-[12px] text-text-secondary">
        住院天数、出院结局、入院途径与年龄别 BMI 等临床特征分析
      </p>
    </div>
  );

  if (isLoading) {
    return (
      <div data-testid={TESTIDS.pageClinical} className="flex flex-col h-full overflow-auto p-6 space-y-6">
        {header}
        <LoadingState label="正在加载住院临床数据…" />
      </div>
    );
  }

  if (error || !data) {
    return (
      <div data-testid={TESTIDS.pageClinical} className="flex flex-col h-full overflow-auto p-6 space-y-6">
        {header}
        <ErrorBanner
          error={error ?? '住院临床数据加载失败'}
          onRetry={() => window.location.reload()}
          onDismiss={() => setError(null)}
        />
      </div>
    );
  }

  if (isEmpty(data)) {
    return (
      <div data-testid={TESTIDS.pageClinical} className="flex flex-col h-full overflow-auto p-6 space-y-6">
        {header}
        <EmptyState title="暂无住院临床数据" description="当前筛选范围内没有可用的住院记录。" />
      </div>
    );
  }

  // 出院结局：治愈/好转在前（按严重程度排序展示更直观）。
  const outcomeSlices: DonutSlice[] = (data.outcome_counts ?? []).map((o) => ({
    name: o.outcome,
    value: o.count,
  }));
  const routeSlices: DonutSlice[] = (data.admission_route_counts ?? []).map((r) => ({
    name: r.route,
    value: r.count,
  }));

  const losBox: BoxRow[] = (data.los_by_disease ?? []).map((d) => ({
    label: d.diagnosis,
    p25: d.p25,
    median: d.median,
    p75: d.p75,
    n: d.n,
  }));
  const bmiBox: BoxRow[] = (data.bmi_by_age_band ?? []).map((d) => ({
    label: d.age_band,
    p25: d.p25,
    median: d.median,
    p75: d.p75,
    n: d.n,
  }));

  return (
    <div
      data-testid={TESTIDS.pageClinical}
      className="flex flex-col h-full overflow-auto"
    >
      <div className="p-6 space-y-6">
        {header}

        {/* KPI 行 */}
        <ClinicalKpiRow kpis={data.kpis} />

        {/* 住院天数：分布 + 各病种箱线 */}
        <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
          <Card title="住院天数分布">
            <HistogramChart data={data.los_histogram ?? []} color={CLINICAL_COLORS.los} countLabel="人次" />
          </Card>
          <Card title="各病种住院天数（P25–中位–P75）">
            <BoxPlotRows rows={losBox} unit="天" />
          </Card>
        </div>

        {/* 出院结局 + 入院途径 双环 */}
        <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
          <Card title="出院结局构成">
            <DonutChart data={outcomeSlices} colorMap={CLINICAL_COLORS.outcome} />
          </Card>
          <Card title="入院途径构成">
            <DonutChart data={routeSlices} />
          </Card>
        </div>

        {/* 年龄别 BMI 箱线 */}
        <Card title="年龄别 BMI（P25–中位–P75）">
          <BoxPlotRows rows={bmiBox} />
        </Card>
      </div>
    </div>
  );
}
