'use client';

import { useEffect, useState } from 'react';
import { useTranslations } from 'next-intl';
import { Button } from '@/components/ui/shared/Button';
import { DialogCloseButton } from '@/components/ui/shared/DialogCloseButton';
import { Dropdown } from '@/components/ui/shared/Dropdown';
import type { AppointmentPurpose, AppointmentRecord } from '@/types/appointment';
import { APPOINTMENT_PURPOSES } from '@/types/appointment';
import { getPurposeLabel } from '@/components/ui/appointments/appointmentPurposeStyles';
import type { Patient } from '@/types/patient';
import {
  combineLocalDateAndTime,
  compareLocalDayStart,
  formatTimeForInput,
  isSameLocalCalendarDay,
} from '@/components/appointments/appointmentTime';

interface AppointmentBookingModalProps {
  open: boolean;
  scheduleDate: Date;
  patient: Patient | undefined;
  providerUserId: string | null;
  providerName: string;
  initialStartMinute: number;
  onClose: () => void;
  onSubmit: (payload: {
    patientId: string;
    providerUserId: string;
    startAt: string;
    endAt: string;
    purpose: AppointmentPurpose;
  }) => Promise<void>;
  editingAppointment?: AppointmentRecord | null;
  loading?: boolean;
  canDelete?: boolean;
  onDelete?: () => void | Promise<void>;
  deleting?: boolean;
}

const PURPOSE_OPTION_COLORS: Record<AppointmentPurpose, string> = {
  consultation: '#ddd6fe',
  filling: '#fed7aa',
  endo: '#fecaca',
  visit: '#bae6fd',
  hygiene: '#d9f99d',
};

