'use client';

import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { AppointmentsStrip } from '@/components/ui/treatment/AppointmentsStrip';
import { FdiToothChart } from '@/components/ui/treatment/FdiToothChart';
import { PastTreatmentsPanel } from '@/components/ui/treatment/PastTreatmentsPanel';
import { Checkbox } from '@/components/ui/shared/Checkbox';
import { Button } from '@/components/ui/shared/Button';
import { Dropdown } from '@/components/ui/shared/Dropdown';
import { SearchBar } from '@/components/ui/shared/SearchBar';
import { Toast } from '@/components/ui/shared/Toast';
import {
  addCalendarDays,
  compareLocalDayStart,
  isSameLocalCalendarDay,
  startOfLocalDay,
} from '@/components/appointments/appointmentTime';
import { appointmentsApi } from '@/lib/api/appointments';
import { treatmentsApi } from '@/lib/api/treatments';
import { pickAutoAppointment } from '@/components/shared/treatmentSelection';
import { canEditTreatment, canViewTreatment } from '@/components/shared/permissions';
import { formatApiErrorMessage } from '@/components/shared/formatApiError';
import type { Organization } from '@/types/organization';
import type { AppointmentRecord } from '@/types/appointment';
import type {
  FdiToothId,
  LinkedOrganizationOption,
  PastTreatment,
  PastTreatmentCase,
  TreatmentAppointment,
  TreatmentAttachmentMeta,
  TreatmentCaseDraft,
} from '@/types/treatment';

