import React, { useState, useEffect, useMemo, useRef } from 'react';
import { 
  useParams, 
  useNavigate, 
  Link 
} from 'react-router-dom';
import {
  ArrowLeft,
  Calendar,
  MapPin,
  Users,
  CreditCard,
  User,
  Mail,
  Phone,
  FileText,
  Building2,
  AlertCircle,
} from 'lucide-react';
import { toast } from 'react-toastify';
import {
  getBookingById,
  type Booking,
} from '../../features/bookings/services/bookingService';
import { getUserFriendlyError } from '../../shared/utils/errorSanitizer';
import useAuthStore from '../../store/useAuthStore';
import { useAuthModal } from '../../features/auth/contexts/AuthModalContext';
import Loading from '../../shared/components/Loading';
import PaymentStatusBadge from '../../shared/components/PaymentStatusBadge';
import { useFormatCurrency } from '../../features/payments/hooks/useFormatCurrency';
import { parseDateLocal } from '../../shared/utils/format';
import CancelBookingModal from '../../features/bookings/components/CancelBookingModal';
import { validateBookingId } from '../../shared/utils/routeValidation';
import { validateAndHandleBookingOwnership } from '../../shared/utils/ownershipValidation';
import { getBookingStatusConfig, canCancelBooking, calculateNights } from '../../shared/utils/bookingUtils';