export function AppointmentBookingModal({
  open,
  scheduleDate,
  patient,
  providerUserId,
  providerName,
  initialStartMinute,
  onClose,
  onSubmit,
  editingAppointment = null,
  loading = false,
  canDelete = false,
  onDelete,
  deleting = false,
}: AppointmentBookingModalProps) {
  const t = useTranslations('appointments');
  const tCommon = useTranslations('common');
  const tPatients = useTranslations('patients');

  const [startTime, setStartTime] = useState('09:00');
  const [endTime, setEndTime] = useState('10:00');
  const [purpose, setPurpose] = useState<AppointmentPurpose>('consultation');
  const [error, setError] = useState('');
  const purposeTextColor = PURPOSE_OPTION_COLORS[purpose];

  useEffect(() => {
    if (!open) {
      return;
    }
    if (editingAppointment) {
      const start = new Date(editingAppointment.startAt);
      const end = new Date(editingAppointment.endAt);
      setStartTime(formatTimeForInput(start));
      setEndTime(formatTimeForInput(end));
      setPurpose((editingAppointment.purpose as AppointmentPurpose) ?? 'consultation');
    } else {
      const start = new Date(
        scheduleDate.getFullYear(),
        scheduleDate.getMonth(),
        scheduleDate.getDate(),
        Math.floor(initialStartMinute / 60),
        initialStartMinute % 60,
        0,
        0,
      );
      const endMinute = Math.min(initialStartMinute + 60, 24 * 60 - 1);
      const end = new Date(
        scheduleDate.getFullYear(),
        scheduleDate.getMonth(),
        scheduleDate.getDate(),
        Math.floor(endMinute / 60),
        endMinute % 60,
        0,
        0,
      );
      setStartTime(formatTimeForInput(start));
      setEndTime(formatTimeForInput(end));
      setPurpose('consultation');
    }
    setError('');
  }, [open, scheduleDate, initialStartMinute, editingAppointment]);

  if (!open || !providerUserId) {
    return null;
  }

  const inputClass =
    'w-full rounded-[var(--radius-md)] border border-border bg-background-secondary/90 text-text-primary px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/35';

  async function handleSubmit() {
    setError('');
    if (!providerUserId) {
      return;
    }
    if (!editingAppointment && !patient) {
      setError(t('errorSelectPatient'));
      return;
    }

    const startAt = combineLocalDateAndTime(scheduleDate, startTime);
    const endAt = combineLocalDateAndTime(scheduleDate, endTime);

    if (endAt <= startAt) {
      setError(t('errorEndAfterStart'));
      return;
    }

    const now = new Date();
    if (isSameLocalCalendarDay(scheduleDate, now) && startAt.getTime() < now.getTime()) {
      setError(t('errorPastSchedule'));
      return;
    }

    const today = new Date();
    if (compareLocalDayStart(scheduleDate, today) < 0) {
      setError(t('errorPastViewOnly'));
      return;
    }

    const effectivePatientId = editingAppointment?.patientId ?? patient?.id;
    const effectiveProviderId = editingAppointment?.providerUserId ?? providerUserId;
    if (!effectivePatientId || !effectiveProviderId) {
      setError(t('errorMissingDetails'));
      return;
    }

    await onSubmit({
      patientId: effectivePatientId,
      providerUserId: effectiveProviderId,
      startAt: startAt.toISOString(),
      endAt: endAt.toISOString(),
      purpose,
    });
  }

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/55">
      <div
        className="surface-card w-full max-w-md p-5 space-y-4 shadow-xl"
        role="dialog"
        aria-modal="true"
        aria-labelledby="appointment-modal-title"
      >
        <div className="flex items-start justify-between gap-2">
          <h2 id="appointment-modal-title" className="text-lg font-semibold text-text-primary pr-2">
            {editingAppointment ? t('editTitle') : t('newTitle')}
          </h2>
          <DialogCloseButton onClick={onClose} />
        </div>

        <p className="text-sm text-text-secondary">
          {t('providerLabel')}{' '}
          <span className="text-text-primary font-medium">{providerName}</span>
        </p>

        <div>
          <label className="block text-sm font-medium text-text-secondary mb-1">
            {t('patientLabel')}
          </label>
          <p className="text-sm text-text-primary rounded-[var(--radius-md)] border border-border bg-background-secondary/60 px-3 py-2">
            {editingAppointment
              ? `${editingAppointment.patient.firstName} ${editingAppointment.patient.lastName}`
              : patient
                ? `${patient.firstName} ${patient.lastName}`
                : tPatients('emptyValue')}
          </p>
        </div>

        <div className="grid grid-cols-2 gap-3">
          <div>
            <label className="block text-sm font-medium text-text-secondary mb-1">
              {t('startLabel')}
            </label>
            <input
              type="time"
              step={60}
              className={inputClass}
              value={startTime}
              onChange={(e) => setStartTime(e.target.value)}
            />
          </div>
          <div>
            <label className="block text-sm font-medium text-text-secondary mb-1">
              {t('endLabel')}
            </label>
            <input
              type="time"
              step={60}
              className={inputClass}
              value={endTime}
              onChange={(e) => setEndTime(e.target.value)}
            />
          </div>
        </div>

        <Dropdown
          label={t('purposeLabel')}
          value={purpose}
          onChange={(e) => setPurpose(e.target.value as AppointmentPurpose)}
          style={{ color: purposeTextColor }}
        >
          {APPOINTMENT_PURPOSES.map((purposeOption) => (
            <option
              key={purposeOption}
              value={purposeOption}
              style={{ color: PURPOSE_OPTION_COLORS[purposeOption], backgroundColor: '#14253d' }}
            >
              {getPurposeLabel(purposeOption, t)}
            </option>
          ))}
        </Dropdown>

        {error && <p className="text-sm text-red-400">{error}</p>}

        <div className="flex flex-wrap items-center gap-2 justify-between">
          {editingAppointment && canDelete && onDelete ? (
            <Button
              type="button"
              variant="danger"
              onClick={() => void onDelete()}
              disabled={loading || deleting}
              isLoading={deleting}
            >
              {tCommon('delete')}
            </Button>
          ) : (
            <span />
          )}
          <div className="flex gap-2 ml-auto">
            <Button type="button" variant="ghost" onClick={onClose} disabled={loading || deleting}>
              {tCommon('cancel')}
            </Button>
            <Button
              type="button"
              variant="primary"
              onClick={() => void handleSubmit()}
              isLoading={loading}
              disabled={deleting}
            >
              {tCommon('save')}
            </Button>
          </div>
        </div>
      </div>
    </div>
  );
}
