'use client';

import { useEffect, useMemo, useState } from 'react';
import { useTranslations } from 'next-intl';
import { Button } from '@/components/ui/shared/Button';
import { ToastStack } from '@/components/ui/shared/Toast';
import { patientsApi } from '@/lib/api/patients';
import { getUserFacingError } from '@/components/shared/formatApiError';
import { useAuth } from '@/lib/hooks/useAuth';
import { useToast } from '@/lib/hooks/useToast';
import { hasPermission } from '@/components/shared/permissions';
import { CreatePatientInput, Patient } 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 { PatientAppointmentHistory } from '@/components/ui/patient/PatientAppointmentHistory';

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

export default function PatientsPage() {
  const t = useTranslations('patients');
  const tErrors = useTranslations('errors');
  const tCommon = useTranslations('common');
  const { currentOrganization } = useAuth();
  const toast = useToast();
  const [search, setSearch] = useState('');
  const [patients, setPatients] = useState<Patient[]>([]);
  const [selectedPatient, setSelectedPatient] = useState<Patient | undefined>();
  const [loadingPatients, setLoadingPatients] = useState(false);
  const [isCreateOpen, setIsCreateOpen] = useState(false);
  const [savingPatient, setSavingPatient] = 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(getUserFacingError(error, tErrors, t('errorLoadPatients')));
    } finally {
      setLoadingPatients(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);
      if (response.existing) {
        toast.showInfo(
          t('patientAlreadyExists', {
            firstName: response.data.firstName,
            lastName: response.data.lastName,
          }),
        );
      } else {
        toast.showSuccess(
          t('successPatientSaved', {
            firstName: response.data.firstName,
            lastName: response.data.lastName,
          }),
        );
      }
    } catch (error: unknown) {
      toast.showError(getUserFacingError(error, tErrors, t('errorSavePatient')));
    } finally {
      setSavingPatient(false);
    }
  }

  return (
    <div className="space-y-6">
      <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <h1 className="text-xl sm:text-2xl font-semibold text-text-primary">{t('title')}</h1>
        <Button
          variant="primary"
          disabled={!canEditPatients}
          onClick={() => {
            if (!canEditPatients) return;
            toast.clear();
            setPatientForm(EMPTY_PATIENT_FORM);
            setIsCreateOpen(true);
          }}
          title={!canEditPatients ? tCommon('readOnlyAccess') : undefined}
        >
          {t('newPatient')}
        </Button>
      </div>

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

      {isCreateOpen && (
        <CreatePatientModal
          isOpen={isCreateOpen}
          formData={patientForm}
          onChange={(patch) => setPatientForm((prev) => ({ ...prev, ...patch }))}
          onSubmit={() => void handleCreatePatient()}
          onClose={() => {
            setIsCreateOpen(false);
            setPatientForm(EMPTY_PATIENT_FORM);
          }}
          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={setSelectedPatient}
            loading={loadingPatients}
          />
        </div>

        <div className="xl:col-span-2 space-y-4">
          <PatientSummaryCard patient={selectedPatient} />
          {selectedPatient ? (
            <PatientAppointmentHistory patientId={selectedPatient.id} />
          ) : null}
        </div>
      </div>
    </div>
  );
}
