'use client';

import { useEffect, useState } from 'react';
import {
  Sparkles,
  AlertTriangle,
  Pill,
  Activity,
  History,
  Stethoscope,
  Info,
} from 'lucide-react';
import { DenseCard, StatusPill } from '@sehat/ui';

/**
 * Shape of the F4 endpoint payload — kept locally so the component is
 * self-contained and not blocked by api-types updates from other agents.
 */
export interface PreConsultSummaryPayload {
  patient: {
    userId: string;
    firstName: string | null;
    lastName: string | null;
    age: number | null;
    gender: string | null;
    locale: string | null;
    timezone: string | null;
  };
  visit: {
    specialtyName: string | null;
    scheduledAt: string;
    urgency: string | null;
    symptoms: string | null;
  };
  activeConditions: Array<{
    name: string;
    icdCode?: string | null;
    onsetDate?: string | null;
    status?: string | null;
  }>;
  activeAllergies: Array<{
    allergen: string;
    severity?: string | null;
    reaction?: string | null;
  }>;
  currentMedications: Array<{
    name: string;
    dose?: string | null;
    frequency?: string | null;
    startDate?: string | null;
  }>;
  recentAppointments: Array<{
    id: string;
    scheduledAt: string;
    status: string;
    specialty: string | null;
    doctorName: string | null;
  }>;
  lastVisitWithThisDoctor: {
    id: string;
    scheduledAt: string;
    summary: string | null;
  } | null;
  recentTriage: {
    urgency: string | null;
    recommendedSpecialty: string | null;
    redFlags: string[];
    summary: string | null;
  } | null;
  narrative: string;
}

interface PreConsultSummaryProps {
  appointmentId: string;
}

type FetchState =
  | { status: 'loading' }
  | { status: 'ready'; data: PreConsultSummaryPayload }
  | { status: 'unavailable' }
  | { status: 'error'; message: string };

/**
 * F4 — Pre-consult summary panel.
 *
 * Calls `/api/v2/appointments/:id/pre-consult-summary` once on mount and
 * surfaces a 2-3 paragraph narrative plus quick-glance chip rows for the
 * doctor right before a visit. Endpoint may not exist yet — we render a
 * graceful "not yet available" hint on 404 and do not block the page.
 */
