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 AvailabilityCalendar from '../components/AvailabilityCalendar';
import AddressAutocomplete from '../components/AddressAutocomplete';

interface ItemFormData {
  name: string;
  description: string;
  tags: string[];
  pickUpAvailable: boolean;
  localDeliveryAvailable: boolean;
  localDeliveryRadius?: number;
  shippingAvailable: boolean;
  inPlaceUseAvailable: boolean;
  pricePerHour?: number;
  pricePerDay?: number;
  replacementCost: number;
  location: string;
  latitude?: number;
  longitude?: number;
  rules?: string;
  minimumRentalDays: number;
  needsTraining: boolean;
  availability: boolean;
  unavailablePeriods?: Array<{
    id: string;
    startDate: Date;
    endDate: Date;
    startTime?: string;
    endTime?: string;
  }>;
}

const EditItem: React.FC = () => {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const { user } = useAuth();
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState(false);
  const [tagInput, setTagInput] = useState("");
  const [imageFiles, setImageFiles] = useState<File[]>([]);
  const [imagePreviews, setImagePreviews] = useState<string[]>([]);
  const [priceType, setPriceType] = useState<"hour" | "day">("day");
  const [acceptedRentals, setAcceptedRentals] = useState<Rental[]>([]);
  const [formData, setFormData] = useState<ItemFormData>({
    name: '',
    description: '',
    tags: [],
    pickUpAvailable: false,
    localDeliveryAvailable: false,
    shippingAvailable: false,
    inPlaceUseAvailable: false,
    pricePerHour: undefined,
    pricePerDay: undefined,
    replacementCost: 0,
    location: '',
    rules: '',
    minimumRentalDays: 1,
    needsTraining: false,
    availability: true,
    unavailablePeriods: [],
  });

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

  const fetchItem = async () => {
    try {
      const response = await itemAPI.getItem(id!);
      const item: Item = response.data;
      
      if (item.ownerId !== user?.id) {
        setError('You are not authorized to edit this item');
        return;
      }

      // Set the price type based on available pricing
      if (item.pricePerHour) {
        setPriceType('hour');
      } else if (item.pricePerDay) {
        setPriceType('day');
      }

      // Convert item data to form data format
      setFormData({
        name: item.name,
        description: item.description,
        tags: item.tags || [],
        pickUpAvailable: item.pickUpAvailable || false,
        localDeliveryAvailable: item.localDeliveryAvailable || false,
        localDeliveryRadius: item.localDeliveryRadius || 25,
        shippingAvailable: item.shippingAvailable || false,
        inPlaceUseAvailable: item.inPlaceUseAvailable || false,
        pricePerHour: item.pricePerHour,
        pricePerDay: item.pricePerDay,
        replacementCost: item.replacementCost,
        location: item.location,
        latitude: item.latitude,
        longitude: item.longitude,
        rules: item.rules || '',
        minimumRentalDays: item.minimumRentalDays,
        needsTraining: item.needsTraining || false,
        availability: item.availability,
        unavailablePeriods: item.unavailablePeriods || [],
      });

      // Set existing images as previews
      if (item.images && item.images.length > 0) {
        setImagePreviews(item.images);
      }
    } catch (err: any) {
      setError(err.response?.data?.message || 'Failed to fetch item');
    } finally {
      setLoading(false);
    }
  };

  const fetchAcceptedRentals = async () => {
    try {
      const response = await rentalAPI.getMyListings();
      const rentals: Rental[] = response.data;
      // Filter for accepted rentals for this specific item
      const itemRentals = rentals.filter(rental => 
        rental.itemId === id && 
        ['confirmed', 'active'].includes(rental.status)
      );
      setAcceptedRentals(itemRentals);
    } catch (err) {
      console.error('Error fetching rentals:', err);
    }
  };

  const handleChange = (
    e: React.ChangeEvent<
      HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement
    >
  ) => {
    const { name, value, type } = e.target;

    if (type === "checkbox") {
      const checked = (e.target as HTMLInputElement).checked;
      setFormData((prev) => ({ ...prev, [name]: checked }));
    } else if (type === "number") {
      setFormData((prev) => ({
        ...prev,
        [name]: value ? parseFloat(value) : undefined,
      }));
    } else {
      setFormData((prev) => ({ ...prev, [name]: value }));
    }
  };

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

    try {
      // Use existing image previews (which includes both old and new images)
      const imageUrls = imagePreviews;

      await itemAPI.updateItem(id!, {
        ...formData,
        images: imageUrls,
        isPortable: formData.pickUpAvailable || formData.shippingAvailable,
      });

      setSuccess(true);
      setTimeout(() => {
        navigate(`/items/${id}`);
      }, 1500);
    } catch (err: any) {
      setError(err.response?.data?.message || 'Failed to update item');
    }
  };

  const addTag = () => {
    if (tagInput.trim() && !formData.tags.includes(tagInput.trim())) {
      setFormData((prev) => ({
        ...prev,
        tags: [...prev.tags, tagInput.trim()],
      }));
      setTagInput("");
    }
  };

  const removeTag = (tag: string) => {
    setFormData((prev) => ({
      ...prev,
      tags: prev.tags.filter((t) => t !== tag),
    }));
  };

  const handleImageChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = Array.from(e.target.files || []);

    // Limit to 5 images total
    if (imagePreviews.length + files.length > 5) {
      setError("You can upload a maximum of 5 images");
      return;
    }

    const newImageFiles = [...imageFiles, ...files];
    setImageFiles(newImageFiles);

    // Create previews
    files.forEach((file) => {
      const reader = new FileReader();
      reader.onloadend = () => {
        setImagePreviews((prev) => [...prev, reader.result as string]);
      };
      reader.readAsDataURL(file);
    });
  };

  const removeImage = (index: number) => {
    setImagePreviews((prev) => prev.filter((_, i) => i !== index));
  };

  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 && error.includes('authorized')) {
    return (
      <div className="container mt-5">
        <div className="alert alert-danger" role="alert">
          {error}
        </div>
      </div>
    );
  }

  return (
    <div className="container mt-4">
      <div className="row justify-content-center">
        <div className="col-md-8">
          <h1>Edit Listing</h1>
          
          {error && (
            <div className="alert alert-danger" role="alert">
              {error}
            </div>
          )}
          
          {success && (
            <div className="alert alert-success" role="alert">
              Item updated successfully! Redirecting...
            </div>
          )}
          
          <form onSubmit={handleSubmit}>
            <div className="mb-3">
              <label className="form-label">Images (Max 5)</label>
              <input
                type="file"
                className="form-control"
                onChange={handleImageChange}
                accept="image/*"
                multiple
                disabled={imagePreviews.length >= 5}
              />
              <div className="form-text">
                Upload up to 5 images of your item
              </div>

              {imagePreviews.length > 0 && (
                <div className="row mt-3">
                  {imagePreviews.map((preview, index) => (
                    <div key={index} className="col-6 col-md-4 col-lg-3 mb-3">
                      <div className="position-relative">
                        <img
                          src={preview}
                          alt={`Preview ${index + 1}`}
                          className="img-fluid rounded"
                          style={{
                            width: "100%",
                            height: "150px",
                            objectFit: "cover",
                          }}
                        />
                        <button
                          type="button"
                          className="btn btn-sm btn-danger position-absolute top-0 end-0 m-1"
                          onClick={() => removeImage(index)}
                        >
                          <i className="bi bi-x"></i>
                        </button>
                      </div>
                    </div>
                  ))}
                </div>
              )}
            </div>

            <div className="mb-3">
              <label htmlFor="name" className="form-label">
                Item Name *
              </label>
              <input
                type="text"
                className="form-control"
                id="name"
                name="name"
                value={formData.name}
                onChange={handleChange}
                required
              />
            </div>

            <div className="mb-3">
              <label htmlFor="description" className="form-label">
                Description *
              </label>
              <textarea
                className="form-control"
                id="description"
                name="description"
                rows={4}
                value={formData.description}
                onChange={handleChange}
                required
              />
            </div>

            <div className="mb-3">
              <label className="form-label">Tags</label>
              <div className="input-group mb-2">
                <input
                  type="text"
                  className="form-control"
                  value={tagInput}
                  onChange={(e) => setTagInput(e.target.value)}
                  onKeyPress={(e) =>
                    e.key === "Enter" && (e.preventDefault(), addTag())
                  }
                  placeholder="Add a tag"
                />
                <button
                  type="button"
                  className="btn btn-outline-secondary"
                  onClick={addTag}
                >
                  Add
                </button>
              </div>
              <div>
                {formData.tags.map((tag, index) => (
                  <span key={index} className="badge bg-primary me-2 mb-2">
                    {tag}
                    <button
                      type="button"
                      className="btn-close btn-close-white ms-2"
                      onClick={() => removeTag(tag)}
                      style={{ fontSize: "0.7rem" }}
                    />
                  </span>
                ))}
              </div>
            </div>

            <div className="mb-3">
              <label htmlFor="location" className="form-label">
                Location *
              </label>
              <AddressAutocomplete
                id="location"
                name="location"
                value={formData.location}
                onChange={(value, lat, lon) => {
                  setFormData(prev => ({
                    ...prev,
                    location: value,
                    latitude: lat,
                    longitude: lon
                  }));
                }}
                placeholder="Address"
                required
              />
            </div>

            <div className="mb-3">
              <label className="form-label">Availability Type</label>
              <div className="form-check">
                <input
                  type="checkbox"
                  className="form-check-input"
                  id="pickUpAvailable"
                  name="pickUpAvailable"
                  checked={formData.pickUpAvailable}
                  onChange={handleChange}
                />
                <label className="form-check-label" htmlFor="pickUpAvailable">
                  Pick-Up
                  <div className="small text-muted">They pick-up the item from your location and they return the item to your location</div>
                </label>
              </div>
              <div className="form-check">
                <input
                  type="checkbox"
                  className="form-check-input"
                  id="localDeliveryAvailable"
                  name="localDeliveryAvailable"
                  checked={formData.localDeliveryAvailable}
                  onChange={handleChange}
                />
                <label
                  className="form-check-label d-flex align-items-center"
                  htmlFor="localDeliveryAvailable"
                >
                  <div>
                    Local Delivery
                    {formData.localDeliveryAvailable && (
                      <span className="ms-2">
                        (Delivery Radius: 
                        <input
                          type="number"
                          className="form-control form-control-sm d-inline-block mx-1"
                          id="localDeliveryRadius"
                          name="localDeliveryRadius"
                          value={formData.localDeliveryRadius || ''}
                          onChange={handleChange}
                          onClick={(e) => e.stopPropagation()}
                          placeholder="25"
                          min="1"
                          max="100"
                          style={{ width: '60px' }}
                        />
                        miles)
                      </span>
                    )}
                    <div className="small text-muted">You deliver and then pick-up the item when the rental period ends</div>
                  </div>
                </label>
              </div>
              <div className="form-check">
                <input
                  type="checkbox"
                  className="form-check-input"
                  id="shippingAvailable"
                  name="shippingAvailable"
                  checked={formData.shippingAvailable}
                  onChange={handleChange}
                />
                <label className="form-check-label" htmlFor="shippingAvailable">
                  Shipping
                </label>
              </div>
              <div className="form-check">
                <input
                  type="checkbox"
                  className="form-check-input"
                  id="inPlaceUseAvailable"
                  name="inPlaceUseAvailable"
                  checked={formData.inPlaceUseAvailable}
                  onChange={handleChange}
                />
                <label
                  className="form-check-label"
                  htmlFor="inPlaceUseAvailable"
                >
                  In-Place Use
                  <div className="small text-muted">They use at your location</div>
                </label>
              </div>
            </div>

            <div className="mb-3">
              <div className="row align-items-center">
                <div className="col-auto">
                  <label className="col-form-label">Price per</label>
                </div>
                <div className="col-auto">
                  <select
                    className="form-select"
                    value={priceType}
                    onChange={(e) => setPriceType(e.target.value as "hour" | "day")}
                  >
                    <option value="hour">Hour</option>
                    <option value="day">Day</option>
                  </select>
                </div>
                <div className="col">
                  <div className="input-group">
                    <span className="input-group-text">$</span>
                    <input
                      type="number"
                      className="form-control"
                      id={priceType === "hour" ? "pricePerHour" : "pricePerDay"}
                      name={priceType === "hour" ? "pricePerHour" : "pricePerDay"}
                      value={priceType === "hour" ? (formData.pricePerHour || "") : (formData.pricePerDay || "")}
                      onChange={handleChange}
                      step="0.01"
                      min="0"
                      placeholder="0.00"
                    />
                  </div>
                </div>
              </div>
            </div>

            <div className="mb-3">
              <label htmlFor="minimumRentalDays" className="form-label">
                Minimum Rental {priceType === "hour" ? "Hours" : "Days"}
              </label>
              <input
                type="number"
                className="form-control"
                id="minimumRentalDays"
                name="minimumRentalDays"
                value={formData.minimumRentalDays}
                onChange={handleChange}
                min="1"
              />
            </div>

            <div className="mb-4">
              <h5>Availability Schedule</h5>
              <p className="text-muted">Select dates when the item is NOT available for rent. Dates with accepted rentals are shown in purple.</p>
              <AvailabilityCalendar
                unavailablePeriods={[
                  ...(formData.unavailablePeriods || []),
                  ...acceptedRentals.map(rental => ({
                    id: `rental-${rental.id}`,
                    startDate: new Date(rental.startDate),
                    endDate: new Date(rental.endDate),
                    isAcceptedRental: true
                  }))
                ]}
                onPeriodsChange={(periods) => {
                  // Filter out accepted rental periods when saving
                  const userPeriods = periods.filter(p => !p.isAcceptedRental);
                  setFormData(prev => ({ ...prev, unavailablePeriods: userPeriods }));
                }}
                mode="owner"
              />
            </div>

            <div className="mb-3">
              <label htmlFor="rules" className="form-label">
                Rental Rules & Guidelines
              </label>
              <div className="form-check mb-2">
                <input
                  type="checkbox"
                  className="form-check-input"
                  id="needsTraining"
                  name="needsTraining"
                  checked={formData.needsTraining}
                  onChange={handleChange}
                />
                <label className="form-check-label" htmlFor="needsTraining">
                  Requires in-person training before rental
                </label>
              </div>
              <textarea
                className="form-control"
                id="rules"
                name="rules"
                rows={3}
                value={formData.rules || ""}
                onChange={handleChange}
                placeholder="Any specific rules or guidelines for renting this item"
              />
            </div>

            <div className="mb-3">
              <label htmlFor="replacementCost" className="form-label">
                Replacement Cost *
              </label>
              <div className="input-group">
                <span className="input-group-text">$</span>
                <input
                  type="number"
                  className="form-control"
                  id="replacementCost"
                  name="replacementCost"
                  value={formData.replacementCost}
                  onChange={handleChange}
                  step="0.01"
                  min="0"
                  required
                />
              </div>
              <div className="form-text">
                The cost to replace the item if damaged or lost
              </div>
            </div>

            <div className="mb-3 form-check">
              <input
                type="checkbox"
                className="form-check-input"
                id="availability"
                name="availability"
                checked={formData.availability}
                onChange={handleChange}
              />
              <label className="form-check-label" htmlFor="availability">
                Available for rent
              </label>
            </div>

            <div className="d-grid gap-2">
              <button
                type="submit"
                className="btn btn-primary"
                disabled={loading}
              >
                {loading ? "Updating..." : "Update Listing"}
              </button>
              <button
                type="button"
                className="btn btn-secondary"
                onClick={() => navigate(-1)}
              >
                Back
              </button>
            </div>
          </form>
        </div>
      </div>
    </div>
  );
};

export default EditItem;