function newCase(): TreatmentCaseDraft {
  return {
    clientId:
      typeof crypto !== 'undefined' && 'randomUUID' in crypto
        ? crypto.randomUUID()
        : `case-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
    treatmentType: 'consultation',
    teeth: [],
    comment: '',
    attachmentMetas: [],
    sendToOrganizationIds: [],
    sentAt: null,
  };
}

function mapAppointment(record: AppointmentRecord): TreatmentAppointment {
  return {
    id: record.id,
    patientId: record.patientId,
    patientFirstName: record.patient.firstName,
    patientLastName: record.patient.lastName,
    providerUserId: record.providerUserId,
    startAt: record.startAt,
    endAt: record.endAt,
    purpose: record.purpose,
  };
}

function mapCaseFromApi(c: PastTreatmentCase): TreatmentCaseDraft {
  return {
    clientId: c.clientId,
    id: c.id,
    treatmentType: c.treatmentType,
    teeth: c.teeth,
    comment: c.notes ?? '',
    attachmentMetas: c.attachmentMetas ?? [],
    sendToOrganizationIds: c.sendToOrganizationIds ?? [],
    sentAt: c.sentAt ?? null,
  };
}

function serializeCases(cases: TreatmentCaseDraft[]) {
  return JSON.stringify(
    cases.map((c) => ({
      clientId: c.clientId,
      id: c.id,
      treatmentType: c.treatmentType,
      teeth: c.teeth,
      comment: c.comment,
      attachmentMetas: c.attachmentMetas,
      sendToOrganizationIds: c.sendToOrganizationIds,
      sentAt: c.sentAt,
    })),
  );
}

interface TreatmentWorkspaceProps {
  userId: string;
  currentOrganization: Organization | null;
}

export function TreatmentWorkspace({ userId, currentOrganization }: TreatmentWorkspaceProps) {
  const canView = canViewTreatment(currentOrganization);
  const canEdit = canEditTreatment(currentOrganization);

  const [stripHidden, setStripHidden] = useState(false);

  const todayStart = useMemo(() => startOfLocalDay(new Date()), []);

  const [selectedDay, setSelectedDay] = useState(() => startOfLocalDay(new Date()));
  const [appointments, setAppointments] = useState<TreatmentAppointment[]>([]);
  const [apptsLoading, setApptsLoading] = useState(false);
  const [selectionLocked, setSelectionLocked] = useState(false);
  const [selectedAppointmentId, setSelectedAppointmentId] = useState<string | null>(null);

  const [history, setHistory] = useState<PastTreatment[]>([]);
  const [historyLoading, setHistoryLoading] = useState(false);

  const [orgs, setOrgs] = useState<LinkedOrganizationOption[]>([]);

  const [cases, setCases] = useState<TreatmentCaseDraft[]>(() => [newCase()]);
  const [activeCaseId, setActiveCaseId] = useState<string>(() => cases[0].clientId);
  const [savedSnapshot, setSavedSnapshot] = useState<string | null>(null);

  const selectionLockedRef = useRef(selectionLocked);
  selectionLockedRef.current = selectionLocked;

  const attachmentInputRef = useRef<HTMLInputElement>(null);

  const [saveBusy, setSaveBusy] = useState(false);
  const [sendBusyId, setSendBusyId] = useState<string | null>(null);
  const [uploadBusy, setUploadBusy] = useState(false);
  const [banner, setBanner] = useState<string | null>(null);
  const [errorBanner, setErrorBanner] = useState<string | null>(null);
  const [organizationSearch, setOrganizationSearch] = useState('');
  const [recentOrganizationIds, setRecentOrganizationIds] = useState<string[]>([]);
  const [reviewTreatment, setReviewTreatment] = useState<PastTreatment | null>(null);

  const isDirty = useMemo(() => {
    if (savedSnapshot === null) {
      return cases.length !== 1 || cases[0].comment !== '' || cases[0].teeth.length > 0;
    }
    return serializeCases(cases) !== savedSnapshot;
  }, [cases, savedSnapshot]);

  const selectedAppointment = useMemo(
    () => appointments.find((a) => a.id === selectedAppointmentId) ?? null,
    [appointments, selectedAppointmentId],
  );

  const isViewingPastDay = useMemo(
    () => compareLocalDayStart(selectedDay, todayStart) < 0,
    [selectedDay, todayStart],
  );

  const canEditTreatmentForDay = canEdit && Boolean(selectedAppointment) && !isViewingPastDay;

  const activeCase = useMemo(
    () => cases.find((c) => c.clientId === activeCaseId) ?? cases[0],
    [cases, activeCaseId],
  );

  const selectedTeethSet = useMemo(() => new Set(activeCase.teeth), [activeCase.teeth]);
  const activeLinkedOrganizations = useMemo(() => orgs.filter((o) => o.active), [orgs]);
  const filteredOrganizations = useMemo(() => {
    const q = organizationSearch.trim().toLowerCase();
    if (!q) return activeLinkedOrganizations;
    return activeLinkedOrganizations.filter((o) => o.name.toLowerCase().includes(q));
  }, [organizationSearch, activeLinkedOrganizations]);
  const recentOrganizations = useMemo(() => {
    if (recentOrganizationIds.length === 0) return [];
    const recentSet = new Set(recentOrganizationIds);
    return activeLinkedOrganizations
      .filter((o) => recentSet.has(o.id))
      .sort((a, b) => recentOrganizationIds.indexOf(a.id) - recentOrganizationIds.indexOf(b.id))
      .slice(0, 3);
  }, [recentOrganizationIds, activeLinkedOrganizations]);

  const currentDraftPreview = useMemo<PastTreatment | null>(() => {
    if (!selectedAppointment) return null;
    return {
      id: 'current-draft',
      patientId: selectedAppointment.patientId,
      title: `Current draft for ${selectedAppointment.patientFirstName} ${selectedAppointment.patientLastName}`,
      treatmentAt: new Date().toISOString(),
      status: 'draft',
      cases: cases.map((c, idx) => ({
        id: c.id ?? c.clientId ?? `draft-${idx + 1}`,
        clientId: c.clientId,
        treatmentType: c.treatmentType,
        teeth: c.teeth,
        notes: c.comment || null,
      })),
      documents: cases.flatMap((c) => c.attachmentMetas),
    };
  }, [cases, selectedAppointment]);

  const treatmentTypeTextColor = useMemo(() => {
    const map: Record<TreatmentCaseDraft['treatmentType'], string> = {
      consultation: '#ddd6fe',
      filling: '#fed7aa',
      endo: '#fecaca',
      visit: '#bae6fd',
      hygiene: '#d9f99d',
    };
    return map[activeCase.treatmentType];
  }, [activeCase.treatmentType]);

  const loadDraftForAppointment = useCallback(async (appointmentId: string) => {
    const response = await treatmentsApi.getDraft(appointmentId);
    if (response.data?.cases?.length) {
      const mapped = response.data.cases.map(mapCaseFromApi);
      setCases(mapped);
      setActiveCaseId(mapped[0].clientId);
      setSavedSnapshot(serializeCases(mapped));
    } else {
      const first = newCase();
      setCases([first]);
      setActiveCaseId(first.clientId);
      setSavedSnapshot(serializeCases([first]));
    }
    setOrganizationSearch('');
    setReviewTreatment(null);
  }, []);

  useEffect(() => {
    setSelectionLocked(false);
  }, [selectedDay]);

  useEffect(() => {
    let cancelled = false;
    setApptsLoading(true);
    void (async () => {
      try {
        const dayStart = startOfLocalDay(selectedDay);
        const dayEnd = addCalendarDays(dayStart, 1);
        const response = await appointmentsApi.list({
          from: dayStart.toISOString(),
          to: dayEnd.toISOString(),
        });
        if (cancelled) return;
        const list = response.data
          .filter((a) => a.providerUserId === userId)
          .map(mapAppointment);
        setAppointments(list);
        if (!selectionLockedRef.current) {
          setSelectedAppointmentId(pickAutoAppointment(list, selectedDay));
        }
      } catch (error: unknown) {
        if (!cancelled) {
          setErrorBanner(formatApiErrorMessage(error, 'Failed to load appointments.'));
        }
      } finally {
        if (!cancelled) setApptsLoading(false);
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [userId, selectedDay]);

  useEffect(() => {
    const today = startOfLocalDay(new Date());
    if (!isSameLocalCalendarDay(selectedDay, today) || selectionLocked) return;

    const id = window.setInterval(() => {
      setSelectedAppointmentId((prev) => {
        const next = pickAutoAppointment(appointments, selectedDay);
        return next ?? prev;
      });
    }, 60_000);

    return () => window.clearInterval(id);
  }, [selectedDay, appointments, selectionLocked]);

  useEffect(() => {
    let cancelled = false;
    void (async () => {
      try {
        const list = await treatmentsApi.listLinkedOrganizations();
        if (!cancelled) setOrgs(list.data);
      } catch (error: unknown) {
        if (!cancelled) {
          setErrorBanner(formatApiErrorMessage(error, 'Failed to load linked organizations.'));
        }
      }
    })();
    return () => {
      cancelled = true;
    };
  }, []);

  useEffect(() => {
    if (!selectedAppointment) {
      setHistory([]);
      return;
    }
    let cancelled = false;
    setHistoryLoading(true);
    void (async () => {
      try {
        const response = await treatmentsApi.listPatientHistory(selectedAppointment.patientId);
        if (!cancelled) {
          setHistory(response.data);
        }
      } catch (error: unknown) {
        if (!cancelled) {
          setErrorBanner(formatApiErrorMessage(error, 'Failed to load treatment history.'));
        }
      } finally {
        if (!cancelled) setHistoryLoading(false);
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [selectedAppointment?.patientId]);

  useEffect(() => {
    if (!selectedAppointment?.id) return;
    let cancelled = false;
    void (async () => {
      try {
        await loadDraftForAppointment(selectedAppointment.id);
      } catch (error: unknown) {
        if (!cancelled) {
          setErrorBanner(formatApiErrorMessage(error, 'Failed to load treatment draft.'));
        }
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [selectedAppointment?.id, loadDraftForAppointment]);

  const fixActiveAfterCasesChange = useCallback((next: TreatmentCaseDraft[]) => {
    setCases(next);
    setActiveCaseId((id) => (next.some((c) => c.clientId === id) ? id : next[0].clientId));
  }, []);

  const toggleTooth = useCallback(
    (fdi: FdiToothId) => {
      if (!canEditTreatmentForDay) return;
      setCases((prev) =>
        prev.map((c) => {
          if (c.clientId !== activeCaseId) return c;
          const set = new Set(c.teeth);
          if (set.has(fdi)) set.delete(fdi);
          else set.add(fdi);
          return { ...c, teeth: [...set].sort() as FdiToothId[] };
        }),
      );
    },
    [activeCaseId, canEditTreatmentForDay],
  );

  const confirmDiscardIfDirty = useCallback(() => {
    if (!isDirty) return true;
    return window.confirm('You have unsaved changes. Discard them and continue?');
  }, [isDirty]);

  const onPickAppointment = useCallback(
    (id: string) => {
      if (!confirmDiscardIfDirty()) return;
      setSelectionLocked(true);
      setSelectedAppointmentId(id);
    },
    [confirmDiscardIfDirty],
  );

  const onSelectDay = useCallback(
    (day: Date) => {
      if (!confirmDiscardIfDirty()) return;
      setSelectedDay(day);
    },
    [confirmDiscardIfDirty],
  );

  const addAttachments = useCallback(
    async (files: FileList | null) => {
      if (!files?.length || !canEditTreatmentForDay || !selectedAppointment) return;
      setUploadBusy(true);
      setErrorBanner(null);
      try {
        const uploaded = await treatmentsApi.uploadCaseAttachments(
          selectedAppointment.id,
          activeCaseId,
          Array.from(files),
        );
        setCases((prev) =>
          prev.map((c) => {
            if (c.clientId !== activeCaseId) return c;
            return { ...c, attachmentMetas: [...c.attachmentMetas, ...uploaded.data] };
          }),
        );
      } catch (error: unknown) {
        setErrorBanner(formatApiErrorMessage(error, 'Failed to upload attachments.'));
      } finally {
        setUploadBusy(false);
      }
    },
    [activeCaseId, canEditTreatmentForDay, selectedAppointment],
  );

  const persistDraft = useCallback(async () => {
    if (!selectedAppointment) {
      throw new Error('No appointment selected');
    }
    const response = await treatmentsApi.saveDraft(selectedAppointment.id, {
      cases: cases.map(({ clientId, id, treatmentType, teeth, comment, attachmentMetas }) => ({
        clientId,
        id,
        treatmentType,
        teeth,
        comment,
        attachmentIds: attachmentMetas.map((a) => a.id),
      })),
    });
    const mapped = response.data.cases.map(mapCaseFromApi);
    setCases(mapped);
    setActiveCaseId((prev) => {
      const stillExists = mapped.some((c) => c.clientId === prev);
      return stillExists ? prev : mapped[0]?.clientId ?? prev;
    });
    setSavedSnapshot(serializeCases(mapped));
    return response.data;
  }, [cases, selectedAppointment]);

  const handleSaveAll = useCallback(async () => {
    if (!canEditTreatmentForDay || !selectedAppointment) return;
    setSaveBusy(true);
    setBanner(null);
    setErrorBanner(null);
    try {
      await persistDraft();
      setBanner('Treatment draft saved. You can send cases later.');
    } catch (error: unknown) {
      setErrorBanner(formatApiErrorMessage(error, 'Failed to save treatment draft.'));
    } finally {
      setSaveBusy(false);
    }
  }, [canEditTreatmentForDay, selectedAppointment, persistDraft]);

  const handleSendCase = useCallback(
    async (treatmentCase: TreatmentCaseDraft) => {
      if (!canEditTreatmentForDay || !selectedAppointment) return;
      const targets = treatmentCase.sendToOrganizationIds.filter((id) =>
        orgs.some((o) => o.id === id && o.active),
      );
      if (targets.length === 0) {
        setErrorBanner('Choose at least one active organization to send this case.');
        return;
      }
      setSendBusyId(treatmentCase.clientId);
      setBanner(null);
      setErrorBanner(null);
      try {
        const saved = await persistDraft();
        const serverCase = saved.cases.find((c) => c.clientId === treatmentCase.clientId);
        if (!serverCase?.id) {
          throw new Error('Case must be saved before sending.');
        }
        const response = await treatmentsApi.sendCase(serverCase.id, { organizationIds: targets });
        setCases((prev) => {
          const next = prev.map((c) =>
            c.clientId === treatmentCase.clientId
              ? {
                  ...c,
                  id: response.data.id,
                  sentAt: response.data.sentAt,
                  sendToOrganizationIds: response.data.sendToOrganizationIds,
                }
              : c,
          );
          setSavedSnapshot(serializeCases(next));
          return next;
        });
        setRecentOrganizationIds((prev) => {
          const next = [...targets.filter((id) => id && !prev.includes(id)), ...prev];
          return next.slice(0, 10);
        });
        setBanner('Case sent to selected organizations.');
      } catch (error: unknown) {
        setErrorBanner(formatApiErrorMessage(error, 'Failed to send case.'));
      } finally {
        setSendBusyId(null);
      }
    },
    [canEditTreatmentForDay, selectedAppointment, orgs, persistDraft, cases],
  );

  if (!canView) {
    return (
      <div className="surface-card p-6 max-w-xl">
        <h2 className="text-lg font-semibold text-text-primary">Treatment workspace</h2>
        <p className="text-sm text-text-secondary mt-2">
          You do not have permission to view the Treatment tab for this organization.
        </p>
      </div>
    );
  }

  return (
    <div className="relative space-y-6 pb-24">
      <header className="space-y-1">
        <h1 className="text-2xl font-semibold text-text-primary">Treatment</h1>
        <p className="text-sm text-text-secondary">
          {canEdit
            ? 'Document cases for your appointments, save drafts, and send work to linked organizations.'
            : 'View-only access — you can review appointments and treatment history but cannot edit.'}
        </p>
      </header>

      <AppointmentsStrip
        stripHidden={stripHidden}
        onToggleStripHidden={() => setStripHidden((s) => !s)}
        selectedDay={selectedDay}
        onSelectDay={onSelectDay}
        appointments={appointments}
        selectedAppointmentId={selectedAppointmentId}
        onSelectAppointment={onPickAppointment}
        loading={apptsLoading}
      />

      {isViewingPastDay && (
        <p className="text-sm text-text-secondary rounded-[var(--radius-md)] border border-border/60 bg-background-secondary/50 px-3 py-2">
          Past days are view-only. You can review appointments and history, but treatment cases
          cannot be added or changed.
        </p>
      )}

      <div className="grid grid-cols-1 xl:grid-cols-[minmax(280px,380px)_minmax(0,1fr)] gap-6 items-start">
        <div className="space-y-4">
          {selectedAppointment ? (
            <div className="surface-card p-4 space-y-1">
              <p className="text-xs uppercase tracking-wide text-text-muted">Selected patient</p>
              <p className="text-lg font-semibold text-text-primary">
                {selectedAppointment.patientFirstName} {selectedAppointment.patientLastName}
              </p>
              <p className="text-xs text-text-secondary">
                Appointment purpose:{' '}
                <span className="capitalize text-text-primary">{selectedAppointment.purpose}</span>
              </p>
            </div>
          ) : (
            <div className="surface-card p-4 text-sm text-text-muted">
              {apptsLoading ? 'Loading appointments…' : 'Select a day with at least one appointment.'}
            </div>
          )}

          <PastTreatmentsPanel
            items={history}
            loading={historyLoading}
            selectedTreatmentId={reviewTreatment?.id ?? null}
            onSelectTreatment={setReviewTreatment}
          />
          <div className="surface-card p-4 space-y-3">
            <div className="flex items-center justify-between gap-2">
              <h3 className="text-sm font-semibold text-text-primary">Treatment review</h3>
              <Button
                type="button"
                variant="primary"
                disabled={!selectedAppointment}
                onClick={() => setReviewTreatment(currentDraftPreview)}
              >
                Preview current treatment
              </Button>
            </div>
            {!reviewTreatment && (
              <p className="text-sm text-text-muted">
                Select a treatment from history, or preview the current draft.
              </p>
            )}
            {reviewTreatment && (
              <div className="border border-border/70 rounded-[var(--radius-md)] p-3 bg-background-secondary/40 space-y-2">
                <div className="flex items-start justify-between gap-2">
                  <p className="text-sm font-medium text-text-primary">{reviewTreatment.title}</p>
                  <span className="text-xs text-text-muted tabular-nums">
                    {new Date(reviewTreatment.treatmentAt).toLocaleDateString()}
                  </span>
                </div>
                <p className="text-xs text-text-secondary capitalize">Status: {reviewTreatment.status}</p>
                <div className="space-y-2">
                  {reviewTreatment.cases.map((c, idx) => (
                    <div key={c.id} className="rounded-[var(--radius-sm)] border border-border/60 px-2.5 py-2">
                      <p className="text-xs text-text-primary font-medium">Case {idx + 1}</p>
                      <p className="text-xs text-text-secondary capitalize mt-1">
                        Type: {c.treatmentType}
                      </p>
                      <p className="text-xs text-text-secondary">
                        Teeth: {c.teeth.length ? [...c.teeth].sort().join(', ') : 'None selected'}
                      </p>
                      {c.notes && <p className="text-xs text-text-muted mt-1">Notes: {c.notes}</p>}
                    </div>
                  ))}
                </div>
                <p className="text-xs text-text-muted">
                  Attachments: {reviewTreatment.documents.length}
                </p>
              </div>
            )}
          </div>
        </div>

        <div className="space-y-4 min-w-0">
          <FdiToothChart
            selected={selectedTeethSet}
            onToggle={toggleTooth}
            disabled={!canEditTreatmentForDay}
          />

          <div className="surface-card p-4 space-y-4">
            <div className="flex flex-wrap items-center justify-between gap-3">
              <div>
                <h3 className="text-sm font-semibold text-text-primary">Treatment cases</h3>
                <p className="text-xs text-text-muted mt-0.5">
                  Each case has its own teeth, notes, attachments, and destinations for send.
                </p>
              </div>
              <Button
                type="button"
                variant="primary"
                disabled={!canEditTreatmentForDay}
                onClick={() => {
                  const nextCase = newCase();
                  fixActiveAfterCasesChange([...cases, nextCase]);
                  setActiveCaseId(nextCase.clientId);
                }}
              >
                Add case
              </Button>
            </div>

            <div className="flex flex-wrap gap-2">
              {cases.map((c, idx) => (
                <button
                  key={c.clientId}
                  type="button"
                  onClick={() => setActiveCaseId(c.clientId)}
                  className={`
                    rounded-[var(--radius-md)] border px-3 py-1.5 text-sm transition-colors
                    focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/45
                    ${
                      c.clientId === activeCaseId
                        ? 'border-primary bg-primary-soft font-medium text-text-primary'
                        : 'border-border/70 text-text-secondary hover:border-border hover:bg-background-card/50'
                    }
                  `}
                >
                  Case {idx + 1}
                  {c.sentAt ? ' · sent' : ''}
                </button>
              ))}
            </div>

            {activeCase && (
              <div className="space-y-4 border border-border/60 rounded-[var(--radius-md)] p-4 bg-background-secondary/30">
                <label className="block text-xs font-medium text-text-secondary">
                  Comments
                  <textarea
                    value={activeCase.comment}
                    onChange={(e) => {
                      const v = e.target.value;
                      setCases((prev) =>
                        prev.map((c) => (c.clientId === activeCaseId ? { ...c, comment: v } : c)),
                      );
                    }}
                    placeholder="Write clinical notes for this case…"
                    rows={5}
                    disabled={!canEditTreatmentForDay || Boolean(activeCase.sentAt)}
                    className="mt-1.5 w-full rounded-[var(--radius-md)] border border-border bg-background-secondary/90 text-text-primary text-sm px-3 py-2 placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-primary/35 resize-y min-h-[120px]"
                  />
                </label>

                <div>
                  <Dropdown
                    label="Treatment type"
                    value={activeCase.treatmentType}
                    onChange={(e) => {
                      const nextType = e.target.value as TreatmentCaseDraft['treatmentType'];
                      setCases((prev) =>
                        prev.map((c) =>
                          c.clientId === activeCaseId ? { ...c, treatmentType: nextType } : c,
                        ),
                      );
                    }}
                    disabled={!canEditTreatmentForDay || Boolean(activeCase.sentAt)}
                    className="capitalize"
                    style={{ color: treatmentTypeTextColor }}
                  >
                    <option value="consultation" style={{ color: '#ddd6fe', backgroundColor: '#14253d' }} className="capitalize">consultation</option>
                    <option value="filling" style={{ color: '#fed7aa', backgroundColor: '#14253d' }} className="capitalize">filling</option>
                    <option value="endo" style={{ color: '#fecaca', backgroundColor: '#14253d' }} className="capitalize">endo</option>
                    <option value="visit" style={{ color: '#bae6fd', backgroundColor: '#14253d' }} className="capitalize">visit</option>
                    <option value="hygiene" style={{ color: '#d9f99d', backgroundColor: '#14253d' }} className="capitalize">hygiene</option>
                  </Dropdown>
                </div>

                <div>
                  <p className="text-xs font-medium text-text-secondary mb-2">Attachments</p>
                  <input
                    ref={attachmentInputRef}
                    id="treatment-case-attachments"
                    type="file"
                    multiple
                    disabled={!canEditTreatmentForDay || uploadBusy || Boolean(activeCase.sentAt)}
                    onChange={(e) => {
                      void addAttachments(e.target.files);
                      e.target.value = '';
                    }}
                    className="sr-only"
                    aria-label="Attach files for this treatment case"
                  />
                  <Button
                    type="button"
                    variant="primary"
                    disabled={!canEditTreatmentForDay || uploadBusy || Boolean(activeCase.sentAt)}
                    isLoading={uploadBusy}
                    onClick={() => attachmentInputRef.current?.click()}
                    aria-controls="treatment-case-attachments"
                  >
                    Choose files
                  </Button>
                  {activeCase.attachmentMetas.length > 0 && (
                    <ul className="mt-2 space-y-1 text-xs text-text-muted">
                      {activeCase.attachmentMetas.map((f) => (
                        <li key={f.id} className="truncate">
                          {f.fileName} ({(f.sizeBytes / 1024).toFixed(1)} KB)
                        </li>
                      ))}
                    </ul>
                  )}
                </div>

                <div>
                  <p className="text-xs font-medium text-text-secondary mb-2">
                    Send this case to linked organizations
                  </p>
                  <div className="space-y-2 mb-2">
                    <SearchBar
                      value={organizationSearch}
                      onChange={setOrganizationSearch}
                      placeholder="Search active organizations..."
                    />
                    {recentOrganizations.length > 0 && (
                      <div className="flex flex-wrap items-center gap-2">
                        <span className="text-xs text-text-muted">Recent:</span>
                        {recentOrganizations.map((o) => (
                          <button
                            key={o.id}
                            type="button"
                            disabled={!canEditTreatmentForDay || Boolean(activeCase.sentAt)}
                            onClick={() => {
                              setCases((prev) =>
                                prev.map((c) => {
                                  if (c.clientId !== activeCaseId || c.sentAt) return c;
                                  if (c.sendToOrganizationIds.includes(o.id)) return c;
                                  return { ...c, sendToOrganizationIds: [...c.sendToOrganizationIds, o.id] };
                                }),
                              );
                            }}
                            className="text-xs rounded-[var(--radius-sm)] border border-border/70 px-2 py-1 text-text-secondary hover:text-text-primary hover:border-border focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/35 disabled:opacity-50"
                          >
                            {o.name}
                          </button>
                        ))}
                      </div>
                    )}
                  </div>
                  <div className="flex flex-col gap-2">
                    {filteredOrganizations.map((o) => (
                      <Checkbox
                        key={o.id}
                        checked={activeCase.sendToOrganizationIds.includes(o.id)}
                        disabled={!canEditTreatmentForDay || Boolean(activeCase.sentAt)}
                        onChange={(checked) => {
                          setCases((prev) =>
                            prev.map((c) => {
                              if (c.clientId !== activeCaseId) return c;
                              const next = new Set(c.sendToOrganizationIds);
                              if (checked) next.add(o.id);
                              else next.delete(o.id);
                              return { ...c, sendToOrganizationIds: [...next] };
                            }),
                          );
                        }}
                        label={o.name}
                      />
                    ))}
                    {filteredOrganizations.length === 0 && (
                      <p className="text-xs text-text-muted">No active organization matches your search.</p>
                    )}
                  </div>
                </div>

                <div className="flex flex-wrap items-center gap-3 pt-1">
                  <Button
                    type="button"
                    variant="primary"
                    disabled={
                      !canEditTreatmentForDay ||
                      Boolean(activeCase.sentAt) ||
                      sendBusyId === activeCase.clientId
                    }
                    isLoading={sendBusyId === activeCase.clientId}
                    onClick={() => void handleSendCase(activeCase)}
                  >
                    Send this case
                  </Button>
                  {activeCase.sentAt && (
                    <span className="text-xs text-text-muted">
                      Sent at {new Date(activeCase.sentAt).toLocaleString()}
                    </span>
                  )}
                </div>
              </div>
            )}

            {canEdit && (
              <div className="flex flex-wrap gap-3 pt-2 border-t border-border/60">
                <Button
                  type="button"
                  variant="primary"
                  disabled={!canEditTreatmentForDay || saveBusy}
                  isLoading={saveBusy}
                  onClick={() => void handleSaveAll()}
                >
                  Save treatment draft
                </Button>
                <p className="text-xs text-text-muted self-center">
                  {isDirty ? 'Unsaved changes' : 'Draft saved'}. Sending is per case and saves first automatically.
                </p>
              </div>
            )}
          </div>
        </div>
      </div>

      {(banner || errorBanner) && (
        <div className="fixed bottom-4 left-0 right-0 z-[70] px-4 pointer-events-none">
          <div className="pointer-events-auto w-full">
            {banner && <Toast variant="success">{banner}</Toast>}
            {errorBanner && (
              <div className={banner ? 'mt-2' : ''}>
                <Toast variant="danger">{errorBanner}</Toast>
              </div>
            )}
          </div>
        </div>
      )}
    </div>
  );
}
