import React, { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { useAuth } from "../contexts/AuthContext";
import api, { addressAPI, userAPI, itemAPI } from "../services/api";
import AvailabilitySettings from "../components/AvailabilitySettings";
import ImageUpload from "../components/ImageUpload";
import ItemInformation from "../components/ItemInformation";
import LocationForm from "../components/LocationForm";
import DeliveryOptions from "../components/DeliveryOptions";
import PricingForm from "../components/PricingForm";
import RulesForm from "../components/RulesForm";
import { Address } from "../types";

interface ItemFormData {
  name: string;
  description: string;
  pickUpAvailable: boolean;
  inPlaceUseAvailable: boolean;
  pricePerHour?: number | string;
  pricePerDay?: number | string;
  replacementCost: number | string;
  address1: string;
  address2: string;
  city: string;
  state: string;
  zipCode: string;
  country: string;
  latitude?: number;
  longitude?: number;
  rules?: string;
  minimumRentalDays: number;
  needsTraining: boolean;
  generalAvailableAfter: string;
  generalAvailableBefore: string;
  specifyTimesPerDay: boolean;
  weeklyTimes: {
    sunday: { availableAfter: string; availableBefore: string };
    monday: { availableAfter: string; availableBefore: string };
    tuesday: { availableAfter: string; availableBefore: string };
    wednesday: { availableAfter: string; availableBefore: string };
    thursday: { availableAfter: string; availableBefore: string };
    friday: { availableAfter: string; availableBefore: string };
    saturday: { availableAfter: string; availableBefore: string };
  };
}

const CreateItem: React.FC = () => {
  const navigate = useNavigate();
  const { user } = useAuth();
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");
  const [formData, setFormData] = useState<ItemFormData>({
    name: "",
    description: "",
    pickUpAvailable: false,
    inPlaceUseAvailable: false,
    pricePerDay: "",
    replacementCost: "",
    address1: "",
    address2: "",
    city: "",
    state: "",
    zipCode: "",
    country: "US",
    minimumRentalDays: 1,
    needsTraining: false,
    generalAvailableAfter: "09:00",
    generalAvailableBefore: "17:00",
    specifyTimesPerDay: false,
    weeklyTimes: {
      sunday: { availableAfter: "09:00", availableBefore: "17:00" },
      monday: { availableAfter: "09:00", availableBefore: "17:00" },
      tuesday: { availableAfter: "09:00", availableBefore: "17:00" },
      wednesday: { availableAfter: "09:00", availableBefore: "17:00" },
      thursday: { availableAfter: "09:00", availableBefore: "17:00" },
      friday: { availableAfter: "09:00", availableBefore: "17:00" },
      saturday: { availableAfter: "09:00", availableBefore: "17:00" },
    },
  });
  const [imageFiles, setImageFiles] = useState<File[]>([]);
  const [imagePreviews, setImagePreviews] = useState<string[]>([]);
  const [priceType, setPriceType] = useState<"hour" | "day">("day");
  const [userAddresses, setUserAddresses] = useState<Address[]>([]);
  const [selectedAddressId, setSelectedAddressId] = useState<string>("");
  const [addressesLoading, setAddressesLoading] = useState(true);

  useEffect(() => {
    fetchUserAddresses();
    fetchUserAvailability();
  }, []);

  const fetchUserAvailability = async () => {
    try {
      const response = await userAPI.getAvailability();
      const userAvailability = response.data;
      setFormData((prev) => ({
        ...prev,
        generalAvailableAfter: userAvailability.generalAvailableAfter,
        generalAvailableBefore: userAvailability.generalAvailableBefore,
        specifyTimesPerDay: userAvailability.specifyTimesPerDay,
        weeklyTimes: userAvailability.weeklyTimes,
      }));
    } catch (error) {
      console.error("Error fetching user availability:", error);
      // Use default values if fetch fails
    }
  };

  useEffect(() => {
    // Auto-populate if user has exactly one address and addresses have finished loading
    if (
      !addressesLoading &&
      userAddresses.length === 1 &&
      selectedAddressId === ""
    ) {
      const address = userAddresses[0];
      setFormData((prev) => ({
        ...prev,
        address1: address.address1,
        address2: address.address2 || "",
        city: address.city,
        state: address.state,
        zipCode: address.zipCode,
        country: address.country,
        latitude: address.latitude,
        longitude: address.longitude,
      }));
      setSelectedAddressId(address.id);
    }
  }, [userAddresses, addressesLoading]);

  const fetchUserAddresses = async () => {
    try {
      const response = await addressAPI.getAddresses();
      setUserAddresses(response.data);
    } catch (error) {
      console.error("Error fetching addresses:", error);
    } finally {
      setAddressesLoading(false);
    }
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!user) {
      setError("You must be logged in to create a listing");
      return;
    }

    setLoading(true);
    setError("");

    try {
      // For now, we'll store image URLs as base64 strings
      // In production, you'd upload to a service like S3
      const imageUrls = imagePreviews;

      // Construct location from address components
      const locationParts = [
        formData.address1,
        formData.address2,
        formData.city,
        formData.state,
        formData.zipCode,
        formData.country,
      ].filter((part) => part && part.trim());

      const location = locationParts.join(", ");

      const response = await api.post("/items", {
        ...formData,
        pricePerDay: formData.pricePerDay
          ? parseFloat(formData.pricePerDay.toString())
          : undefined,
        pricePerHour: formData.pricePerHour
          ? parseFloat(formData.pricePerHour.toString())
          : undefined,
        replacementCost: formData.replacementCost
          ? parseFloat(formData.replacementCost.toString())
          : 0,
        availableAfter: formData.generalAvailableAfter,
        availableBefore: formData.generalAvailableBefore,
        specifyTimesPerDay: formData.specifyTimesPerDay,
        weeklyTimes: formData.weeklyTimes,
        location,
        images: imageUrls,
      });

      // Auto-save address if user has no addresses and entered manual address
      if (userAddresses.length === 0 && formData.address1) {
        try {
          await addressAPI.createAddress({
            address1: formData.address1,
            address2: formData.address2,
            city: formData.city,
            state: formData.state,
            zipCode: formData.zipCode,
            country: formData.country,
            latitude: formData.latitude,
            longitude: formData.longitude,
            isPrimary: true,
          });
        } catch (addressError) {
          console.error("Failed to save address:", addressError);
          // Don't fail item creation if address save fails
        }
      }

      // Check if this is user's first item and save availability settings
      try {
        const userItemsResponse = await itemAPI.getItems({ owner: user.id });
        const userItems = userItemsResponse.data.items || [];

        // If this is their first item (the one we just created), save availability to user
        if (userItems.length <= 1) {
          await userAPI.updateAvailability({
            generalAvailableAfter: formData.generalAvailableAfter,
            generalAvailableBefore: formData.generalAvailableBefore,
            specifyTimesPerDay: formData.specifyTimesPerDay,
            weeklyTimes: formData.weeklyTimes,
          });
        }
      } catch (availabilityError) {
        console.error("Failed to save availability:", availabilityError);
        // Don't fail item creation if availability save fails
      }

      navigate(`/items/${response.data.id}`);
    } catch (err: any) {
      setError(err.response?.data?.error || "Failed to create listing");
    } finally {
      setLoading(false);
    }
  };

  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) || 0,
      }));
    } else {
      setFormData((prev) => ({ ...prev, [name]: value }));
    }
  };

  const handleAddressSelect = (addressId: string) => {
    if (addressId === "new") {
      // Clear form for new address entry
      setFormData((prev) => ({
        ...prev,
        address1: "",
        address2: "",
        city: "",
        state: "",
        zipCode: "",
        country: "US",
      }));
      setSelectedAddressId("");
    } else {
      const selectedAddress = userAddresses.find(
        (addr) => addr.id === addressId
      );
      if (selectedAddress) {
        setFormData((prev) => ({
          ...prev,
          address1: selectedAddress.address1,
          address2: selectedAddress.address2 || "",
          city: selectedAddress.city,
          state: selectedAddress.state,
          zipCode: selectedAddress.zipCode,
          country: selectedAddress.country,
          latitude: selectedAddress.latitude,
          longitude: selectedAddress.longitude,
        }));
        setSelectedAddressId(addressId);
      }
    }
  };

  const formatAddressDisplay = (address: Address) => {
    return `${address.address1}, ${address.city}, ${address.state} ${address.zipCode}`;
  };

  const handleWeeklyTimeChange = (
    day: string,
    field: "availableAfter" | "availableBefore",
    value: string
  ) => {
    setFormData((prev) => ({
      ...prev,
      weeklyTimes: {
        ...prev.weeklyTimes,
        [day]: {
          ...prev.weeklyTimes[day as keyof typeof prev.weeklyTimes],
          [field]: value,
        },
      },
    }));
  };

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

    // Limit to 5 images
    if (imageFiles.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) => {
    setImageFiles((prev) => prev.filter((_, i) => i !== index));
    setImagePreviews((prev) => prev.filter((_, i) => i !== index));
  };

  return (
    <div className="container mt-4">
      <div className="row justify-content-center">
        <div className="col-md-8">
          <h1>List an Item for Rent</h1>

          {error && (
            <div className="alert alert-danger" role="alert">
              {error}
            </div>
          )}

          <form onSubmit={handleSubmit}>
            <ImageUpload
              imageFiles={imageFiles}
              imagePreviews={imagePreviews}
              onImageChange={handleImageChange}
              onRemoveImage={removeImage}
              error={error}
            />

            <ItemInformation
              name={formData.name}
              description={formData.description}
              onChange={handleChange}
            />

            <LocationForm
              data={{
                address1: formData.address1,
                address2: formData.address2,
                city: formData.city,
                state: formData.state,
                zipCode: formData.zipCode,
                country: formData.country,
                latitude: formData.latitude,
                longitude: formData.longitude,
              }}
              userAddresses={userAddresses}
              selectedAddressId={selectedAddressId}
              addressesLoading={addressesLoading}
              onChange={handleChange}
              onAddressSelect={handleAddressSelect}
              formatAddressDisplay={formatAddressDisplay}
            />

            <DeliveryOptions
              pickUpAvailable={formData.pickUpAvailable}
              inPlaceUseAvailable={formData.inPlaceUseAvailable}
              onChange={handleChange}
            />

            {/* Availability Card */}
            <div className="card mb-4">
              <div className="card-body">
                <AvailabilitySettings
                  data={{
                    generalAvailableAfter: formData.generalAvailableAfter,
                    generalAvailableBefore: formData.generalAvailableBefore,
                    specifyTimesPerDay: formData.specifyTimesPerDay,
                    weeklyTimes: formData.weeklyTimes,
                  }}
                  onChange={(field, value) => {
                    setFormData((prev) => ({ ...prev, [field]: value }));
                  }}
                  onWeeklyTimeChange={handleWeeklyTimeChange}
                />
              </div>
            </div>

            <PricingForm
              priceType={priceType}
              pricePerHour={formData.pricePerHour || ""}
              pricePerDay={formData.pricePerDay || ""}
              replacementCost={formData.replacementCost}
              minimumRentalDays={formData.minimumRentalDays}
              onPriceTypeChange={setPriceType}
              onChange={handleChange}
            />

            <RulesForm
              needsTraining={formData.needsTraining}
              rules={formData.rules || ""}
              onChange={handleChange}
            />

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

export default CreateItem;
