import React, { useState, useEffect } from "react";
import { useParams, useNavigate } from "react-router-dom";
import { Item, Rental } from "../types";
import { useAuth } from "../contexts/AuthContext";
import { itemAPI, rentalAPI } from "../services/api";
import GoogleMapWithRadius from "../components/GoogleMapWithRadius";
import ItemReviews from "../components/ItemReviews";

const ItemDetail: React.FC = () => {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const { user } = useAuth();
  const [item, setItem] = useState<Item | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [selectedImage, setSelectedImage] = useState(0);
  const [isAlreadyRenting, setIsAlreadyRenting] = useState(false);
  const [rentalDates, setRentalDates] = useState({
    startDate: "",
    startTime: "14:00",
    endDate: "",
    endTime: "12:00",
  });
  const [totalCost, setTotalCost] = useState(0);
  const [costLoading, setCostLoading] = useState(false);
  const [costError, setCostError] = useState<string | null>(null);

  useEffect(() => {
    fetchItem();
  }, [id]);

  useEffect(() => {
    if (user) {
      checkIfAlreadyRenting();
    } else {
      setIsAlreadyRenting(false);
    }
  }, [id, user]);

  const fetchItem = async () => {
    try {
      const response = await itemAPI.getItem(id!);
      setItem(response.data);
    } catch (err: any) {
      setError(err.response?.data?.message || "Failed to fetch item");
    } finally {
      setLoading(false);
    }
  };

  const checkIfAlreadyRenting = async () => {
    try {
      const response = await rentalAPI.getRentals();
      const rentals: Rental[] = response.data;
      // Check if user has an active rental for this item
      const hasActiveRental = rentals.some(
        (rental) =>
          rental.item?.id === id &&
          ["pending", "confirmed", "active"].includes(rental.status)
      );
      setIsAlreadyRenting(hasActiveRental);
    } catch (err) {
      console.error("Failed to check rental status:", err);
    }
  };

  const handleEdit = () => {
    navigate(`/items/${id}/edit`);
  };

  const handleRent = () => {
    const params = new URLSearchParams({
      startDate: rentalDates.startDate,
      startTime: rentalDates.startTime,
      endDate: rentalDates.endDate,
      endTime: rentalDates.endTime,
    });
    navigate(`/items/${id}/rent?${params.toString()}`);
  };

  const handleDateTimeChange = (field: string, value: string) => {
    setRentalDates((prev) => ({
      ...prev,
      [field]: value,
    }));
  };

  const calculateTotalCost = async () => {
    if (!item || !rentalDates.startDate || !rentalDates.endDate) {
      setTotalCost(0);
      return;
    }

    try {
      setCostLoading(true);
      setCostError(null);

      const startDateTime = new Date(
        `${rentalDates.startDate}T${rentalDates.startTime}`
      ).toISOString();

      const endDateTime = new Date(
        `${rentalDates.endDate}T${rentalDates.endTime}`
      ).toISOString();

      const response = await rentalAPI.getRentalCostPreview({
        itemId: item.id,
        startDateTime,
        endDateTime,
      });

      setTotalCost(response.data.baseAmount);
    } catch (err: any) {
      setCostError(err.response?.data?.error || "Failed to calculate cost");
      setTotalCost(0);
    } finally {
      setCostLoading(false);
    }
  };

  const generateTimeOptions = (item: Item | null, selectedDate: string) => {
    const options = [];
    let availableAfter = "00:00";
    let availableBefore = "23:59";

    // Determine time constraints only if we have both item and a valid selected date
    if (item && selectedDate && selectedDate.trim() !== "") {
      const date = new Date(selectedDate);
      const dayName = date
        .toLocaleDateString("en-US", { weekday: "long" })
        .toLowerCase() as
        | "sunday"
        | "monday"
        | "tuesday"
        | "wednesday"
        | "thursday"
        | "friday"
        | "saturday";

      // Use day-specific times if available
      if (
        item.specifyTimesPerDay &&
        item.weeklyTimes &&
        item.weeklyTimes[dayName]
      ) {
        const dayTimes = item.weeklyTimes[dayName];
        availableAfter = dayTimes.availableAfter;
        availableBefore = dayTimes.availableBefore;
        console.log("Using day-specific times:", {
          availableAfter,
          availableBefore,
        });
      }
      // Otherwise use global times
      else if (item.availableAfter && item.availableBefore) {
        availableAfter = item.availableAfter;
        availableBefore = item.availableBefore;
      } else {
        console.log(
          "No time constraints found, using default 24-hour availability"
        );
      }
    }

    for (let hour = 0; hour < 24; hour++) {
      const time24 = `${hour.toString().padStart(2, "0")}:00`;

      // Ensure consistent format for comparison (normalize to HH:MM)
      const normalizedAvailableAfter =
        availableAfter.length === 5 ? availableAfter : availableAfter + ":00";
      const normalizedAvailableBefore =
        availableBefore.length === 5
          ? availableBefore
          : availableBefore + ":00";

      // Check if this time is within the available range
      if (
        time24 >= normalizedAvailableAfter &&
        time24 <= normalizedAvailableBefore
      ) {
        const hour12 = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;
        const period = hour < 12 ? "AM" : "PM";
        const time12 = `${hour12}:00 ${period}`;
        options.push({ value: time24, label: time12 });
      }
    }

    // If no options are available, return at least one option to prevent empty dropdown
    if (options.length === 0) {
      console.log("No valid time options found, showing Not Available");
      options.push({ value: "00:00", label: "Not Available" });
    }

    return options;
  };

  useEffect(() => {
    calculateTotalCost();
  }, [rentalDates, item]);

  // Validate and adjust selected times based on item availability
  useEffect(() => {
    if (!item) return;

    const validateAndAdjustTime = (date: string, currentTime: string) => {
      if (!date) return currentTime;

      const availableOptions = generateTimeOptions(item, date);
      if (availableOptions.length === 0) return currentTime;

      // If current time is not in available options, use the first available time
      const isCurrentTimeValid = availableOptions.some(
        (option) => option.value === currentTime
      );
      return isCurrentTimeValid ? currentTime : availableOptions[0].value;
    };

    const adjustedStartTime = validateAndAdjustTime(
      rentalDates.startDate,
      rentalDates.startTime
    );
    const adjustedEndTime = validateAndAdjustTime(
      rentalDates.endDate || rentalDates.startDate,
      rentalDates.endTime
    );

    // Update state if times have changed
    if (
      adjustedStartTime !== rentalDates.startTime ||
      adjustedEndTime !== rentalDates.endTime
    ) {
      setRentalDates((prev) => ({
        ...prev,
        startTime: adjustedStartTime,
        endTime: adjustedEndTime,
      }));
    }
  }, [item, rentalDates.startDate, rentalDates.endDate]);

  if (loading) {
    return (
      <div className="container mt-5">
        <div className="text-center">
          <div className="spinner-border" role="status">
            <span className="visually-hidden">Loading...</span>
          </div>
        </div>
      </div>
    );
  }

  if (error || !item) {
    return (
      <div className="container mt-5">
        <div className="alert alert-danger" role="alert">
          {error || "Item not found"}
        </div>
      </div>
    );
  }

  const isOwner = user?.id === item.ownerId;

  return (
    <div className="container mt-5">
      <div className="row justify-content-center">
        <div className="col-md-10">
          {isOwner && (
            <div className="d-flex justify-content-end mb-3">
              <button className="btn btn-outline-primary" onClick={handleEdit}>
                <i className="bi bi-pencil me-2"></i>
                Edit Listing
              </button>
            </div>
          )}

          <div className="row">
            <div className="col-md-8">
              {/* Images */}
              {item.images.length > 0 ? (
                <div className="mb-4">
                  <img
                    src={item.images[selectedImage]}
                    alt={item.name}
                    className="img-fluid rounded mb-3"
                    style={{
                      width: "100%",
                      maxHeight: "500px",
                      objectFit: "cover",
                    }}
                  />
                  {item.images.length > 1 && (
                    <div className="d-flex gap-2 overflow-auto justify-content-center">
                      {item.images.map((image, index) => (
                        <img
                          key={index}
                          src={image}
                          alt={`${item.name} ${index + 1}`}
                          className={`rounded cursor-pointer ${
                            selectedImage === index
                              ? "border border-primary"
                              : ""
                          }`}
                          style={{
                            width: "80px",
                            height: "80px",
                            objectFit: "cover",
                            cursor: "pointer",
                          }}
                          onClick={() => setSelectedImage(index)}
                        />
                      ))}
                    </div>
                  )}
                </div>
              ) : (
                <div
                  className="bg-light rounded d-flex align-items-center justify-content-center mb-4"
                  style={{ height: "400px" }}
                >
                  <span className="text-muted">No image available</span>
                </div>
              )}
              {/* Item Name */}
              <h1 className="mb-3">{item.name}</h1>

              {/* Owner Info */}
              {item.owner && (
                <div
                  className="d-flex align-items-center mb-4"
                  onClick={() => navigate(`/users/${item.ownerId}`)}
                  style={{ cursor: "pointer" }}
                >
                  {item.owner.profileImage ? (
                    <img
                      src={item.owner.profileImage}
                      alt={`${item.owner.firstName} ${item.owner.lastName}`}
                      className="rounded-circle me-2"
                      style={{
                        width: "30px",
                        height: "30px",
                        objectFit: "cover",
                      }}
                    />
                  ) : (
                    <div
                      className="rounded-circle bg-secondary d-flex align-items-center justify-content-center me-2"
                      style={{ width: "30px", height: "30px" }}
                    >
                      <i
                        className="bi bi-person-fill text-white"
                        style={{ fontSize: "0.8rem" }}
                      ></i>
                    </div>
                  )}
                  <span className="text-muted">
                    {item.owner.firstName} {item.owner.lastName}
                  </span>
                </div>
              )}

              {/* Description (no label) */}
              <div className="mb-4">
                <p>{item.description}</p>
              </div>

              {/* Map */}
              <GoogleMapWithRadius
                latitude={item.latitude}
                longitude={item.longitude}
              />

              <ItemReviews itemId={item.id} />

              {/* Rules */}
              {item.rules && (
                <div className="mb-4">
                  <h5>Rules</h5>
                  <p>{item.rules}</p>
                </div>
              )}

              {/* Cancellation Policy */}
              <div className="mb-4">
                <h5>Cancellation Policy</h5>
                <div className="small">
                  <div className="mb-2">
                    Full refund: Cancel 48+ hours before rental start time
                  </div>
                  <div className="mb-2">
                    50% refund: Cancel 24-48 hours before rental start time
                  </div>
                  <div className="mb-2">
                    No refund: Cancel within 24 hours of rental start time
                  </div>
                  <div>Replacement Cost: ${item.replacementCost}</div>
                </div>
              </div>
            </div>

            {/* Right Side - Sticky Pricing Card */}
            <div className="col-md-4">
              <div
                className="card sticky-pricing-card"
                style={{
                  position: "sticky",
                  top: "20px",
                  alignSelf: "flex-start",
                }}
              >
                <div className="card-body text-center">
                  {(() => {
                    const hasAnyPositivePrice =
                      (item.pricePerHour !== undefined &&
                        Number(item.pricePerHour) > 0) ||
                      (item.pricePerDay !== undefined &&
                        Number(item.pricePerDay) > 0) ||
                      (item.pricePerWeek !== undefined &&
                        Number(item.pricePerWeek) > 0) ||
                      (item.pricePerMonth !== undefined &&
                        Number(item.pricePerMonth) > 0);

                    const hasAnyZeroPrice =
                      (item.pricePerHour !== undefined &&
                        Number(item.pricePerHour) === 0) ||
                      (item.pricePerDay !== undefined &&
                        Number(item.pricePerDay) === 0) ||
                      (item.pricePerWeek !== undefined &&
                        Number(item.pricePerWeek) === 0) ||
                      (item.pricePerMonth !== undefined &&
                        Number(item.pricePerMonth) === 0);

                    if (!hasAnyPositivePrice && hasAnyZeroPrice) {
                      return (
                        <div className="mb-4">
                          <h4>Free to Borrow</h4>
                        </div>
                      );
                    }

                    return (
                      <>
                        {item.pricePerHour !== undefined &&
                          Number(item.pricePerHour) > 0 && (
                            <div className="mb-2">
                              <h4>
                                ${Math.floor(Number(item.pricePerHour))}/Hour
                              </h4>
                            </div>
                          )}
                        {item.pricePerDay !== undefined &&
                          Number(item.pricePerDay) > 0 && (
                            <div className="mb-2">
                              <h4>
                                ${Math.floor(Number(item.pricePerDay))}/Day
                              </h4>
                            </div>
                          )}
                        {item.pricePerWeek !== undefined &&
                          Number(item.pricePerWeek) > 0 && (
                            <div className="mb-2">
                              <h4>
                                ${Math.floor(Number(item.pricePerWeek))}/Week
                              </h4>
                            </div>
                          )}
                        {item.pricePerMonth !== undefined &&
                          Number(item.pricePerMonth) > 0 && (
                            <div className="mb-2">
                              <h4>
                                ${Math.floor(Number(item.pricePerMonth))}/Month
                              </h4>
                            </div>
                          )}
                      </>
                    );
                  })()}

                  {/* Rental Period Selection - Only show for non-owners */}
                  {!isOwner && item.availability && !isAlreadyRenting && (
                    <>
                      <hr />
                      <div className="text-start">
                        <div className="mb-2">
                          <label className="form-label small mb-1">Start</label>
                          <div className="input-group input-group-sm">
                            <input
                              type="date"
                              className="form-control"
                              value={rentalDates.startDate}
                              onChange={(e) =>
                                handleDateTimeChange(
                                  "startDate",
                                  e.target.value
                                )
                              }
                              min={new Date().toLocaleDateString()}
                              style={{ flex: "1 1 50%" }}
                            />
                            <select
                              className="form-select"
                              value={rentalDates.startTime}
                              onChange={(e) =>
                                handleDateTimeChange(
                                  "startTime",
                                  e.target.value
                                )
                              }
                              style={{ flex: "1 1 50%" }}
                              disabled={
                                !!(
                                  rentalDates.startDate &&
                                  generateTimeOptions(
                                    item,
                                    rentalDates.startDate
                                  ).every(
                                    (opt) => opt.label === "Not Available"
                                  )
                                )
                              }
                            >
                              {generateTimeOptions(
                                item,
                                rentalDates.startDate
                              ).map((option) => (
                                <option key={option.value} value={option.value}>
                                  {option.label}
                                </option>
                              ))}
                            </select>
                          </div>
                        </div>

                        <div className="mb-3">
                          <label className="form-label small mb-1">End</label>
                          <div className="input-group input-group-sm">
                            <input
                              type="date"
                              className="form-control"
                              value={rentalDates.endDate}
                              onChange={(e) =>
                                handleDateTimeChange("endDate", e.target.value)
                              }
                              min={
                                rentalDates.startDate ||
                                new Date().toLocaleDateString()
                              }
                              style={{ flex: "1 1 50%" }}
                            />
                            <select
                              className="form-select"
                              value={rentalDates.endTime}
                              onChange={(e) =>
                                handleDateTimeChange("endTime", e.target.value)
                              }
                              style={{ flex: "1 1 50%" }}
                              disabled={
                                !!(
                                  (rentalDates.endDate ||
                                    rentalDates.startDate) &&
                                  generateTimeOptions(
                                    item,
                                    rentalDates.endDate || rentalDates.startDate
                                  ).every(
                                    (opt) => opt.label === "Not Available"
                                  )
                                )
                              }
                            >
                              {generateTimeOptions(
                                item,
                                rentalDates.endDate || rentalDates.startDate
                              ).map((option) => (
                                <option key={option.value} value={option.value}>
                                  {option.label}
                                </option>
                              ))}
                            </select>
                          </div>
                        </div>

                        {rentalDates.startDate && rentalDates.endDate && (
                          <div className="mb-3 p-2 bg-light rounded text-center">
                            {costLoading ? (
                              <div className="spinner-border spinner-border-sm" role="status">
                                <span className="visually-hidden">Calculating...</span>
                              </div>
                            ) : costError ? (
                              <small className="text-danger">{costError}</small>
                            ) : totalCost > 0 ? (
                              <strong>Total: ${totalCost}</strong>
                            ) : null}
                          </div>
                        )}
                      </div>
                    </>
                  )}

                  {/* Action Buttons */}
                  {!isOwner && item.availability && !isAlreadyRenting && (
                    <div className="d-grid">
                      <button
                        className="btn btn-primary"
                        onClick={handleRent}
                        disabled={
                          !rentalDates.startDate || !rentalDates.endDate
                        }
                      >
                        Rent Now
                      </button>
                    </div>
                  )}
                  {!isOwner && isAlreadyRenting && (
                    <div className="d-grid">
                      <button
                        className="btn btn-success"
                        disabled
                        style={{ opacity: 0.8 }}
                      >
                        ✓ Renting
                      </button>
                    </div>
                  )}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

export default ItemDetail;
