import React, { useState, useEffect, useRef } from 'react';
import { Medication, Frequency } from '../../types';
import { medicationIcons } from '../icons/Icons';

interface EditMedicationModalProps {
  isOpen: boolean;
  onClose: () => void;
  medication: Medication | null;
  onUpdate: (medication: Medication) => Promise<void>;
}

const EditMedicationModal: React.FC<EditMedicationModalProps> = ({
  isOpen,
  onClose,
  medication,
  onUpdate,
}) => {
  const [name, setName] = useState('');
  const [dosage, setDosage] = useState('');
  const [frequency, setFrequency] = useState<Frequency>(Frequency.Daily);
  const [hoursBetween, setHoursBetween] = useState(8);
  const [startTime, setStartTime] = useState('09:00');
  const [notes, setNotes] = useState('');
  const [icon, setIcon] = useState('pill');
  const [isSaving, setIsSaving] = useState(false);

  const modalRef = useRef<HTMLDivElement>(null);
  const nameInputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    if (medication) {
      setName(medication.name);
      setDosage(medication.dosage);
      setFrequency(medication.frequency);
      setHoursBetween(medication.hoursBetween || 8);
      setStartTime(medication.startTime);
      setNotes(medication.notes || '');
      setIcon(medication.icon || 'pill');
      setIsSaving(false);
    }
    if (isOpen) {
      setTimeout(() => nameInputRef.current?.focus(), 100);
    }
  }, [medication, isOpen]);

  useEffect(() => {
    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === 'Escape' && !isSaving) onClose();
    };
    if (isOpen) {
      window.addEventListener('keydown', handleKeyDown);
    }
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [isOpen, onClose, isSaving]);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!medication || !name || !dosage || !startTime || isSaving) {
      return;
    }
    setIsSaving(true);
    try {
      await onUpdate({
        ...medication,
        name,
        dosage,
        frequency,
        hoursBetween:
          frequency === Frequency.EveryXHours ? hoursBetween : undefined,
        startTime,
        notes,
        icon,
      });
    } catch (error) {
      console.error('Failed to update medication', error);
      alert('There was an error updating your medication. Please try again.');
      setIsSaving(false);
    }
  };

  if (!isOpen) return null;

  return (
    <div
      className='fixed inset-0 bg-black bg-opacity-50 dark:bg-opacity-70 z-50 flex justify-center items-center p-4'
      role='dialog'
      aria-modal='true'
      aria-labelledby='edit-med-title'
    >
      <div
        className='bg-white dark:bg-slate-800 rounded-lg shadow-xl w-full max-w-md'
        ref={modalRef}
      >
        <div className='p-6 border-b border-slate-200 dark:border-slate-700'>
          <h3
            id='edit-med-title'
            className='text-xl font-semibold text-slate-800 dark:text-slate-100'
          >
            Edit Medication
          </h3>
        </div>
        <form onSubmit={handleSubmit}>
          <div className='p-6 space-y-4 max-h-[70vh] overflow-y-auto'>
            <div>
              <label
                htmlFor='edit-name'
                className='block text-sm font-medium text-slate-700 dark:text-slate-300'
              >
                Medication Name
              </label>
              <input
                type='text'
                id='edit-name'
                value={name}
                onChange={e => setName(e.target.value)}
                required
                ref={nameInputRef}
                className='mt-1 block w-full px-3 py-2 border border-slate-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm bg-white dark:bg-slate-700 dark:border-slate-600 dark:placeholder-slate-400 dark:text-white'
              />
            </div>
            <div>
              <label
                htmlFor='edit-dosage'
                className='block text-sm font-medium text-slate-700 dark:text-slate-300'
              >
                Dosage (e.g., "1 tablet", "500mg")
              </label>
              <input
                type='text'
                id='edit-dosage'
                value={dosage}
                onChange={e => setDosage(e.target.value)}
                required
                className='mt-1 block w-full px-3 py-2 border border-slate-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm bg-white dark:bg-slate-700 dark:border-slate-600 dark:placeholder-slate-400 dark:text-white'
              />
            </div>
            <div>
              <label
                htmlFor='edit-frequency'
                className='block text-sm font-medium text-slate-700 dark:text-slate-300'
              >
                Frequency
              </label>
              <select
                id='edit-frequency'
                value={frequency}
                onChange={e => setFrequency(e.target.value as Frequency)}
                className='mt-1 block w-full px-3 py-2 border border-slate-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm dark:bg-slate-700 dark:border-slate-600 dark:text-white'
              >
                {Object.values(Frequency).map(f => (
                  <option key={f} value={f}>
                    {f}
                  </option>
                ))}
              </select>
            </div>
            {frequency === Frequency.EveryXHours && (
              <div>
                <label
                  htmlFor='edit-hoursBetween'
                  className='block text-sm font-medium text-slate-700 dark:text-slate-300'
                >
                  Hours Between Doses
                </label>
                <input
                  type='number'
                  id='edit-hoursBetween'
                  value={hoursBetween}
                  onChange={e => setHoursBetween(parseInt(e.target.value, 10))}
                  min='1'
                  max='23'
                  className='mt-1 block w-full px-3 py-2 border border-slate-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm bg-white dark:bg-slate-700 dark:border-slate-600 dark:placeholder-slate-400 dark:text-white'
                />
              </div>
            )}
            <div>
              <label
                htmlFor='edit-startTime'
                className='block text-sm font-medium text-slate-700 dark:text-slate-300'
              >
                First Dose Time
              </label>
              <input
                type='time'
                id='edit-startTime'
                value={startTime}
                onChange={e => setStartTime(e.target.value)}
                required
                className='mt-1 block w-full px-3 py-2 border border-slate-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm bg-white dark:bg-slate-700 dark:border-slate-600 dark:placeholder-slate-400 dark:text-white'
              />
            </div>
            <div>
              <label className='block text-sm font-medium text-slate-700 dark:text-slate-300'>
                Icon
              </label>
              <div className='mt-2 flex flex-wrap gap-2'>
                {Object.entries(medicationIcons).map(([key, IconComponent]) => (
                  <button
                    key={key}
                    type='button'
                    onClick={() => setIcon(key)}
                    className={`p-2 rounded-full transition-colors ${icon === key ? 'bg-indigo-600 text-white ring-2 ring-offset-2 ring-indigo-500 ring-offset-white dark:ring-offset-slate-800' : 'bg-slate-100 text-slate-600 hover:bg-slate-200 dark:bg-slate-700 dark:text-slate-300 dark:hover:bg-slate-600'}`}
                    aria-label={`Select ${key} icon`}
                  >
                    <IconComponent className='w-6 h-6' />
                  </button>
                ))}
              </div>
            </div>
            <div>
              <label
                htmlFor='edit-notes'
                className='block text-sm font-medium text-slate-700 dark:text-slate-300'
              >
                Notes (optional)
              </label>
              <textarea
                id='edit-notes'
                value={notes}
                onChange={e => setNotes(e.target.value)}
                rows={3}
                className='mt-1 block w-full px-3 py-2 border border-slate-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm bg-white dark:bg-slate-700 dark:border-slate-600 dark:placeholder-slate-400 dark:text-white'
                placeholder='e.g., take with food'
              ></textarea>
            </div>
          </div>
          <div className='px-6 py-4 bg-slate-50 dark:bg-slate-700/50 flex justify-end space-x-3 rounded-b-lg border-t border-slate-200 dark:border-slate-700'>
            <button
              type='button'
              onClick={onClose}
              disabled={isSaving}
              className='px-4 py-2 text-sm font-medium text-slate-700 bg-white border border-slate-300 rounded-md shadow-sm hover:bg-slate-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:bg-slate-700 dark:text-slate-200 dark:border-slate-600 dark:hover:bg-slate-600 dark:focus:ring-offset-slate-800 disabled:opacity-50'
            >
              Cancel
            </button>
            <button
              type='submit'
              disabled={isSaving}
              className='px-4 py-2 text-sm font-medium text-white bg-indigo-600 border border-transparent rounded-md shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-slate-800 disabled:opacity-50 disabled:cursor-not-allowed flex items-center'
            >
              {isSaving && <Spinner />}
              {isSaving ? 'Saving...' : 'Save Changes'}
            </button>
          </div>
        </form>
      </div>
    </div>
  );
};

const Spinner = () => (
  <svg
    className='animate-spin -ml-1 mr-3 h-5 w-5 text-white'
    xmlns='http://www.w3.org/2000/svg'
    fill='none'
    viewBox='0 0 24 24'
  >
    <circle
      className='opacity-25'
      cx='12'
      cy='12'
      r='10'
      stroke='currentColor'
      strokeWidth='4'
    ></circle>
    <path
      className='opacity-75'
      fill='currentColor'
      d='M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z'
    ></path>
  </svg>
);

export default EditMedicationModal;
