import {
  createFileRoute,
  useNavigate,
  useSearch,
} from "@tanstack/react-router";
import { useState, useMemo, useEffect } from "react";
import dayjs from "dayjs";
import {
  p,
  div,
  Quantifier,
  MiniQuantifier,
} from "web-components";
import {
  useSlots,
  useAllProducts,
  useStores,
} from "../hooks/prominent-api-hooks";
import { useCentralProductStore } from "../lib/stores/central-product-store";
import { useCentralSlotStore } from "../lib/stores/central-slot-store";
import {
  useAddToCart,
  useGetCart,
  useUpdateCartItem,
  useRemoveFromCart,
} from "../hooks/cart-query-hooks";
import { usePopulateCentralProductStore } from "../hooks/usePopulateCentralProductStore";
import { AppLayout } from "../components/AppLayout";
import { Truck, Store, Grid3X3, ChevronLeft, ShoppingCart, Clock, ChevronDown } from "lucide-react";
import { Dialog } from "../components/Dialog";

export const Route = createFileRoute("/slot-view")({
  component: SlotViewPage,
});

function SlotViewPage() {
  const search = useSearch({ from: "/slot-view" }) as {
    slotId?: string;
    storeId?: string;
  };
  const slotId = search.slotId ? Number(search.slotId) : undefined;
  const storeId = search.storeId ? Number(search.storeId) : undefined;

  const navigate = useNavigate();
  const { data: slotsData } = useSlots();
  const { productsById } = useCentralProductStore();
  const productSlotsMap = useCentralSlotStore((state) => state.productSlotsMap);
  const { data: storesData } = useStores();
  const [showSlotDialog, setShowSlotDialog] = useState(false);

  // Populate central product store with products data
  usePopulateCentralProductStore();

  const stores = storesData?.stores || [];

  // Find the specific slot from cached data
  const slot = slotsData?.slots?.find((s: any) => s.id === slotId);

  // Find earliest slot for pre-selection
  const earliestSlot = slotsData?.slots
    ?.filter((s: any) => dayjs(s.deliveryTime).isAfter(dayjs()))
    .sort((a: any, b: any) => dayjs(a.deliveryTime).diff(dayjs(b.deliveryTime)))[0];

  const addToCart = useAddToCart("regular");
  const { data: cartData } = useGetCart("regular");

  const formatTimeRange = (deliveryTime: string) => {
    const time = dayjs(deliveryTime);
    const endTime = time.add(1, "hour");
    const startPeriod = time.format("A");
    const endPeriod = endTime.format("A");

    if (startPeriod === endPeriod) {
      return `${time.format("h")}-${endTime.format("h")} ${startPeriod}`;
    } else {
      return `${time.format("h:mm")} ${startPeriod} - ${endTime.format("h:mm")} ${endPeriod}`;
    }
  };

  const formatFullDisplay = (deliveryTime: string) => {
    const time = dayjs(deliveryTime);
    const endTime = time.add(1, "hour");
    const startPeriod = time.format("A");
    const endPeriod = endTime.format("A");

    let timeRange;
    if (startPeriod === endPeriod) {
      timeRange = `${time.format("h")}-${endTime.format("h")} ${startPeriod}`;
    } else {
      timeRange = `${time.format("h:mm")} ${startPeriod} - ${endTime.format("h:mm")} ${endPeriod}`;
    }

    return `${time.format("ddd, DD MMM ")}${timeRange}`;
  };

  // Get current selected slot display
  const getCurrentSlotDisplay = () => {
    if (slotId) {
      const s = slotsData?.slots?.find((s: any) => s.id === slotId);
      return s ? formatFullDisplay(s.deliveryTime as any) : 'Select time';
    }
    if (earliestSlot) {
      return formatFullDisplay(earliestSlot.deliveryTime as any);
    }
    return 'Select time';
  };

  const handleAddToCart = (productId: number) => {
    const item = filteredProducts.find((p) => p.id === productId);
    const deliveryTime = slot?.deliveryTime
      ? dayjs(slot.deliveryTime).format("ddd, DD MMM • h:mm A")
      : "";
    addToCart.mutate(
      { productId, quantity: 1, slotId: slotId || 0, storeId: item?.storeId },
      {
        onSuccess: () => {
          alert(
            `Added ${item?.name || "item"} for delivery at ${deliveryTime}`,
          );
        },
      },
    );
  };

  const handleSlotChange = (newSlotId: number) => {
    navigate({
      to: "/slot-view",
      search: { slotId: newSlotId, storeId },
    });
    setShowSlotDialog(false);
  };

  // Get product details from central store using slot product IDs
  const slotProducts =
    slot?.products
      ?.map((p: any) => productsById[p.id])
      ?.filter(
        (product: any): product is NonNullable<typeof product> =>
          product !== null && product !== undefined,
      )
      ?.filter((product: any) => !productSlotsMap[product.id]?.isOutOfStock) ||
    [];

  const filteredProducts = storeId
    ? slotProducts.filter((p: any) => p.storeId === storeId)
    : slotProducts;

  // Transform slots for display
  const slotOptions = slotsData?.slots
    ?.filter((s: any) => dayjs(s.deliveryTime).isAfter(dayjs()))
    .sort((a: any, b: any) => dayjs(a.deliveryTime).diff(dayjs(b.deliveryTime)))
    .map((s: any) => ({
      id: s.id,
      deliveryTime: formatFullDisplay(s.deliveryTime),
      closeTime: dayjs(s.freezeTime).format("h:mm A"),
    })) || [];

  if (!slot) {
    return (
      <AppLayout>
        <div className="flex min-h-screen flex-col items-center justify-center">
          <p className="font-bold mb-4 text-2xl text-gray-900">
            Slot View
          </p>
          <p className="text-gray-600">No delivery slot available.</p>
        </div>
      </AppLayout>
    );
  }

  return (
    <AppLayout>
      <div className="min-h-screen bg-gray-50">
        {/* Header with Dropdown - Matching Mobile App */}
        <div className="sticky top-0 z-20 border-b border-gray-200 bg-white px-4 py-3">
          <div className="flex items-center gap-2">
            {/* Back Button */}
            <button
              onClick={() => navigate({ to: "/home" })}
              className="p-1 hover:bg-gray-100 rounded-full"
            >
              <ChevronLeft className="h-6 w-6 text-gray-700" />
            </button>

            {/* Delivery Time Dropdown */}
            <div className="flex-1">
              <button
                onClick={() => setShowSlotDialog(true)}
                className="flex w-full items-center justify-between rounded-lg border border-brand-200 bg-brand-50 px-3 py-2"
              >
                <div className="flex-1 text-left">
                  <p className="text-xs font-bold uppercase text-brand-500">Delivery Time</p>
                  <p className="text-sm font-bold text-brand-900">
                    {getCurrentSlotDisplay()}
                  </p>
                </div>
                <ChevronDown className="h-5 w-5 text-brand-500" />
              </button>
            </div>
          </div>
        </div>

        <div className="flex flex-row">
          {/* StoreSidebar - Fixed width on left for both mobile and desktop */}
          <div className="w-20 shrink-0 md:w-24">
            <StoreSidebar
              stores={stores}
              slotId={slotId}
              storeId={storeId}
              onStoreSelect={(newStoreId) =>
                navigate({
                  to: "/slot-view",
                  search: { slotId, storeId: newStoreId },
                })
              }
              onAllSelect={() =>
                navigate({ to: "/slot-view", search: { slotId } })
              }
            />
          </div>

          {/* Products Grid */}
          <div className="flex-1 p-4">
            <div className="mb-4 flex items-center justify-between">
              <p className="font-bold text-xl text-gray-900">
                {storeId
                  ? stores.find((s: any) => s.id === storeId)?.name ||
                    "Store Products"
                  : "All Products"}
              </p>
              <p className="text-sm text-gray-500">
                {filteredProducts.length} items
              </p>
            </div>

            <div className="grid grid-cols-2 gap-3 sm:gap-4 md:grid-cols-3 lg:grid-cols-4">
              {filteredProducts.map((product: any) => (
                <CompactProductCard
                  key={product.id}
                  item={product}
                  handleAddToCart={handleAddToCart}
                  onPress={() =>
                    navigate({
                      to: "/home/product/$id",
                      params: { id: String(product.id) },
                    })
                  }
                />
              ))}
            </div>

            {filteredProducts.length === 0 && (
              <div className="py-10 text-center">
                <p className="font-medium text-gray-400">
                  {storeId
                    ? "No products from this store in this slot."
                    : "No products available for this slot."}
                </p>
              </div>
            )}
          </div>
        </div>

        {/* Slot Selection Dialog */}
        <Dialog open={showSlotDialog} onClose={() => setShowSlotDialog(false)} title="Select Delivery Time">
          <div className="max-h-[60vh] overflow-y-auto p-4">
            {slotOptions.map((slotOption) => (
              <button
                key={slotOption.id}
                onClick={() => handleSlotChange(slotOption.id)}
                className={`mb-2 w-full rounded-lg border p-3 text-left transition-colors ${
                  slotOption.id === (slotId || earliestSlot?.id)
                    ? 'border-brand-500 bg-brand-50'
                    : 'border-gray-200 bg-white hover:bg-gray-50'
                }`}
              >
                <p className="font-medium text-gray-900">
                  Delivery: {slotOption.deliveryTime}
                </p>
                <p className="mt-1 text-xs text-gray-500">
                  Orders Close at: {slotOption.closeTime}
                </p>
              </button>
            ))}
          </div>
        </Dialog>
      </div>
    </AppLayout>
  );
}

