import { useState } from "react";
import { useParams, useNavigate } from "react-router-dom";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { endpoints } from "@/lib/api";
import { fmtDateTime, fmtDate, nowLocalInput, istInputToIso } from "@/lib/format";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { StatusBadge } from "@/components/shared/StatusBadge";
import { LoadingBlock, EmptyState } from "@/components/shared/EmptyState";
import { ADM_STATUS } from "@/lib/constants";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from "@/components/ui/dialog";
import { ChevronLeft, ArrowLeftRight, LogOut, User, BedDouble, CheckCircle2, AlertTriangle } from "lucide-react";

export default function AdmissionDetail() {
  const { id } = useParams();
  const navigate = useNavigate();
  const qc = useQueryClient();
  const { data: a, isLoading } = useQuery({ queryKey: ["admission", id], queryFn: () => endpoints.admission(id) });
  const [transferOpen, setTransferOpen] = useState(false);
  const [dischargeOpen, setDischargeOpen] = useState(false);

  if (isLoading) return <LoadingBlock rows={6} />;
  if (!a) return <EmptyState icon="FileX" title="Admission not found" />;

  return (
    <div className="space-y-5 animate-fade-in-up">
      <button onClick={() => navigate("/ipd")} className="flex items-center gap-1 text-sm text-subink hover:text-ink" data-testid="back-ipd"><ChevronLeft size={16} />IPD</button>

      <div className="rounded-2xl bg-white border border-hairline p-5">
        <div className="flex flex-col sm:flex-row sm:items-center gap-4">
          <div className="h-14 w-14 rounded-2xl bg-teal-soft text-teal flex items-center justify-center text-lg font-bold shrink-0">{a.patient?.initials}</div>
          <div className="flex-1">
            <div className="flex items-center gap-2 flex-wrap">
              <h1 className="text-xl font-bold text-ink">{a.patient?.full_name}</h1>
              <StatusBadge map={ADM_STATUS} status={a.status} />
            </div>
            <div className="text-sm text-subink tnum mt-0.5">{a.patient?.patient_id} · {a.admission_id}</div>
          </div>
          <div className="flex flex-wrap gap-2">
            <Button variant="outline" data-testid="adm-view-patient" onClick={() => navigate(`/patients/${a.patient_id}`)}><User size={15} className="mr-1.5" />Patient profile</Button>
            {a.status === "Active" && <>
              <Button variant="outline" className="border-clinical/30 text-clinical hover:bg-blue-50" data-testid="adm-transfer-btn" onClick={() => setTransferOpen(true)}><ArrowLeftRight size={15} className="mr-1.5" />Transfer bed</Button>
              <Button className="bg-teal hover:bg-teal-hover text-white" data-testid="adm-discharge-btn" onClick={() => setDischargeOpen(true)}><LogOut size={15} className="mr-1.5" />Discharge</Button>
            </>}
          </div>
        </div>
      </div>

      <div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
        <div className="rounded-2xl bg-white border border-hairline p-5">
          <div className="text-sm font-semibold text-ink mb-3">Admission details</div>
          <dl className="space-y-2.5 text-sm">
            <Row label="Doctor" value={a.doctor_name} />
            <Row label="Department" value={a.department} />
            <Row label="Ward" value={a.bed?.ward_name} />
            <Row label="Current bed" value={a.bed?.bed_number} />
            <Row label="Admitted" value={fmtDateTime(a.admission_time)} />
            {a.discharge_time && <Row label="Discharged" value={fmtDateTime(a.discharge_time)} />}
            <Row label="Length of stay" value={a.los?.label} />
            <Row label="Reason" value={a.reason || "—"} />
            {a.discharge_note && <Row label="Discharge note" value={a.discharge_note} />}
          </dl>
          <div className="mt-3 rounded-lg bg-amber-50 border border-amber-200 text-amber-700 text-xs p-2.5">Administrative workflow only — no billing clearance or clinical documentation implied.</div>
        </div>

        <div className="lg:col-span-2 space-y-4">
          <div className="rounded-2xl bg-white border border-hairline">
            <div className="px-4 py-3 border-b border-hairline text-sm font-semibold text-ink">Bed assignment history</div>
            <div className="p-4 space-y-3">
              {(a.bed_assignments || []).map((b, i) => (
                <div key={i} className="flex items-center gap-3">
                  <div className="h-8 w-8 rounded-lg bg-teal-soft text-teal flex items-center justify-center shrink-0"><BedDouble size={15} /></div>
                  <div className="flex-1">
                    <div className="text-sm text-ink"><span className="font-medium">{b.ward_name}</span> · <span className="tnum">{b.bed_number}</span>{!b.to && <span className="ml-2 text-xs text-teal font-medium">Current</span>}</div>
                    <div className="text-xs text-subink tnum">{fmtDateTime(b.from)} → {b.to ? fmtDateTime(b.to) : "present"}</div>
                  </div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>

      {a.status === "Active" && <TransferDialog admission={a} open={transferOpen} onOpenChange={setTransferOpen} qc={qc} />}
      {a.status === "Active" && <DischargeDialog admission={a} open={dischargeOpen} onOpenChange={setDischargeOpen} qc={qc} />}
    </div>
  );
}

function Row({ label, value }) {
  return (<div className="flex justify-between gap-3"><dt className="text-subink">{label}</dt><dd className="text-ink font-medium text-right">{value}</dd></div>);
}

function TransferDialog({ admission, open, onOpenChange, qc }) {
  const [wardId, setWardId] = useState("");
  const [bedId, setBedId] = useState("");
  const [err, setErr] = useState("");
  const { data: wards = [] } = useQuery({ queryKey: ["wards"], queryFn: endpoints.wards });
  const { data: beds = [], refetch } = useQuery({ queryKey: ["beds-available", wardId], queryFn: () => endpoints.beds({ ward: wardId, status: "Available" }), enabled: !!wardId });

  const mutation = useMutation({
    mutationFn: () => endpoints.transfer(admission.id, bedId),
    onSuccess: () => { qc.invalidateQueries(); toast.success("Patient transferred"); onOpenChange(false); setWardId(""); setBedId(""); },
    onError: (e) => { const m = e?.response?.data?.detail || "Could not transfer"; setErr(m); toast.error(m); refetch(); setBedId(""); },
  });

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent data-testid="transfer-dialog">
        <DialogHeader><DialogTitle>Transfer bed</DialogTitle><DialogDescription>Move {admission.patient?.full_name} to another available bed. The current bed will be marked for cleaning.</DialogDescription></DialogHeader>
        <div className="space-y-3">
          <div className="space-y-1.5">
            <Label className="text-sm">Ward</Label>
            <select value={wardId} onChange={(e) => { setWardId(e.target.value); setBedId(""); }} data-testid="transfer-ward" className="w-full h-10 px-3 rounded-xl border border-hairline bg-white text-sm">
              <option value="">Select ward</option>
              {wards.map((w) => <option key={w.id} value={w.id}>{w.name} · {w.floor}</option>)}
            </select>
          </div>
          {wardId && (beds.length === 0 ? (
            <div className="rounded-xl bg-amber-50 border border-amber-200 text-amber-700 text-sm p-3">No available beds in this ward.</div>
          ) : (
            <div className="grid grid-cols-3 gap-2">
              {beds.map((b) => {
                const sel = bedId === b.id;
                return (
                  <button key={b.id} data-testid={`transfer-bed-${b.bed_number}`} onClick={() => setBedId(b.id)} className={`rounded-xl border p-2.5 text-left ${sel ? "border-teal ring-2 ring-teal/30 bg-teal-soft" : "border-hairline hover:border-teal/40"}`}>
                    <div className="flex items-center justify-between"><BedDouble size={14} className={sel ? "text-teal" : "text-subink"} />{sel && <CheckCircle2 size={14} className="text-teal" />}</div>
                    <div className="text-sm font-semibold text-ink tnum mt-1">{b.bed_number}</div>
                    <div className="text-xs text-subink">{b.bed_type}</div>
                  </button>
                );
              })}
            </div>
          ))}
          {err && <div className="flex items-center gap-1.5 text-xs text-red-600"><AlertTriangle size={13} />{err}</div>}
        </div>
        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)} disabled={mutation.isPending}>Cancel</Button>
          <Button className="bg-teal hover:bg-teal-hover text-white" data-testid="transfer-confirm" disabled={!bedId || mutation.isPending} onClick={() => mutation.mutate()}>{mutation.isPending ? "Transferring…" : "Confirm transfer"}</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

function DischargeDialog({ admission, open, onOpenChange, qc }) {
  const [time, setTime] = useState(nowLocalInput());
  const [note, setNote] = useState("");
  const [err, setErr] = useState("");
  const mutation = useMutation({
    mutationFn: () => endpoints.discharge(admission.id, { discharge_time: istInputToIso(time), note: note || null }),
    onSuccess: () => { qc.invalidateQueries(); toast.success("Patient discharged"); onOpenChange(false); },
    onError: (e) => { const m = e?.response?.data?.detail || "Could not discharge"; setErr(m); toast.error(m); },
  });
  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent data-testid="discharge-dialog">
        <DialogHeader><DialogTitle>Discharge patient</DialogTitle><DialogDescription>Confirm the administrative discharge for {admission.patient?.full_name}. The bed will be marked for cleaning.</DialogDescription></DialogHeader>
        <div className="space-y-3">
          <div className="space-y-1.5"><Label className="text-sm">Discharge date & time</Label><Input type="datetime-local" max={nowLocalInput()} value={time} onChange={(e) => setTime(e.target.value)} data-testid="discharge-time" /></div>
          <div className="space-y-1.5"><Label className="text-sm">Administrative note</Label><Textarea rows={2} value={note} onChange={(e) => setNote(e.target.value)} placeholder="Optional" data-testid="discharge-note" /></div>
          {err && <div className="flex items-center gap-1.5 text-xs text-red-600"><AlertTriangle size={13} />{err}</div>}
        </div>
        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)} disabled={mutation.isPending}>Cancel</Button>
          <Button className="bg-teal hover:bg-teal-hover text-white" data-testid="discharge-confirm" disabled={mutation.isPending} onClick={() => mutation.mutate()}>{mutation.isPending ? "Discharging…" : "Confirm discharge"}</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
