import { useState } from 'react';
import { useFormik } from 'formik';
import { z } from 'zod';
import { CalendarDays, Clock, ClipboardList, CheckCircle2, AlertCircle, Loader2 } from 'lucide-react';
import { useAuth } from '../context/AuthContext';
import { useCreateReservation } from '../hooks/useCreateReservation';
import { useServices } from '../hooks/useServices';
import { useSlotReservations } from '../hooks/useSlotReservations';
import styles from './BookingForm.module.scss';

const todayISO = () => new Date().toISOString().split('T')[0];

const baseSchema = z.object({
  serviceId: z.string().min(1, 'Please select a service.'),
  date: z
    .string()
    .min(1, 'Date is required.')
    .refine((v) => v >= todayISO(), 'Date cannot be in the past.'),
  time: z.string().min(1, 'Time is required.'),
  specialRequirements: z.string().max(500, 'Maximum 500 characters allowed.'),
});

const BookingForm = () => {
  const { user } = useAuth();
  const [submitStatus, setSubmitStatus] = useState(null);

  const { data: services = [], isLoading: servicesLoading, isError: servicesError } = useServices();

  const { mutate: createReservation, isPending } = useCreateReservation({
    onSuccess: () => { setSubmitStatus('success'); formik.resetForm(); },
    onError:   () => setSubmitStatus('error'),
  });

  const formik = useFormik({
    initialValues: { serviceId: '', date: '', time: '', specialRequirements: '' },
    validate: (values) => {
      const result = baseSchema.safeParse(values);
      const errors = {};
      if (!result.success) {
        result.error.issues.forEach(({ path, message }) => {
          const key = path[0];
          if (key && !errors[key]) errors[key] = message;
        });
      }
      if (values.time && bookedTimes.includes(values.time)) {
        errors.time = `${values.time} is already booked for this service and date.`;
      }
      return errors;
    },
    onSubmit: ({ serviceId, date, time, specialRequirements }) => {
      setSubmitStatus(null);
      createReservation({
        userId: user.id,
        serviceId,
        date,
        time,
        specialRequirements: specialRequirements.trim() || null,
        status: 'pending',
      });
    },
  });

  const { data: slotReservations = [] } = useSlotReservations(
    formik.values.serviceId,
    formik.values.date,
  );
  const bookedTimes = slotReservations
    .filter((r) => r.status !== 'cancelled')
    .map((r) => r.time);

  return (
    <div className={styles['booking-form']}>
      <div className={styles['booking-form__header']}>
        <ClipboardList size={24} className={styles['booking-form__icon']} />
        <div>
          <h2 className={styles['booking-form__title']}>Book a Service</h2>
          <p className={styles['booking-form__subtitle']}>
            Fill in the details below to request a reservation.
          </p>
        </div>
      </div>

      {submitStatus === 'success' && (
        <div
          className={[styles['booking-form__banner'], styles['booking-form__banner--success']].join(' ')}
          role="status"
        >
          <CheckCircle2 size={18} />
          <span>
            Your reservation was submitted successfully and is{' '}
            <strong>pending confirmation</strong>.
          </span>
        </div>
      )}

      {submitStatus === 'error' && (
        <div
          className={[styles['booking-form__banner'], styles['booking-form__banner--error']].join(' ')}
          role="alert"
        >
          <AlertCircle size={18} />
          <span>Something went wrong. Make sure the API server is running and try again.</span>
        </div>
      )}

      <form
        className={styles['booking-form__body']}
        onSubmit={formik.handleSubmit}
        noValidate
      >
        {/* Service */}
        <div className={styles['booking-form__field']}>
          <label htmlFor="serviceId" className={styles['booking-form__label']}>
            Service <span className={styles['booking-form__required']}>*</span>
          </label>
          {servicesError ? (
            <p className={styles['booking-form__field-error']}>
              Failed to load services. Start the API server.
            </p>
          ) : (
            <div className={styles['booking-form__select-wrapper']}>
              <select
                id="serviceId"
                className={[
                  styles['booking-form__select'],
                  formik.touched.serviceId && formik.errors.serviceId
                    ? styles['booking-form__select--error']
                    : '',
                ].join(' ')}
                disabled={servicesLoading}
                {...formik.getFieldProps('serviceId')}
              >
                <option value="">
                  {servicesLoading ? 'Loading services...' : '-- Select a service --'}
                </option>
                {services.map((s) => (
                  <option key={s.id} value={s.id}>
                    {s.name} -- ${s.price} / {s.duration} min
                  </option>
                ))}
              </select>
            </div>
          )}
          {formik.touched.serviceId && formik.errors.serviceId && (
            <p className={styles['booking-form__field-error']}>{formik.errors.serviceId}</p>
          )}
        </div>

        {/* Date + Time */}
        <div className={styles['booking-form__row']}>
          <div className={styles['booking-form__field']}>
            <label htmlFor="date" className={styles['booking-form__label']}>
              <CalendarDays size={15} className={styles['booking-form__label-icon']} />
              Date <span className={styles['booking-form__required']}>*</span>
            </label>
            <input
              id="date"
              type="date"
              className={[
                styles['booking-form__input'],
                formik.touched.date && formik.errors.date ? styles['booking-form__input--error'] : '',
              ].join(' ')}
              min={todayISO()}
              {...formik.getFieldProps('date')}
            />
            {formik.touched.date && formik.errors.date && (
              <p className={styles['booking-form__field-error']}>{formik.errors.date}</p>
            )}
          </div>

          <div className={styles['booking-form__field']}>
            <label htmlFor="time" className={styles['booking-form__label']}>
              <Clock size={15} className={styles['booking-form__label-icon']} />
              Time <span className={styles['booking-form__required']}>*</span>
            </label>
            <input
              id="time"
              type="time"
              className={[
                styles['booking-form__input'],
                formik.touched.time && formik.errors.time ? styles['booking-form__input--error'] : '',
              ].join(' ')}
              {...formik.getFieldProps('time')}
            />
            {formik.touched.time && formik.errors.time && (
              <p className={styles['booking-form__field-error']}>{formik.errors.time}</p>
            )}
            {bookedTimes.length > 0 && !(formik.touched.time && formik.errors.time) && (
              <p className={styles['booking-form__hint']}>
                Occupied: {bookedTimes.join(', ')}
              </p>
            )}
          </div>
        </div>

        {/* Special Requirements */}
        <div className={styles['booking-form__field']}>
          <label htmlFor="specialRequirements" className={styles['booking-form__label']}>
            Special Requirements
            <span className={styles['booking-form__optional']}>(optional)</span>
          </label>
          <textarea
            id="specialRequirements"
            className={styles['booking-form__textarea']}
            rows={4}
            placeholder="Any accessibility needs, preferences, or notes for the service provider..."
            {...formik.getFieldProps('specialRequirements')}
          />
          {formik.touched.specialRequirements && formik.errors.specialRequirements && (
            <p className={styles['booking-form__field-error']}>
              {formik.errors.specialRequirements}
            </p>
          )}
        </div>

        <div className={styles['booking-form__actions']}>
          <button
            type="button"
            className={[styles['booking-form__btn'], styles['booking-form__btn--secondary']].join(' ')}
            onClick={() => { formik.resetForm(); setSubmitStatus(null); }}
            disabled={isPending}
          >
            Clear
          </button>
          <button
            type="submit"
            className={[styles['booking-form__btn'], styles['booking-form__btn--primary']].join(' ')}
            disabled={isPending || servicesLoading || formik.isSubmitting}
          >
            {isPending ? (
              <>
                <Loader2 size={16} className={styles['booking-form__spinner']} />
                Submitting...
              </>
            ) : 'Request Booking'}
          </button>
        </div>
      </form>
    </div>
  );
};

export default BookingForm;
