import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { formatDate, formatDatetime, usePatient } from '@openmrs/esm-framework';
import { usePatientAppointmentHistory } from '../../hooks/usePatientAppointmentHistory';
import { getGender } from '../../helpers';
import { type Appointment } from '../../types';
import styles from './appointment-details.scss';

interface AppointmentDetailsProps {
  appointment: Appointment;
}

const AppointmentDetails: React.FC<AppointmentDetailsProps> = ({ appointment }) => {
  const { t } = useTranslation();
  const [isEnabledQuery, setIsEnabledQuery] = useState(false);
  const { appointmentsCount, isLoading } = usePatientAppointmentHistory(appointment.patient.uuid);
  const { patient } = usePatient(appointment.patient.uuid);

  useEffect(() => {
    if (!isLoading) {
      setIsEnabledQuery(true);
    }
  }, [appointmentsCount, isLoading]);

  const patientName =
    Array.isArray(patient?.name) && patient.name.length > 0
      ? [...(Array.isArray(patient.name[0].given) ? patient.name[0].given : []), patient.name[0].family]
          .filter(Boolean)
          .join(' ')
      : appointment.patient?.name || '--';

  const patientIdentifier =
    Array.isArray(patient?.identifier) && patient.identifier.length > 0
      ? patient.identifier[0].value || '--'
      : appointment.patient?.identifiers?.[0]?.identifier || appointment.patient?.identifier || '--';

  const getPatientAge = () => {
    if (appointment.patient?.person?.age !== undefined && appointment.patient.person.age !== null) {
      return appointment.patient.person.age;
    }

    if (appointment.patient?.age !== undefined && appointment.patient.age !== null) {
      return appointment.patient.age;
    }

    const birthdate = patient?.birthDate || appointment.patient?.person?.birthdate || appointment.patient?.birthdate;
    if (birthdate) {
      const birthDateObj = new Date(typeof birthdate === 'number' ? birthdate : birthdate);
      return Math.floor((Date.now() - birthDateObj.getTime()) / (365.25 * 24 * 60 * 60 * 1000));
    }

    return null;
  };

  const patientAge = getPatientAge();

  const getPatientGender = () => {
    if (appointment.patient?.person?.gender) {
      return appointment.patient.person.gender;
    }

    if (appointment.patient?.gender) {
      return appointment.patient.gender;
    }

    if (patient?.gender) {
      return patient.gender;
    }

    return null;
  };

  const patientGender = getPatientGender();

  const getNotesValue = () => {
    const noteValue = appointment.note;
    if (noteValue && typeof noteValue === 'string' && noteValue.trim() !== '') {
      return noteValue.trim();
    }

    const commentsValue = appointment.comments;
    if (commentsValue && typeof commentsValue === 'string' && commentsValue.trim() !== '') {
      return commentsValue.trim();
    }

    return null;
  };

  const appointmentNotes = getNotesValue();

  return (
    <div className={styles.appointmentDetailsContainer}>
      <p className={styles.title}>{appointment.service?.name || appointment.appointmentService?.name || '--'}</p>
      <p className={styles.subTitle}>
        {appointment.appointmentDate ? formatDatetime(new Date(appointment.appointmentDate)) : '--'}
      </p>

      <div className={styles.patientInfoGrid}>
        <div>
          <p className={styles.gridTitle}>{t('patientDetails', 'Patient details')}</p>
          <div className={styles.labelContainer}>
            <p className={styles.labelBold}>{t('patientName', 'Patient name')}: </p>
            <p className={styles.label}>{patientName}</p>
          </div>
          <div className={styles.labelContainer}>
            <p className={styles.labelBold}>{t('identifier', 'Identifier')}: </p>
            <p className={styles.label}>{patientIdentifier}</p>
          </div>
          <div className={styles.labelContainer}>
            <p className={styles.labelBold}>{t('age', 'Age')}: </p>
            <p className={styles.label}>{patientAge !== null ? patientAge : '--'}</p>
          </div>
          <div className={styles.labelContainer}>
            <p className={styles.labelBold}>{t('gender', 'Gender')}: </p>
            <p className={styles.label}>{patientGender ? getGender(patientGender, t) : '--'}</p>
          </div>
          {patient && patient?.birthDate ? (
            <div className={styles.labelContainer}>
              <p className={styles.labelBold}>{t('dateOfBirth', 'Date of birth')}: </p>
              <p className={styles.label}>{formatDate(new Date(patient.birthDate))}</p>
            </div>
          ) : (
            ''
          )}
          {patient && patient?.telecom
            ? patient.telecom.map((contact, i) => (
                <div key={i} className={styles.labelContainer}>
                  <p className={styles.labelBold}>{t('Contact', 'Contact {{index}}', { index: i + 1 })}: </p>
                  <p className={styles.label}>{contact.value}</p>
                </div>
              ))
            : ''}
        </div>
        <div>
          <p className={styles.gridTitle}>{t('appointmentNotes', 'Appointment Notes')}</p>
          <p className={styles.label}>{appointmentNotes || t('noNotesAvailable', 'No notes available')}</p>
        </div>
        <div>
          <p className={styles.gridTitle}>{t('appointmentHistory', 'Appointment History')}</p>
          <div className={styles.historyGrid}>
            <div>
              <p className={styles.historyGridLabel}>{t('completed', 'Completed')}</p>
              <span className={styles.historyGridCount}>{appointmentsCount.completedAppointments}</span>
            </div>
            <div>
              <p className={styles.historyGridLabel}>{t('missed', 'Missed')}</p>
              <span className={styles.historyGridCountRed}>{appointmentsCount.missedAppointments}</span>
            </div>
            <div>
              <p className={styles.historyGridLabel}>{t('cancelled', 'Cancelled')}</p>
              <span className={styles.historyGridCount}>{appointmentsCount.cancelledAppointments}</span>
            </div>
            <div>
              <p className={styles.historyGridLabel}>{t('upcoming', 'Upcoming')}</p>
              <span className={styles.historyGridCount}>{appointmentsCount.upcomingAppointments}</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

export default AppointmentDetails;
