import React, { useState, useEffect, useRef, useMemo } from 'react';
import { Link } from 'react-router-dom';
import {
  Calendar,
  MapPin,
  Users,
  CreditCard,
  Eye,
  XCircle,
  AlertCircle,
  Search,
  Filter,
} from 'lucide-react';
import { toast } from 'react-toastify';
import {
  getMyBookings,
  type Booking,
} from '../../features/bookings/services/bookingService';
import CancelBookingModal from '../../features/bookings/components/CancelBookingModal';
import useAuthStore from '../../store/useAuthStore';
import Loading from '../../shared/components/Loading';
import EmptyState from '../../shared/components/EmptyState';
import { useFormatCurrency } from '../../features/payments/hooks/useFormatCurrency';
import { parseDateLocal } from '../../shared/utils/format';
import { getBookingStatusConfig, canCancelBooking } from '../../shared/utils/bookingUtils';

const MyBookingsPage: React.FC = () => {
  const { isAuthenticated } = useAuthStore();
  const { formatCurrency } = useFormatCurrency();

  const [bookings, setBookings] = useState<Booking[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [showCancelModal, setShowCancelModal] = useState(false);
  const [selectedBooking, setSelectedBooking] = useState<Booking | null>(null);
  const [searchQuery, setSearchQuery] = useState('');
  const [statusFilter, setStatusFilter] = useState<string>('all');
  const abortControllerRef = useRef<AbortController | null>(null);

  // Fetch bookings with request cancellation
  useEffect(() => {
    if (!isAuthenticated) {
      return;
    }

    // Cancel previous request if exists
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
    }

    // Create new abort controller
    abortControllerRef.current = new AbortController();

    fetchBookings();

    // Cleanup: abort request on unmount
    return () => {
      if (abortControllerRef.current) {
        abortControllerRef.current.abort();
      }
    };
  }, [isAuthenticated]);

  
  // Memoize filtered bookings to avoid recalculating on every render
  const filteredBookings = useMemo(() => {
    let filtered = [...bookings];

    // Filter by status
    if (statusFilter !== 'all') {
      filtered = filtered.filter(
        (b) => b.status === statusFilter
      );
    }

    // Filter by search query
    if (searchQuery.trim()) {
      const query = searchQuery.toLowerCase();
      filtered = filtered.filter(
        (b) =>
          b.booking_number.toLowerCase().includes(query) ||
          b.room?.room_type?.name
            .toLowerCase()
            .includes(query) ||
          b.room?.room_number
            .toString()
            .includes(query)
      );
    }

    return filtered;
  }, [bookings, statusFilter, searchQuery]);

  const fetchBookings = async () => {
    try {
      setLoading(true);
      setError(null);

      const response = await getMyBookings();

      if (response.success && response.data?.bookings) {
        setBookings(response.data.bookings);
      } else {
        throw new Error('Unable to load bookings list');
      }
    } catch (err: unknown) {
      const isAbortError = (e: unknown): boolean => {
        if (typeof e === 'object' && e !== null) {
          const error = e as { name?: string; code?: string };
          return error.name === 'AbortError' || error.code === 'ERR_CANCELED';
        }
        return false;
      };
      if (isAbortError(err)) {
        return;
      }

      const message =
        getUserFriendlyError(err) ||
        'Unable to load bookings list';
      setError(message);
      toast.error(message);
    } finally {
      setLoading(false);
    }
  };

  const handleCancelBookingClick = (booking: Booking) => {
    setSelectedBooking(booking);
    setShowCancelModal(true);
  };

  const handleCancelSuccess = () => {
    if (selectedBooking) {
      setBookings((prev) =>
        prev.map((b) =>
          b.id === selectedBooking.id
            ? { ...b, status: 'cancelled' }
            : b
        )
      );
    }
    setShowCancelModal(false);
    setSelectedBooking(null);
  };

  const formatDate = (dateString: string) => {
    
    const date = parseDateLocal(dateString);
    return date.toLocaleDateString('en-US', {
      weekday: 'short',
      year: 'numeric',
      month: 'short',
      day: 'numeric',
    });
  };

  const formatPrice = (price: number) => formatCurrency(price);

  if (loading) {
    return <Loading fullScreen text="Loading..." />;
  }

  return (
    <div className="min-h-screen bg-gray-50 py-8">
      <div className="max-w-7xl mx-auto px-4">
        {}
        <div className="mb-8">
          <h1 className="text-3xl font-bold text-gray-900 
            mb-2"
          >
            My Bookings
          </h1>
          <p className="text-gray-600">
            Manage and track your bookings
          </p>
        </div>

        {}
        <div className="bg-white rounded-lg shadow-md 
          p-4 mb-6"
        >
          <div className="flex flex-col md:flex-row gap-4">
            {}
            <div className="flex-1">
              <div className="relative">
                <Search 
                  className="absolute left-3 top-1/2 
                    -translate-y-1/2 w-5 h-5 
                    text-gray-400" 
                />
                <input
                  type="text"
                  placeholder="Search by booking number, room name..."
                  value={searchQuery}
                  onChange={(e) => 
                    setSearchQuery(e.target.value)
                  }
                  className="w-full pl-10 pr-4 py-2 border 
                    border-gray-300 rounded-lg 
                    focus:ring-2 focus:ring-indigo-500 
                    focus:border-indigo-500"
                />
              </div>
            </div>

            {}
            <div className="md:w-64">
              <div className="relative">
                <Filter 
                  className="absolute left-3 top-1/2 
                    -translate-y-1/2 w-5 h-5 
                    text-gray-400" 
                />
                <select
                  value={statusFilter}
                  onChange={(e) => 
                    setStatusFilter(e.target.value)
                  }
                  className="w-full pl-10 pr-4 py-2 border 
                    border-gray-300 rounded-lg 
                    focus:ring-2 focus:ring-indigo-500 
                    focus:border-indigo-500 
                    appearance-none bg-white"
                >
                  <option value="all">All statuses</option>
                  <option value="pending">Pending confirmation</option>
                  <option value="confirmed">Confirmed</option>
                  <option value="checked_in">
                    Checked in
                  </option>
                  <option value="checked_out">
                    Checked out
                  </option>
                  <option value="cancelled">Cancelled</option>
                </select>
              </div>
            </div>
          </div>

          {}
          <div className="mt-3 text-sm text-gray-600">
            Showing {filteredBookings.length} / 
            {bookings.length} bookings
          </div>
        </div>

        {}
        {error && (
          <div
            className="bg-red-50 border border-red-200 
              rounded-lg p-6 mb-6 flex items-start gap-3"
          >
            <AlertCircle 
              className="w-6 h-6 text-red-500 
                flex-shrink-0 mt-0.5" 
            />
            <div>
              <p className="text-red-700 font-medium">
                {error}
              </p>
              <button
                onClick={fetchBookings}
                className="mt-2 text-sm text-red-600 
                  hover:text-red-800 underline"
              >
                Try again
              </button>
            </div>
          </div>
        )}

        {}
        {filteredBookings.length === 0 ? (
          <EmptyState
            icon={Calendar}
            title={
              searchQuery || statusFilter !== 'all'
                ? 'No bookings found'
                : 'No bookings yet'
            }
            description={
              searchQuery || statusFilter !== 'all'
                ? 'Try changing filters or search keywords'
                : 'Start booking to enjoy your vacation'
            }
          >
            {!searchQuery && statusFilter === 'all' ? (
              <Link
                to="/rooms"
                className="inline-flex items-center 
                  gap-2 px-6 py-3 bg-indigo-600 
                  text-white rounded-lg 
                  hover:bg-indigo-700 
                  transition-colors font-semibold"
              >
                View room list
              </Link>
            ) : (
              <button
                onClick={() => {
                  setSearchQuery('');
                  setStatusFilter('all');
                }}
                className="px-6 py-3 bg-gray-600 
                  text-white rounded-lg 
                  hover:bg-gray-700 transition-colors 
                  font-semibold"
              >
                Clear filters
              </button>
            )}
          </EmptyState>
        ) : (
          <div className="space-y-4">
            {filteredBookings.map((booking) => {
              const statusConfig = getBookingStatusConfig(booking.status);
              const StatusIcon = statusConfig.icon;
              const room = booking.room;
              const roomType = room?.room_type;

              return (
                <div
                  key={booking.id}
                  className="bg-white rounded-lg shadow-md 
                    hover:shadow-lg transition-shadow 
                    overflow-hidden"
                >
                  <div className="p-6">
                    <div className="flex flex-col 
                      lg:flex-row gap-6"
                    >
                      {}
                      {((room?.room_type?.images && room.room_type.images.length > 0) 
                        ? room.room_type.images[0] 
                        : roomType?.images?.[0]) && (
                        <div className="lg:w-48 flex-shrink-0">
                          <img
                            src={(room?.room_type?.images && room.room_type.images.length > 0) 
                              ? room.room_type.images[0] 
                              : (roomType?.images?.[0] || '')}
                            alt={roomType?.name || 'Room'}
                            className="w-full h-48 lg:h-full 
                              object-cover rounded-lg"
                          />
                        </div>
                      )}

                      {}
                      <div className="flex-1 min-w-0">
                        {}
                        <div className="flex items-start 
                          justify-between gap-4 mb-3"
                        >
                          <div>
                            <h3 className="text-xl font-bold 
                              text-gray-900 mb-1"
                            >
                              {roomType?.name || 'N/A'}
                            </h3>
                            <p className="text-sm 
                              text-gray-600"
                            >
                              <MapPin 
                                className="w-4 h-4 inline 
                                  mr-1" 
                              />
                              Room {room?.room_number} - 
                              Floor {room?.floor}
                            </p>
                          </div>

                          {}
                          <div
                            className={`flex items-center 
                              gap-2 px-3 py-1.5 rounded-full 
                              text-sm font-medium 
                              ${statusConfig.color}`}
                          >
                            <StatusIcon 
                              className="w-4 h-4" 
                            />
                            {statusConfig.text}
                          </div>
                        </div>

                        {}
                        <div className="grid grid-cols-1 
                          sm:grid-cols-2 gap-3 mb-4"
                        >
                          {}
                          <div>
                            <p className="text-xs text-gray-500 
                              mb-1"
                            >
                              Booking number
                            </p>
                            <p className="font-medium 
                              text-gray-900 font-mono"
                            >
                              {booking.booking_number}
                            </p>
                          </div>

                          {}
                          <div>
                            <p className="text-xs text-gray-500 
                              mb-1"
                            >
                              <Calendar 
                                className="w-3 h-3 inline 
                                  mr-1" 
                              />
                              Check-in date
                            </p>
                            <p className="font-medium 
                              text-gray-900"
                            >
                              {formatDate(
                                booking.check_in_date
                              )}
                            </p>
                          </div>

                          {}
                          <div>
                            <p className="text-xs text-gray-500 
                              mb-1"
                            >
                              <Calendar 
                                className="w-3 h-3 inline 
                                  mr-1" 
                              />
                              Check-out date
                            </p>
                            <p className="font-medium 
                              text-gray-900"
                            >
                              {formatDate(
                                booking.check_out_date
                              )}
                            </p>
                          </div>

                          {}
                          <div>
                            <p className="text-xs text-gray-500 
                              mb-1"
                            >
                              <Users 
                                className="w-3 h-3 inline 
                                  mr-1" 
                              />
                              Guests
                            </p>
                            <p className="font-medium 
                              text-gray-900"
                            >
                              {booking.guest_count} guest(s)
                            </p>
                          </div>

                          {}
                          <div>
                            <p className="text-xs text-gray-500 
                              mb-1"
                            >
                              <CreditCard 
                                className="w-3 h-3 inline 
                                  mr-1" 
                              />
                              Payment
                            </p>
                            <p className="font-medium 
                              text-gray-900"
                            >
                              {booking.payment_method === 'cash'
                                ? 'On-site'
                                : 'Bank transfer'}
                            </p>
                          </div>

                          {}
                          <div>
                            <p className="text-xs text-gray-500 
                              mb-1"
                            >
                              Total price
                            </p>
                            <p className="font-bold 
                              text-indigo-600 text-lg"
                            >
                              {formatPrice(booking.total_price)}
                            </p>
                            {(() => {
                              const completedPayments = booking.payments?.filter(
                                (p) => p.payment_status === 'completed'
                              ) || [];
                              const amountPaid = completedPayments.reduce(
                                (sum, p) => sum + (p.amount || 0),
                                0
                              );
                              const remainingDue = booking.total_price - amountPaid;
                              const hasPayments = completedPayments.length > 0;
                              
                              if (hasPayments) {
                                return (
                                  <div className="text-xs mt-1">
                                    <div className="text-green-600 font-medium">
                                      Paid: {formatPrice(amountPaid)}
                                    </div>
                                    {remainingDue > 0 && (
                                      <div className="text-amber-600 font-medium">
                                        Due: {formatPrice(remainingDue)}
                                      </div>
                                    )}
                                  </div>
                                );
                              }
                              return null;
                            })()}
                          </div>
                        </div>

                        {}
                        <div className="flex flex-wrap gap-3 
                          pt-4 border-t"
                        >
                          {}
                          <Link
                            to={`/bookings/${booking.id}`}
                            className="inline-flex items-center 
                              gap-2 px-4 py-2 
                              bg-indigo-600 text-white 
                              rounded-lg hover:bg-indigo-700 
                              transition-colors font-medium 
                              text-sm"
                          >
                            <Eye className="w-4 h-4" />
                            View details
                          </Link>

                          {}
                          {canCancelBooking(booking) && (
                            <button
                              type="button"
                              onClick={(e) => {
                                e.preventDefault();
                                e.stopPropagation();
                                handleCancelBookingClick(booking);
                              }}
                              className="inline-flex 
                                items-center gap-2 px-4 py-2 
                                bg-red-600 text-white 
                                rounded-lg hover:bg-red-700 
                                transition-colors font-medium 
                                text-sm cursor-pointer"
                            >
                              <XCircle 
                                className="w-4 h-4" 
                              />
                              Cancel booking
                            </button>
                          )}
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </div>

      {/* Cancel Booking Modal */}
      {showCancelModal && selectedBooking && (
        <CancelBookingModal
          isOpen={showCancelModal}
          booking={selectedBooking}
          onClose={() => {
            setShowCancelModal(false);
            setSelectedBooking(null);
          }}
          onSuccess={handleCancelSuccess}
        />
      )}
    </div>
  );
};

export default MyBookingsPage;