export function PreConsultSummary({ appointmentId }: PreConsultSummaryProps) {
  const [state, setState] = useState<FetchState>({ status: 'loading' });

  useEffect(() => {
    let cancelled = false;
    setState({ status: 'loading' });
    void (async () => {
      try {
        // We hit the local Next.js proxy at /api/... — `v2` is not in the
        // current rewrite layer, so we use the same prefix as the other
        // endpoints in this app.
        const res = await fetch(
          `/api/appointments/${appointmentId}/pre-consult-summary`,
          { cache: 'no-store' },
        );
        if (cancelled) return;
        if (res.status === 404) {
          setState({ status: 'unavailable' });
          return;
        }
        if (!res.ok) {
          const text = await res
            .json()
            .then((j) => (j && typeof j.message === 'string' ? j.message : null))
            .catch(() => null);
          setState({
            status: 'error',
            message: text ?? `Request failed (${res.status})`,
          });
          return;
        }
        const data = (await res.json()) as PreConsultSummaryPayload;
        setState({ status: 'ready', data });
      } catch (e) {
        if (!cancelled) {
          setState({
            status: 'error',
            message: e instanceof Error ? e.message : 'Network error',
          });
        }
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [appointmentId]);

  if (state.status === 'loading') {
    return (
      <DenseCard
        title={
          <span className="flex items-center gap-1.5">
            <Sparkles className="h-4 w-4 text-brand-500" /> Pre-consult summary
          </span>
        }
      >
        <div className="h-16 animate-pulse rounded bg-denseSurface-bg" />
      </DenseCard>
    );
  }

  if (state.status === 'unavailable') {
    return (
      <DenseCard
        title={
          <span className="flex items-center gap-1.5 text-ink-2">
            <Sparkles className="h-4 w-4 text-ink-3" /> Pre-consult summary
          </span>
        }
      >
        <div className="flex items-start gap-2 rounded-md border border-dashed border-denseSurface-border bg-denseSurface-bg p-3 text-xs text-ink-2">
          <Info className="mt-0.5 h-3.5 w-3.5 flex-shrink-0 text-ink-3" />
          <span>
            Pre-consult summary not yet available for this appointment.
          </span>
        </div>
      </DenseCard>
    );
  }

  if (state.status === 'error') {
    return (
      <DenseCard
        title={
          <span className="flex items-center gap-1.5">
            <Sparkles className="h-4 w-4 text-brand-500" /> Pre-consult summary
          </span>
        }
      >
        <div className="flex items-start gap-2 rounded-md border border-warning-500/30 bg-warning-500/5 p-2 text-xs text-warning-500">
          <AlertTriangle className="mt-0.5 h-3.5 w-3.5 flex-shrink-0" />
          <span>{state.message}</span>
        </div>
      </DenseCard>
    );
  }

  const { data } = state;
  const narrativeParas = data.narrative
    .split(/\n{2,}/)
    .map((p) => p.trim())
    .filter(Boolean);

  return (
    <DenseCard
      title={
        <span className="flex items-center gap-1.5">
          <Sparkles className="h-4 w-4 text-brand-500" /> Pre-consult summary
        </span>
      }
      actions={
        data.visit.urgency ? (
          <StatusPill tone={urgencyTone(data.visit.urgency)}>
            {data.visit.urgency}
          </StatusPill>
        ) : null
      }
    >
      <div className="space-y-3">
        {/* Narrative — the most important content, displayed first. */}
        {narrativeParas.length > 0 ? (
          <div className="space-y-2 rounded-md border border-brand-500/20 bg-brand-500/5 p-3">
            {narrativeParas.map((p, i) => (
              <p key={i} className="text-sm leading-relaxed text-ink-1">
                {p}
              </p>
            ))}
          </div>
        ) : null}

        {/* Chip rows */}
        <div className="grid grid-cols-1 gap-2 md:grid-cols-3">
          <ChipRow
            label="Active conditions"
            icon={<Activity className="h-3.5 w-3.5" />}
            items={data.activeConditions.map((c) => c.name)}
            chipTone="neutral"
            emptyHint="None recorded"
          />
          <ChipRow
            label="Allergies"
            icon={<AlertTriangle className="h-3.5 w-3.5" />}
            items={data.activeAllergies.map((a) =>
              a.severity ? `${a.allergen} (${a.severity})` : a.allergen,
            )}
            chipTone="danger"
            emptyHint="No known allergies"
          />
          <ChipRow
            label="Current meds"
            icon={<Pill className="h-3.5 w-3.5" />}
            items={data.currentMedications.map((m) =>
              m.dose ? `${m.name} ${m.dose}` : m.name,
            )}
            chipTone="brand"
            emptyHint="None recorded"
          />
        </div>

        {/* Last visit + recent triage cards */}
        {(data.lastVisitWithThisDoctor || data.recentTriage) ? (
          <div className="grid grid-cols-1 gap-2 md:grid-cols-2">
            {data.lastVisitWithThisDoctor ? (
              <MiniCard
                label="Last visit with you"
                icon={<History className="h-3.5 w-3.5" />}
              >
                <p className="font-mono text-[11px] text-ink-3">
                  {new Date(
                    data.lastVisitWithThisDoctor.scheduledAt,
                  ).toLocaleDateString(undefined, {
                    day: 'numeric',
                    month: 'short',
                    year: 'numeric',
                  })}
                </p>
                {data.lastVisitWithThisDoctor.summary ? (
                  <p className="mt-1 line-clamp-3 text-xs text-ink-1">
                    {data.lastVisitWithThisDoctor.summary}
                  </p>
                ) : (
                  <p className="mt-1 text-xs italic text-ink-3">
                    No summary recorded.
                  </p>
                )}
              </MiniCard>
            ) : null}
            {data.recentTriage ? (
              <MiniCard
                label="Recent triage"
                icon={<Stethoscope className="h-3.5 w-3.5" />}
              >
                <div className="flex flex-wrap items-center gap-1.5">
                  {data.recentTriage.urgency ? (
                    <StatusPill tone={urgencyTone(data.recentTriage.urgency)}>
                      {data.recentTriage.urgency}
                    </StatusPill>
                  ) : null}
                  {data.recentTriage.recommendedSpecialty ? (
                    <span className="rounded bg-denseSurface-bg px-1.5 py-0.5 text-[11px] text-ink-2">
                      → {data.recentTriage.recommendedSpecialty}
                    </span>
                  ) : null}
                </div>
                {data.recentTriage.redFlags.length > 0 ? (
                  <ul className="mt-1.5 space-y-0.5 text-[11px] text-danger-500">
                    {data.recentTriage.redFlags.map((f, i) => (
                      <li key={i} className="flex items-start gap-1">
                        <AlertTriangle className="mt-0.5 h-3 w-3 flex-shrink-0" />
                        <span>{f}</span>
                      </li>
                    ))}
                  </ul>
                ) : null}
                {data.recentTriage.summary ? (
                  <p className="mt-1.5 line-clamp-2 text-xs text-ink-1">
                    {data.recentTriage.summary}
                  </p>
                ) : null}
              </MiniCard>
            ) : null}
          </div>
        ) : null}
      </div>
    </DenseCard>
  );
}

function urgencyTone(
  u: string,
): React.ComponentProps<typeof StatusPill>['tone'] {
  const lower = u.toLowerCase();
  if (lower.includes('high') || lower.includes('emergency') || lower.includes('urgent'))
    return 'danger';
  if (lower.includes('medium') || lower.includes('moderate')) return 'warning';
  if (lower.includes('low') || lower.includes('routine')) return 'success';
  return 'neutral';
}

function ChipRow({
  label,
  icon,
  items,
  chipTone,
  emptyHint,
}: {
  label: string;
  icon: React.ReactNode;
  items: string[];
  chipTone: 'neutral' | 'danger' | 'brand';
  emptyHint: string;
}) {
  const cls =
    chipTone === 'danger'
      ? 'border-danger-500/30 bg-danger-500/10 text-danger-500'
      : chipTone === 'brand'
        ? 'border-brand-500/30 bg-brand-500/10 text-brand-700'
        : 'border-denseSurface-border bg-denseSurface-bg text-ink-2';
  return (
    <div>
      <p className="flex items-center gap-1 text-[10px] font-semibold uppercase tracking-wide text-ink-3">
        {icon} {label}
      </p>
      {items.length === 0 ? (
        <p className="mt-1 text-xs italic text-ink-3">{emptyHint}</p>
      ) : (
        <ul className="mt-1 flex flex-wrap gap-1">
          {items.map((item, i) => (
            <li
              key={`${item}-${i}`}
              className={['rounded-full border px-2 py-0.5 text-[11px]', cls].join(' ')}
            >
              {item}
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}

function MiniCard({
  label,
  icon,
  children,
}: {
  label: string;
  icon: React.ReactNode;
  children: React.ReactNode;
}) {
  return (
    <div className="rounded-md border border-denseSurface-border bg-white p-2.5">
      <p className="flex items-center gap-1 text-[10px] font-semibold uppercase tracking-wide text-ink-3">
        {icon} {label}
      </p>
      <div className="mt-1">{children}</div>
    </div>
  );
}
