import React, { useMemo, useState } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Sparkline } from '../components/charts';
import { ErrBox, Loading, PriorityCard, Screen, SearchInput, Sec } from '../components/ui';
import { load } from '../lib/api';
import { cap, fmtD, fmtDY } from '../lib/format';
import { shapeBiomarkers } from '../lib/shape';
import { C } from '../lib/theme';
import type { BiomarkersResponse, DrawsResponse, HealthMeta, MarkerGroup } from '../lib/types';
import { useLoad } from '../lib/use-load';
import { useWindowDimensions } from 'react-native';

function MarkerCard({ m, sparkW }: { m: MarkerGroup; sparkW: number }) {
  const L = m.latest;
  return (
    <View style={[s.card, L.flagged && { borderColor: 'rgba(255,69,58,0.35)' }]}>
      <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-start', gap: 8 }}>
        <View style={{ flex: 1 }}>
          <Text style={{ fontSize: 12, color: C.muted, textTransform: 'capitalize' }}>
            {cap(m.name)}
          </Text>
          <View style={{ flexDirection: 'row', alignItems: 'baseline', gap: 5, marginTop: 2 }}>
            <Text style={{ fontSize: 22, fontWeight: '300', letterSpacing: -0.5, color: C.text }}>
              {String(L.value)}
            </Text>
            <Text style={{ fontSize: 11, color: C.muted }}>{L.unit || ''}</Text>
          </View>
          <Text style={{ fontSize: 10.5, color: C.dim, marginTop: 2 }}>
            {L.reference_range ? `ref ${L.reference_range} · ` : ''}
            {fmtDY(L.collected)} · {cap(L.panel)}
          </Text>
        </View>
        <View style={[s.status, L.flagged ? s.statusFlag : s.statusOk]}>
          <Text style={{
            fontSize: 9.5, fontWeight: '700', letterSpacing: 0.4,
            color: L.flagged ? C.red : C.green,
          }}>
            {L.flagged ? 'FLAG' : 'OK'}
          </Text>
        </View>
      </View>
      <Sparkline pts={m.series} flagged={L.flagged} width={sparkW} />
    </View>
  );
}

export default function Blood() {
  const { width } = useWindowDimensions();
  const sparkW = Math.min(608, width - 32) - 28;
  const [q, setQ] = useState('');
  const { data, err, loading, refresh } = useLoad(() =>
    Promise.all([
      load<BiomarkersResponse>('biomarkers'),
      load<HealthMeta>('meta'),
      load<DrawsResponse>('draws'),
    ]),
  );

  const marks = useMemo(() => (data ? shapeBiomarkers(data[0]) : []), [data]);

  let body: React.ReactNode = null;
  if (loading && !data) body = <Loading />;
  else if (err) body = <ErrBox msg={err} />;
  else if (data) {
    const [bio, meta, draws] = data;
    const latestDraw = bio.biomarkers.reduce((m, b) => (b.collected > m ? b.collected : m), '');
    const flaggedNow = marks.filter((m) => m.latest.flagged);
    const ql = q.trim().toLowerCase();
    const subset = ql
      ? marks.filter((m) => cap(m.name).toLowerCase().includes(ql) || m.panel.includes(ql))
      : marks;
    const flagged = subset.filter((m) => m.latest.flagged);
    const rest = subset.filter((m) => !m.latest.flagged);

    body = (
      <>
        <View style={{ flexDirection: 'row', flexWrap: 'wrap', gap: 8, marginBottom: 4 }}>
          <Pill num={String(marks.length)} lbl="Markers" />
          <Pill num={String(draws.draws.length)} lbl="Draws" />
          <Pill num={String(flaggedNow.length)} lbl="Flagged" color={flaggedNow.length ? C.red : C.green} />
          <Pill num={fmtD(latestDraw)} lbl="Last draw" small />
        </View>

        {meta.current_priorities?.length ? (
          <>
            <Sec title="Priorities" />
            {meta.current_priorities.map((p, i) => (
              <PriorityCard key={p.title} p={p} rank={i + 1} />
            ))}
          </>
        ) : null}

        <Sec title="All markers" count={marks.length} />
        <SearchInput value={q} onChange={setQ} placeholder="Search markers…" />
        {flagged.length ? (
          <>
            <Sec title="Flagged" count={flagged.length} />
            {flagged.map((m) => <MarkerCard key={m.name} m={m} sparkW={sparkW} />)}
          </>
        ) : null}
        {rest.length ? (
          <>
            {flagged.length ? <Sec title="In range" count={rest.length} /> : null}
            {rest.map((m) => <MarkerCard key={m.name} m={m} sparkW={sparkW} />)}
          </>
        ) : null}
        {!subset.length ? (
          <Text style={{ color: C.muted, fontSize: 13, textAlign: 'center', padding: 24 }}>
            No markers match.
          </Text>
        ) : null}

        {meta.tests_never_done?.length ? (
          <>
            <Sec title="Never tested" count={meta.tests_never_done.length} />
            {meta.tests_never_done.map((t) => (
              <View key={t} style={s.missing}>
                <Text style={{ color: C.muted, fontSize: 12 }}>○  {t}</Text>
              </View>
            ))}
          </>
        ) : null}
      </>
    );
  }

  return <Screen onRefresh={refresh}>{body}</Screen>;
}

function Pill({ num, lbl, color, small }: { num: string; lbl: string; color?: string; small?: boolean }) {
  return (
    <View style={s.pill}>
      <Text style={{
        fontSize: small ? 14 : 19, fontWeight: '600', color: color || C.text,
        paddingTop: small ? 5 : 0,
      }}>
        {num}
      </Text>
      <Text style={{ fontSize: 10, color: C.muted, letterSpacing: 0.5 }}>{lbl.toUpperCase()}</Text>
    </View>
  );
}

const s = StyleSheet.create({
  card: {
    backgroundColor: C.surface, borderWidth: 1, borderColor: C.border, borderRadius: 12,
    paddingVertical: 12, paddingHorizontal: 14, marginBottom: 8,
  },
  status: { paddingVertical: 2, paddingHorizontal: 8, borderRadius: 10 },
  statusOk: { backgroundColor: C.greenDim },
  statusFlag: { backgroundColor: C.redDim },
  pill: {
    borderWidth: 1, borderColor: C.border, borderRadius: 10, paddingVertical: 8,
    paddingHorizontal: 14, backgroundColor: C.surface,
  },
  missing: {
    borderWidth: 1, borderStyle: 'dashed', borderColor: C.border, borderRadius: 10,
    paddingVertical: 9, paddingHorizontal: 13, backgroundColor: C.surface, marginBottom: 6,
  },
});