const BookingDetailPage: React.FC = () => {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const { isAuthenticated, userInfo } = useAuthStore();
  const { openModal: _openModal } = useAuthModal();
  const { formatCurrency } = useFormatCurrency();
  const abortControllerRef = useRef<AbortController | null>(null);

  const [booking, setBooking] = useState<Booking | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [showCancelModal, setShowCancelModal] = useState(false);

  // Validate route parameter
  useEffect(() => {
    const bookingId = validateBookingId(id);
    if (!bookingId) {
      setError('Invalid booking ID');
      setLoading(false);
      toast.error('Invalid booking ID');
      navigate('/bookings');
      return;
    }
  }, [id, navigate]);

  // Fetch booking details with ownership validation
  useEffect(() => {
    if (!isAuthenticated) {
      return;
    }

    const bookingId = validateBookingId(id);
    if (!bookingId) {
      return;
    }

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

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

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

        const response = await getBookingById(bookingId);

        if (response.success && response.data?.booking) {
          const bookingData = response.data.booking;
          
          // Validate ownership
          if (!validateAndHandleBookingOwnership(bookingData, userInfo?.id, navigate)) {
            setLoading(false);
            return;
          }

          setBooking(bookingData);
        } else {
          throw new Error('Unable to load booking information');
        }
      } 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 booking information';
        setError(message);
        toast.error(message);
      } finally {
        setLoading(false);
      }
    };

    fetchBookingDetails();

    // Cleanup: abort request on unmount or dependency change
    return () => {
      if (abortControllerRef.current) {
        abortControllerRef.current.abort();
      }
    };
  }, [id, isAuthenticated, userInfo?.id, navigate]);

  const handleCancelBookingClick = () => {
    if (!booking) {
      toast.error('Booking not found');
      return;
    }
    setShowCancelModal(true);
  };

  const handleCancelSuccess = async () => {
    if (booking) {
      await fetchBookingDetails(booking.id);
    }
    setShowCancelModal(false);
  };

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

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

  // Memoize nights calculation
  const nights = useMemo(() => {
    if (!booking) return 1;
    return calculateNights(booking.check_in_date, booking.check_out_date);
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [booking?.check_in_date, booking?.check_out_date]);

  // Memoize services total calculation
  const servicesTotal = useMemo(() => {
    if (!booking) return 0;
    
    const serviceUsages = (booking && typeof booking === 'object' && 'service_usages' in booking && Array.isArray((booking as { service_usages?: unknown[] }).service_usages)) ? (booking as { service_usages: unknown[] }).service_usages : ((booking && typeof booking === 'object' && 'services' in booking && Array.isArray((booking as { services?: unknown[] }).services)) ? (booking as { services: unknown[] }).services : []);
    if (Array.isArray(serviceUsages) && serviceUsages.length > 0) {
      return serviceUsages.reduce((sum: number, su: { total_price?: number }) => {
        return sum + (su.total_price || 0);
      }, 0);
    }
    return 0;
  }, [booking]);

  // Memoize service usages
  const serviceUsages = useMemo(() => {
    if (!booking) return [];
    
    const bookingObj = booking as { service_usages?: unknown[]; services?: unknown[] };
    const usages = Array.isArray(bookingObj.service_usages) 
      ? bookingObj.service_usages 
      : (Array.isArray(bookingObj.services) ? bookingObj.services : []);
    return Array.isArray(usages) ? usages : [];
  }, [booking]);

  // Memoize room price per night
  const roomPricePerNight = useMemo(() => {
    if (!booking) return 0;
    
    const roomTotal = booking.total_price - servicesTotal;
    return nights > 0 ? roomTotal / nights : roomTotal;
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [booking?.total_price, servicesTotal, nights]);

  // Memoize room total
  const roomTotal = useMemo(() => {
    return roomPricePerNight * nights;
  }, [roomPricePerNight, nights]);

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

  if (error || !booking) {
    return (
      <div className="min-h-screen bg-gray-50 py-8">
        <div className="max-w-4xl mx-auto px-4">
          <div
            className="bg-red-50 border border-red-200 
              rounded-lg p-8 text-center"
          >
            <AlertCircle
              className="w-12 h-12 text-red-500 
                mx-auto mb-3"
            />
            <p className="text-red-700 font-medium mb-4">
              {error || 'Booking not found'}
            </p>
            <button
              onClick={() => navigate('/bookings')}
              className="px-6 py-2 bg-red-600 
                text-white rounded-lg 
                hover:bg-red-700 transition-colors"
            >
              Back to list
            </button>
          </div>
        </div>
      </div>
    );
  }

  const room = booking.room;
  const roomType = room?.room_type;
  const statusConfig = getBookingStatusConfig(booking.status);
  const StatusIcon = statusConfig.icon;
  const bookingCanCancel = canCancelBooking(booking);

  return (
    <div className="min-h-screen bg-gray-50 py-8">
      <div className="max-w-4xl mx-auto px-4">
        {}
        <Link
          to="/bookings"
          className="inline-flex items-center gap-2 
            text-gray-600 hover:text-gray-900 
            mb-6 transition-colors"
        >
          <ArrowLeft className="w-5 h-5" />
          <span>Back to list</span>
        </Link>

        {}
        <div className="flex items-center justify-between 
          mb-6"
        >
          <h1 className="text-3xl font-bold text-gray-900">
            Booking Details
          </h1>

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

        {}
        <div className="bg-indigo-50 border 
          border-indigo-200 rounded-lg p-4 mb-6"
        >
          <p className="text-sm text-indigo-600 
            font-medium mb-1"
          >
            Booking Number
          </p>
          <p className="text-2xl font-bold text-indigo-900 
            font-mono"
          >
            {booking.booking_number}
          </p>
        </div>

        {}
        <div className="bg-white rounded-lg shadow-md 
          p-6 mb-6"
        >
          <h2 className="text-xl font-bold text-gray-900 
            mb-4"
          >
            Room Information
          </h2>

          {roomType && (
            <div className="flex flex-col md:flex-row 
              gap-6"
            >
              {}
              {((room?.room_type?.images && room.room_type.images.length > 0) 
                ? room.room_type.images[0] 
                : roomType?.images?.[0]) && (
                <div className="md:w-64 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 md:h-full 
                      object-cover rounded-lg"
                  />
                </div>
              )}

              {}
              <div className="flex-1">
                <h3 className="text-2xl font-bold 
                  text-gray-900 mb-2"
                >
                  {roomType.name}
                </h3>
                <p className="text-gray-600 mb-4">
                  <MapPin className="w-4 h-4 inline mr-1" />
                  Room {room?.room_number} - 
                  Floor {room?.floor}
                </p>

                <div className="grid grid-cols-2 gap-4">
                  <div>
                    <p className="text-sm text-gray-500">
                      Capacity
                    </p>
                    <p className="font-medium text-gray-900">
                      Max {room?.room_type?.capacity || roomType?.capacity || 0} guests
                    </p>
                  </div>
                  <div>
                    <p className="text-sm text-gray-500">
                      Room Price
                    </p>
                    <p className="font-medium text-indigo-600">
                      {formatPrice(roomPricePerNight)}/night
                    </p>
                  </div>
                </div>
              </div>
            </div>
          )}
        </div>

        {}
        <div className="bg-white rounded-lg shadow-md 
          p-6 mb-6"
        >
          <h2 className="text-xl font-bold text-gray-900 
            mb-4"
          >
            Booking Details
          </h2>

          <div className="space-y-4">
            {}
            <div className="grid grid-cols-1 md:grid-cols-2 
              gap-4"
            >
              <div>
                <p className="text-sm text-gray-600 mb-1">
                  <Calendar className="w-4 h-4 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-sm text-gray-600 mb-1">
                  <Calendar className="w-4 h-4 inline mr-1" />
                  Check-out Date
                </p>
                <p className="font-medium text-gray-900">
                  {formatDate(booking.check_out_date)}
                </p>
              </div>
            </div>

            {}
            <div>
              <p className="text-sm text-gray-600 mb-1">
                <Users className="w-4 h-4 inline mr-1" />
                Number of Guests
              </p>
              <p className="font-medium text-gray-900">
                {booking.guest_count} guest(s)
              </p>
            </div>

            {}
            {booking.notes && (
              <div>
                <p className="text-sm text-gray-600 mb-1">
                  <FileText className="w-4 h-4 inline mr-1" />
                  Notes
                </p>
                <p className="font-medium text-gray-900">
                  {booking.notes}
                </p>
              </div>
            )}

            {}
            <div className="border-t pt-4">
              <p className="text-sm text-gray-600 mb-1">
                <CreditCard className="w-4 h-4 inline mr-1" />
                Payment Method
              </p>
              <p className="font-medium text-gray-900 mb-2">
                {booking.payment_method === 'cash'
                  ? '💵 Pay at hotel'
                  : booking.payment_method === 'stripe'
                  ? '💳 Pay with Card (Stripe)'
                  : booking.payment_method === 'paypal'
                  ? '💳 PayPal'
                  : booking.payment_method || 'N/A'}
              </p>
              <div className="flex items-center gap-2">
                <span className="text-sm text-gray-500">
                  Status:
                </span>
                <PaymentStatusBadge 
                  status={booking.payment_status}
                  size="sm"
                />
              </div>
            </div>

            {}
            {booking.payments && booking.payments.length > 0 && (
              <div className="border-t pt-4">
                <h3 className="text-lg font-semibold text-gray-900 mb-4">
                  Payment History
                </h3>
                <div className="space-y-3">
                  {booking.payments.map((payment: { id?: number; amount?: number; payment_method?: string; payment_status?: string; payment_date?: string; transaction_id?: string }, index: number) => (
                    <div key={payment.id || index} className="p-4 bg-gradient-to-r from-green-50 to-emerald-50 rounded-lg border border-green-200">
                      <div className="flex justify-between items-start mb-2">
                        <div className="flex-1">
                          <div className="flex items-center gap-2 mb-1">
                            <span className="text-lg font-bold text-green-700">
                              {formatPrice(payment.amount || 0)}
                            </span>
                            <span className={`text-xs px-2 py-1 rounded-full font-medium ${
                              payment.payment_status === 'completed' || payment.payment_status === 'paid'
                                ? 'bg-green-100 text-green-700'
                                : payment.payment_status === 'pending'
                                ? 'bg-yellow-100 text-yellow-700'
                                : 'bg-red-100 text-red-700'
                            }`}>
                              {payment.payment_status === 'completed' || payment.payment_status === 'paid' ? 'Paid' : payment.payment_status || 'Pending'}
                            </span>
                          </div>
                          <div className="space-y-1">
                            <p className="text-sm text-gray-700">
                              <span className="font-medium">Payment Method:</span>{' '}
                              {payment.payment_method === 'stripe' ? '💳 Stripe (Card)' : 
                               payment.payment_method === 'paypal' ? '💳 PayPal' : 
                               payment.payment_method === 'cash' ? '💵 Cash' : 
                               payment.payment_method || 'N/A'}
                            </p>
                            <p className="text-sm text-gray-700">
                              <span className="font-medium">Payment Type:</span>{' '}
                              {payment.payment_type === 'deposit' ? 'Deposit (20%)' : 
                               payment.payment_type === 'remaining' ? 'Remaining Payment' : 
                               'Full Payment'}
                            </p>
                            {payment.transaction_id && (
                              <p className="text-xs text-gray-500 font-mono">
                                Transaction ID: {payment.transaction_id}
                              </p>
                            )}
                            {payment.payment_date && (
                              <p className="text-xs text-gray-500">
                                Paid on: {new Date(payment.payment_date).toLocaleDateString('en-US', { 
                                  year: 'numeric', 
                                  month: 'long', 
                                  day: 'numeric',
                                  hour: '2-digit',
                                  minute: '2-digit'
                                })}
                              </p>
                            )}
                          </div>
                        </div>
                      </div>
                    </div>
                  ))}
                </div>
              </div>
            )}

            {}
            <div className="border-t pt-4">
              <h3 className="text-lg font-semibold text-gray-900 mb-4">
                Price Breakdown
              </h3>
              
              <div className="space-y-3">
                {}
                <div className="flex justify-between items-center">
                  <div>
                    <p className="text-sm font-medium text-gray-900">
                      Room ({nights} night{nights !== 1 ? 's' : ''})
                    </p>
                    <p className="text-xs text-gray-500">
                      {formatPrice(roomPricePerNight)} per night
                    </p>
                  </div>
                  <span className="text-base font-semibold text-gray-900">
                    {formatPrice(roomTotal)}
                  </span>
                </div>

                {}
                {serviceUsages.length > 0 && (
                  <>
                    {serviceUsages.map((serviceUsage: { id?: number; service_name?: string; name?: string; quantity?: number; price?: number; total?: number; total_price?: number }, index: number) => (
                          <div key={serviceUsage.id || index} className="flex justify-between items-center">
                            <div>
                              <p className="text-sm font-medium text-gray-900">
                                {serviceUsage.service_name || serviceUsage.name || 'Service'}
                              </p>
                              <p className="text-xs text-gray-500">
                                {formatPrice(serviceUsage.unit_price || serviceUsage.price || 0)} × {serviceUsage.quantity || 1}
                              </p>
                            </div>
                            <span className="text-base font-semibold text-gray-900">
                              {formatPrice(serviceUsage.total_price || (serviceUsage.unit_price || serviceUsage.price || 0) * (serviceUsage.quantity || 1))}
                            </span>
                          </div>
                    ))}
                  </>
                )}

                {}
                {(() => {
                  
                  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;
                  
                  return (
                    <>
                      {hasPayments && (
                        <>
                          <div className="border-t pt-3 mt-3">
                            <div className="flex justify-between items-center mb-2">
                              <span className="text-sm font-medium text-gray-700">
                                Amount Paid:
                              </span>
                              <span className="text-base font-semibold text-green-600">
                                {formatPrice(amountPaid)}
                              </span>
                            </div>
                            {remainingDue > 0 && (
                              <div className="flex justify-between items-center mb-2">
                                <span className="text-sm font-medium text-gray-700">
                                  Remaining Due:
                                </span>
                                <span className="text-base font-semibold text-amber-600">
                                  {formatPrice(remainingDue)}
                                </span>
                              </div>
                            )}
                          </div>
                        </>
                      )}
                      {}
                      <div className="border-t pt-3 mt-3">
                        <div className="flex justify-between items-center">
                          <span className="text-lg font-semibold text-gray-900">
                            Total Booking Price
                          </span>
                          <span className="text-2xl font-bold text-indigo-600">
                            {formatPrice(booking.total_price)}
                          </span>
                        </div>
                      </div>
                    </>
                  );
                })()}
              </div>
            </div>
          </div>
        </div>

        {}
        {booking.guest_info && (
          <div className="bg-white rounded-lg shadow-md 
            p-6 mb-6"
          >
            <h2 className="text-xl font-bold text-gray-900 
              mb-4"
            >
              Customer Information
            </h2>
            <div className="space-y-3">
              <div>
                <p className="text-sm text-gray-600">
                  <User className="w-4 h-4 inline mr-1" />
                  Full Name
                </p>
                <p className="font-medium text-gray-900">
                  {booking.guest_info.full_name}
                </p>
              </div>
              <div>
                <p className="text-sm text-gray-600">
                  <Mail className="w-4 h-4 inline mr-1" />
                  Email
                </p>
                <p className="font-medium text-gray-900">
                  {booking.guest_info.email}
                </p>
              </div>
              <div>
                <p className="text-sm text-gray-600">
                  <Phone className="w-4 h-4 inline mr-1" />
                  Phone Number
                </p>
                <p className="font-medium text-gray-900">
                  {booking.guest_info.phone}
                </p>
              </div>
            </div>
          </div>
        )}

        {}
        {booking.payment_method === 'stripe' && 
         booking.payment_status === 'unpaid' && (
          <div
            className="bg-blue-50 border border-blue-200 
              rounded-lg p-6 mb-6"
          >
            <div className="flex items-start gap-3">
              <Building2
                className="w-6 h-6 text-blue-600 
                  mt-1 flex-shrink-0"
              />
              <div className="flex-1">
                <h3 className="font-bold text-indigo-900 mb-2">
                  Payment Required
                </h3>
                <p className="text-sm text-indigo-700 mb-4">
                  Please complete your payment to confirm your booking.
                  </p>
                <Link
                  to={`/payment/${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-semibold"
                >
                  <CreditCard className="w-4 h-4" />
                  Complete Payment
                </Link>
              </div>
            </div>
          </div>
        )}

        {}
        <div
          className="bg-yellow-50 border border-yellow-200 
            rounded-lg p-4 mb-6"
        >
          <p className="text-sm text-yellow-800 font-medium 
            mb-2"
          >
            ⚠️ Important Notice
          </p>
          <ul className="text-sm text-yellow-700 space-y-1 
            ml-4 list-disc"
          >
            <li>
              Please bring your ID card when checking in
            </li>
            <li>
              Check-in time: 14:00 / 
              Check-out time: 12:00
            </li>
            {bookingCanCancel && (
              <li>
                If you cancel the booking, 20% of 
                the total order value will be charged
              </li>
            )}
          </ul>
        </div>

        {}
        <div className="flex flex-col sm:flex-row gap-4">
          {}
          {booking.payment_method === 'stripe' && 
           booking.payment_status === 'unpaid' && (
            <Link
              to={`/payment/${booking.id}`}
              className="flex-1 flex items-center 
                justify-center gap-2 px-6 py-3 
                bg-green-600 text-white rounded-lg 
                hover:bg-green-700 transition-colors 
                font-semibold"
            >
              <CreditCard className="w-5 h-5" />
              Confirm Payment
            </Link>
          )}

          {bookingCanCancel ? (
            <button
              type="button"
              onClick={(e) => {
                e.stopPropagation();
                handleCancelBookingClick();
              }}
              className="flex-1 flex items-center 
                justify-center gap-2 px-6 py-3 
                bg-red-600 text-white rounded-lg 
                hover:bg-red-700 active:bg-red-800
                transition-colors 
                font-semibold cursor-pointer
                relative z-10"
              aria-label="Cancel booking"
            >
              <XCircle className="w-5 h-5" />
              Cancel Booking
            </button>
          ) : (
            <div className="flex-1 text-center text-sm text-gray-500 py-3">
              Cannot cancel {booking.status} booking
              <br />
              <small className="text-xs">(Only pending bookings can be cancelled)</small>
            </div>
          )}

          <Link
            to="/bookings"
            className="flex-1 flex items-center 
              justify-center gap-2 px-6 py-3 
              bg-gray-600 text-white rounded-lg 
              hover:bg-gray-700 transition-colors 
              font-semibold"
          >
            Back to list
          </Link>
        </div>
      </div>

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

export default BookingDetailPage;