interface StoreSidebarProps {
  stores: any[];
  slotId?: number;
  storeId?: number;
  onStoreSelect: (storeId: number) => void;
  onAllSelect: () => void;
}

function StoreSidebar({
  stores,
  slotId,
  storeId,
  onStoreSelect,
  onAllSelect,
}: StoreSidebarProps) {
  return (
    <div className="sticky top-[73px] z-10 h-[calc(100vh-73px)] w-full overflow-y-auto border-r border-gray-200 bg-white p-2 md:top-0 md:h-auto md:p-3">
      <div className="flex flex-col gap-2 md:gap-3">
        {/* All Products Item */}
        <div
          onClick={onAllSelect}
          className={`flex flex-col items-center rounded-2xl p-2 md:p-3 ${
            !storeId
              ? "bg-gradient-to-br from-brand-400 to-brand-600 text-white shadow-lg"
              : "border border-gray-100 bg-white text-gray-500"
          }`}
        >
          <div
            className={`mb-1 flex h-8 w-8 items-center justify-center rounded-full border md:h-10 md:w-10 ${
              !storeId ? "border-white/30 bg-white/20" : "bg-gray-50"
            }`}
          >
            <Grid3X3
              className={`h-4 w-4 md:h-5 md:w-5 ${!storeId ? "text-white" : "text-gray-500"}`}
            />
          </div>
          <p
            className={`text-center text-[10px] font-bold ${!storeId ? "text-white" : "text-gray-500"}`}
          >
            ALL
          </p>
        </div>

        <div className="h-px bg-gray-200 my-1" />

        {/* Store Items */}
        {stores.map((store: any) => {
          const isActive = storeId === store.id;

          return (
            <div
              key={store.id}
              onClick={() => onStoreSelect(store.id)}
              className={`flex flex-col items-center rounded-2xl p-2 ${
                isActive
                  ? "bg-gradient-to-br from-brand-400 to-brand-600 text-white shadow-lg"
                  : "border border-gray-100 bg-white text-gray-500"
              }`}
            >
              <div
                className={`mb-1 md:mb-2 flex h-10 w-10 items-center justify-center overflow-hidden rounded-full border-2 md:h-12 md:w-12 ${
                  isActive
                    ? "border-white bg-white"
                    : "border-gray-100 bg-gray-50"
                }`}
              >
                {store.signedImageUrl ? (
                  <img
                    src={store.signedImageUrl}
                    alt={store.name}
                    className="h-full w-full object-cover"
                  />
                ) : (
                  <Store
                    className={`h-5 w-5 md:h-6 md:w-6 ${isActive ? "text-brand-500" : "text-gray-400"}`}
                  />
                )}
              </div>
              <p
                className={`w-full text-center text-[10px] leading-tight ${
                  isActive
                    ? "font-bold text-white"
                    : "font-medium text-gray-500"
                }`}
              >
                {store.name.replace(/^The\s+/i, "")}
              </p>
            </div>
          );
        })}
      </div>
    </div>
  );
}

