import { useState, useMemo } from 'react';
import { CalendarDays } from 'lucide-react';
import { GradientButton } from '../ui/GradientButton';
import { api } from '../../api/client';
import type { RentalListing, RentalPeriodType, Booking } from '../../types/rental';
import { formatCurrency } from '../../utils/format';

interface BookingFormProps {
  rental: RentalListing;
  onSuccess?: () => void;
}

export function BookingForm({ rental, onSuccess }: BookingFormProps) {
  const hasDailyPrice = rental.dailyPrice != null;
  const hasMonthlyPrice = rental.monthlyPrice != null;

  const defaultPeriod: RentalPeriodType = hasDailyPrice ? 'DAILY' : 'MONTHLY';

  const [periodType, setPeriodType] = useState<RentalPeriodType>(defaultPeriod);
  const [startDate, setStartDate] = useState('');
  const [endDate, setEndDate] = useState('');
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const priceEstimate = useMemo(() => {
    if (!startDate || !endDate) return null;

    const start = new Date(startDate);
    const end = new Date(endDate);
    if (end <= start) return null;

    const diffMs = end.getTime() - start.getTime();

    if (periodType === 'DAILY') {
      const days = Math.ceil(diffMs / (1000 * 60 * 60 * 24));
      if (days < 1 || rental.dailyPrice == null) return null;
      return { units: days, unitLabel: days === 1 ? 'day' : 'days', unitPrice: rental.dailyPrice, total: days * rental.dailyPrice };
    } else {
      const months = Math.max(1, Math.round(diffMs / (1000 * 60 * 60 * 24 * 30)));
      if (rental.monthlyPrice == null) return null;
      return { units: months, unitLabel: months === 1 ? 'month' : 'months', unitPrice: rental.monthlyPrice, total: months * rental.monthlyPrice };
    }
  }, [startDate, endDate, periodType, rental.dailyPrice, rental.monthlyPrice]);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();

    if (!startDate || !endDate) {
      setError('Please select both start and end dates');
      return;
    }

    const start = new Date(startDate);
    const end = new Date(endDate);
    if (end <= start) {
      setError('End date must be after start date');
      return;
    }

    setSubmitting(true);
    setError(null);

    try {
      await api.post<Booking>('/bookings', {
        rentalListingId: rental.id,
        periodType,
        startDate: new Date(startDate).toISOString(),
        endDate: new Date(endDate).toISOString(),
      });
      onSuccess?.();
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to submit booking request');
    } finally {
      setSubmitting(false);
    }
  };

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

  return (
    <form onSubmit={handleSubmit} className="bg-white rounded-2xl border border-gray-100 shadow-sm p-5">
      <div className="flex items-center gap-2 mb-4">
        <CalendarDays className="w-5 h-5 text-primary-500" />
        <h3 className="text-lg font-bold text-gray-900">Book this Rental</h3>
      </div>

      {/* Period Type Selector */}
      {hasDailyPrice && hasMonthlyPrice && (
        <div className="mb-4">
          <label className="block text-sm font-medium text-gray-700 mb-1.5">Rental Period</label>
          <div className="flex rounded-xl border border-gray-200 overflow-hidden">
            <button
              type="button"
              onClick={() => setPeriodType('DAILY')}
              className={`flex-1 py-2.5 text-sm font-medium transition-colors cursor-pointer
                ${periodType === 'DAILY'
                  ? 'bg-primary-600 text-white'
                  : 'bg-white text-gray-600 hover:bg-gray-50'}`}
            >
              Daily ({formatCurrency(rental.dailyPrice!)}/day)
            </button>
            <button
              type="button"
              onClick={() => setPeriodType('MONTHLY')}
              className={`flex-1 py-2.5 text-sm font-medium transition-colors cursor-pointer
                ${periodType === 'MONTHLY'
                  ? 'bg-primary-600 text-white'
                  : 'bg-white text-gray-600 hover:bg-gray-50'}`}
            >
              Monthly ({formatCurrency(rental.monthlyPrice!)}/mo)
            </button>
          </div>
        </div>
      )}

      {/* Date Pickers */}
      <div className="grid grid-cols-2 gap-3 mb-4">
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1.5">Start Date</label>
          <input
            type="date"
            value={startDate}
            onChange={e => setStartDate(e.target.value)}
            min={todayStr}
            className="w-full rounded-xl border border-gray-200 bg-white px-4 py-2.5 text-sm text-gray-900
              focus:border-primary-400 focus:ring-2 focus:ring-primary-100 focus:outline-none transition-all duration-200"
          />
        </div>
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1.5">End Date</label>
          <input
            type="date"
            value={endDate}
            onChange={e => setEndDate(e.target.value)}
            min={startDate || todayStr}
            className="w-full rounded-xl border border-gray-200 bg-white px-4 py-2.5 text-sm text-gray-900
              focus:border-primary-400 focus:ring-2 focus:ring-primary-100 focus:outline-none transition-all duration-200"
          />
        </div>
      </div>

      {/* Price Calculation */}
      {priceEstimate && (
        <div className="mb-4 bg-gray-50 rounded-xl p-4 border border-gray-100">
          <div className="flex items-center justify-between text-sm text-gray-600 mb-1">
            <span>
              {formatCurrency(priceEstimate.unitPrice)} x {priceEstimate.units} {priceEstimate.unitLabel}
            </span>
            <span>{formatCurrency(priceEstimate.total)}</span>
          </div>
          <div className="flex items-center justify-between pt-2 border-t border-gray-200 mt-2">
            <span className="text-sm font-semibold text-gray-900">Estimated Total</span>
            <span className="text-lg font-bold text-primary-600">{formatCurrency(priceEstimate.total)}</span>
          </div>
        </div>
      )}

      {error && (
        <p className="mb-3 text-sm text-red-500">{error}</p>
      )}

      <GradientButton
        type="submit"
        isLoading={submitting}
        disabled={submitting || !startDate || !endDate}
        className="w-full"
      >
        Request Booking
      </GradientButton>

      <p className="mt-2 text-xs text-gray-400 text-center">
        You won't be charged until the landlord confirms your booking.
      </p>
    </form>
  );
}
