'use client';

import { useEffect, useMemo, useState } from 'react';
import { Button } from '@/components/ui/common/Button';
import { patientsApi } from '@/lib/api/patients';
import { useAuth } from '@/lib/hooks/useAuth';
import { hasPermission } from '@/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 [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 [errorMessage, setErrorMessage] = useState<string>('');
  const [successMessage, setSuccessMessage] = useState<string>('');
  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('');
  }, []);

  useEffect(() => {
    if (!successMessage) {
      return;
    }

    const timeout = setTimeout(() => {
      setSuccessMessage('');
    }, 3000);

    return () => clearTimeout(timeout);
  }, [successMessage]);

  async function loadPatients(q: string) {
    setLoadingPatients(true);
    setErrorMessage('');
    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: any) {
      const message = Array.isArray(error?.message) ? error.message.join(', ') : error?.message;
      setErrorMessage(message || 'Failed to load patients.');
    } finally {
      setLoadingPatients(false);
    }
  }

  async function loadTreatments(patientId: string) {
    setLoadingTreatments(true);
    setErrorMessage('');
    try {
      const response = await patientsApi.listTreatments(patientId);
      setTreatments(response.data);
    } catch (error: any) {
      const message = Array.isArray(error?.message) ? error.message.join(', ') : error?.message;
      setErrorMessage(message || 'Failed to load treatment history.');
    } finally {
      setLoadingTreatments(false);
    }
  }

  async function handleCreatePatient() {
    setSavingPatient(true);
    setErrorMessage('');
    setSuccessMessage('');
    try {
      const response = await patientsApi.create(patientForm);
      setIsCreateOpen(false);
      setPatientForm(EMPTY_PATIENT_FORM);
      await loadPatients(search);
      setSelectedPatient(response.data);
      await loadTreatments(response.data.id);
      setSuccessMessage(
        `Patient ${response.data.firstName} ${response.data.lastName} was saved successfully.`,
      );
    } catch (error: any) {
      const message = Array.isArray(error?.message) ? error.message.join(', ') : error?.message;
      setErrorMessage(message || '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);
    setErrorMessage('');
    setSuccessMessage('');
    try {
      await patientsApi.addTreatment(selectedPatient.id, payload);
      await loadTreatments(selectedPatient.id);
      setSuccessMessage('Treatment entry added successfully.');
    } catch (error: any) {
      const message = Array.isArray(error?.message) ? error.message.join(', ') : error?.message;
      setErrorMessage(message || 'Failed to add treatment entry.');
    } finally {
      setSavingTreatment(false);
    }
  }

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

      <CreatePatientModal
        isOpen={isCreateOpen}
        formData={patientForm}
        onChange={(patch) => setPatientForm((prev) => ({ ...prev, ...patch }))}
        onSubmit={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>

      {(errorMessage || successMessage) && (
        <div className="absolute bottom-0 left-0 right-0 z-10 w-full">
          {errorMessage && (
            <div className="rounded-[var(--radius-sm)] border border-red-500/50 bg-red-500/10 px-3 py-2 text-sm text-red-300 shadow-lg">
              {errorMessage}
            </div>
          )}
          {successMessage && (
            <div className="rounded-[var(--radius-sm)] border border-emerald-500/50 bg-emerald-500/10 px-3 py-2 text-sm text-emerald-300 shadow-lg">
              {successMessage}
            </div>
          )}
        </div>
      )}
    </div>
  );
}
