'use client';

import { useEffect, useMemo, useState } from 'react';
import { Button } from '@/components/ui/shared/Button';
import { ToastStack } from '@/components/ui/shared/Toast';
import { patientsApi } from '@/lib/api/patients';
import { formatApiErrorMessage } from '@/lib/formatApiError';
import { useAuth } from '@/lib/hooks/useAuth';
import { useToast } from '@/lib/hooks/useToast';
import { hasPermission } from '@/components/shared/permissions';
import {
  CreatePatientInput,
  CreateTreatmentHistoryInput,
  Patient,
  TreatmentHistoryItem,
} from '@/types/patient';
import { PatientSearchSelect } from '../../../components/ui/patient/PatientSearchSelect';
import { CreatePatientModal } from '../../../components/ui/patient/CreatePatientModal';
import { PatientSummaryCard } from '../../../components/ui/patient/PatientSummaryCard';
import { TreatmentHistoryPreview } from '../../../components/ui/patient/TreatmentHistoryPreview';

const EMPTY_PATIENT_FORM: CreatePatientInput = {
  firstName: '',
  lastName: '',
  phone: '',
  email: '',
};

export default function PatientsPage() {
  const { currentOrganization } = useAuth();
  const toast = useToast();
  const [search, setSearch] = useState('');
  const [patients, setPatients] = useState<Patient[]>([]);
  const [selectedPatient, setSelectedPatient] = useState<Patient | undefined>();
  const [treatments, setTreatments] = useState<TreatmentHistoryItem[]>([]);
  const [loadingPatients, setLoadingPatients] = useState(false);
  const [loadingTreatments, setLoadingTreatments] = useState(false);
  const [isCreateOpen, setIsCreateOpen] = useState(false);
  const [savingPatient, setSavingPatient] = useState(false);
  const [savingTreatment, setSavingTreatment] = useState(false);
  const [patientForm, setPatientForm] = useState<CreatePatientInput>(EMPTY_PATIENT_FORM);
  const canEditPatients = hasPermission(currentOrganization, 'TAB_PATIENTS_EDIT');

  const sortedPatients = useMemo(
    () =>
      [...patients].sort((a, b) =>
        `${a.firstName} ${a.lastName}`.localeCompare(`${b.firstName} ${b.lastName}`),
      ),
    [patients],
  );

  useEffect(() => {
    const timeout = setTimeout(() => {
      void loadPatients(search);
    }, 300);
    return () => clearTimeout(timeout);
  }, [search]);

  useEffect(() => {
    void loadPatients('');
  }, []);

  async function loadPatients(q: string) {
    setLoadingPatients(true);
    toast.setError('');
    try {
      const response = await patientsApi.list({ q, page: 1, limit: 25 });
      const items = response.data.items;
      setPatients(items);

      if (selectedPatient) {
        const freshSelected = items.find((item) => item.id === selectedPatient.id);
        setSelectedPatient(freshSelected);
      }
    } catch (error: unknown) {
      toast.showError(formatApiErrorMessage(error, 'Failed to load patients.'));
    } finally {
      setLoadingPatients(false);
    }
  }

  async function loadTreatments(patientId: string) {
    setLoadingTreatments(true);
    toast.setError('');
    try {
      const response = await patientsApi.listTreatments(patientId);
      setTreatments(response.data);
    } catch (error: unknown) {
      toast.showError(formatApiErrorMessage(error, 'Failed to load treatment history.'));
    } finally {
      setLoadingTreatments(false);
    }
  }

  async function handleCreatePatient() {
    setSavingPatient(true);
    toast.setError('');
    try {
      const response = await patientsApi.create(patientForm);
      setIsCreateOpen(false);
      setPatientForm(EMPTY_PATIENT_FORM);
      await loadPatients(search);
      setSelectedPatient(response.data);
      await loadTreatments(response.data.id);
      toast.showSuccess(
        `Patient ${response.data.firstName} ${response.data.lastName} was saved successfully.`,
      );
    } catch (error: unknown) {
      toast.showError(formatApiErrorMessage(error, 'Failed to save patient.'));
    } finally {
      setSavingPatient(false);
    }
  }

  async function handleQuickAddTreatment() {
    if (!selectedPatient) {
      return;
    }

    const payload: CreateTreatmentHistoryInput = {
      title: 'Initial consultation',
      status: 'scheduled',
      treatmentAt: new Date().toISOString(),
      notes: 'Created from quick action on patients page.',
    };

    setSavingTreatment(true);
    toast.setError('');
    try {
      await patientsApi.addTreatment(selectedPatient.id, payload);
      await loadTreatments(selectedPatient.id);
      toast.showSuccess('Treatment entry added successfully.');
    } catch (error: unknown) {
      toast.showError(formatApiErrorMessage(error, 'Failed to add treatment entry.'));
    } finally {
      setSavingTreatment(false);
    }
  }

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between gap-3">
        <h1 className="text-2xl font-semibold text-text-primary">Patients</h1>
        <Button
          variant="primary"
          disabled={!canEditPatients}
          onClick={() => {
            if (!canEditPatients) return;
            toast.clear();
            setIsCreateOpen(true);
          }}
          title={!canEditPatients ? 'Read-only access for this organization.' : undefined}
        >
          New Patient
        </Button>
      </div>

      <ToastStack {...toast.messages} />

      {isCreateOpen && (
        <CreatePatientModal
          isOpen={isCreateOpen}
          formData={patientForm}
          onChange={(patch) => setPatientForm((prev) => ({ ...prev, ...patch }))}
          onSubmit={() => void handleCreatePatient()}
          onClose={() => setIsCreateOpen(false)}
          loading={savingPatient}
        />
      )}

      <div className="grid grid-cols-1 xl:grid-cols-3 gap-6">
        <div className="xl:col-span-1">
          <PatientSearchSelect
            search={search}
            onSearchChange={setSearch}
            patients={sortedPatients}
            selectedPatientId={selectedPatient?.id}
            onSelectPatient={(patient) => {
              setSelectedPatient(patient);
              void loadTreatments(patient.id);
            }}
            loading={loadingPatients}
          />
        </div>

        <div className="xl:col-span-2 space-y-4">
          <PatientSummaryCard patient={selectedPatient} />
          <div className="flex">
            <Button
              variant="secondary"
              disabled={!selectedPatient || !canEditPatients}
              isLoading={savingTreatment}
              onClick={() => {
                if (!canEditPatients) return;
                void handleQuickAddTreatment();
              }}
              title={!canEditPatients ? 'Read-only access for this organization.' : undefined}
            >
              Add Quick Treatment Entry
            </Button>
          </div>
          <TreatmentHistoryPreview items={treatments} loading={loadingTreatments} />
        </div>
      </div>
    </div>
  );
}