const formatQuantity = (
  quantity: number,
  unit: string,
): { value: string; display: string } => {
  if (unit?.toLowerCase() === "kg" && quantity < 1) {
    return {
      value: `${Math.round(quantity * 1000)} g`,
      display: `${Math.round(quantity * 1000)}g`,
    };
  }
  return { value: `${quantity} ${unit}(s)`, display: `${quantity}${unit}` };
};

interface CompactProductCardProps {
  item: any;
  handleAddToCart: (productId: number) => void;
  onPress?: () => void;
}

function CompactProductCard({
  item,
  handleAddToCart,
  onPress,
}: CompactProductCardProps) {
  const { data: cartData } = useGetCart("regular");
  const productSlotsMap = useCentralSlotStore((state) => state.productSlotsMap);
  const updateCartItem = useUpdateCartItem("regular");
  const removeFromCart = useRemoveFromCart("regular");

  const cartItem = cartData?.items?.find(
    (cartItem: any) => cartItem.productId === item.id,
  );
  const quantity = cartItem?.quantity || 0;
  const isOutOfStock = productSlotsMap[item.id]?.isOutOfStock;

  const handleQuantityChange = (newQuantity: number) => {
    if (newQuantity === 0 && cartItem) {
      removeFromCart.mutate(cartItem.id);
    } else if (newQuantity === 1 && !cartItem) {
      handleAddToCart(item.id);
    } else if (cartItem) {
      updateCartItem.mutate({ productId: cartItem.id, quantity: newQuantity });
    }
  };

  return (
    <div
      onClick={onPress}
      className="mb-2 overflow-hidden rounded-lg border border-gray-100 bg-white shadow-sm"
    >
      <div className="relative">
        <img
          src={item.images?.[0]}
          alt={item.name}
          className="aspect-square w-full object-cover"
        />
        {isOutOfStock && (
          <div className="absolute inset-0 flex items-center justify-center bg-black/30">
            <p className="text-xs font-bold text-white">
              Out of Stock
            </p>
          </div>
        )}
        <div className="absolute bottom-2 right-2">
          {quantity > 0 ? (
            <MiniQuantifier
              value={quantity}
              setValue={handleQuantityChange}
              step={item.incrementStep}
            />
          ) : (
            <div
              className="flex h-8 w-8 items-center justify-center rounded-full bg-white shadow-md"
              onClick={(e) => {
                e.stopPropagation();
                handleQuantityChange(1);
              }}
            >
              <ShoppingCart className="h-4 w-4 text-brand-500" />
            </div>
          )}
        </div>
      </div>

      <div className="p-2">
        <p
          className="font-medium mb-1 text-xs text-gray-900"
        >
          {item.name}
        </p>

        <div className="flex items-center justify-between">
          <div className="flex flex-wrap items-baseline">
            <p className="font-bold text-sm text-brand-500">
              ₹{item.price}
            </p>
            {item.marketPrice &&
              Number(item.marketPrice) > Number(item.price) && (
                <p className="ml-1 text-xs text-gray-400 line-through">
                  ₹{item.marketPrice}
                </p>
              )}
            <p className="ml-1 text-xs text-gray-600">
              Qty:{" "}
              <span className="font-semibold text-brand-500">
                {
                  formatQuantity(
                    item.productQuantity || 1,
                    item.unit || item.unitNotation,
                  ).display
                }
              </span>
            </p>
          </div>
        </div>
      </div>
    </div>
  );
}