"use client";

import { useState } from "react";

type Shop = {
  id: number;
  label: string;
};

type UserData = {
  shops: Shop[];
};

type ItemFromApi = {
  item_name: string;
  stock: number;
  shop: Shop;
};

type SellableFromApi = {
  shopId: number;
  item_name: string;
  price: number;
  amount: number;
  shop: {
    label: string;
  };
};

type Props = {
  loading: boolean;
  reloadSellable: () => Promise<void>;
  reloadUser: () => Promise<void>;
};

const formatName = (name: string) => {
  const parts = name.split(":");
  if (!parts[1]) return "";
  return parts[1]
    .split("_")
    .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
    .join(" ");
};

const getModId = (name: string) => {
  const [modId] = name.split(":");
  return modId ?? "";
};

export default function SellableItemsButton({
  loading,
  reloadSellable,
  reloadUser,
}: Props) {
  const [isOpen, setIsOpen] = useState(false);

  const [items, setItems] = useState<ItemFromApi[]>([]);
  const [sellables, setSellables] = useState<SellableFromApi[]>([]);
  const [userShops, setUserShops] = useState<Shop[]>([]);
  const [search, setSearch] = useState("");

  const [selectedIndex, setSelectedIndex] = useState<number | null>(null);
  const [price, setPrice] = useState<number | "">("");
  const [amount, setAmount] = useState<number | "">("");

  const [editingKey, setEditingKey] = useState<string | null>(null);
  const [editPrice, setEditPrice] = useState<number | "">("");
  const [editAmount, setEditAmount] = useState<number | "">("");

  // Format price as 0.00$
  const formatPrice = (p: number) => `${p.toFixed(2)}$`;
  const sellableKey = (s: SellableFromApi) => `${s.shopId}:${s.item_name}`;

  /* ─────────────── LOAD ALL DATA ─────────────── */
  const loadAll = async (): Promise<boolean> => {
    try {
      const [userRes, itemsRes, sellablesRes] = await Promise.all([
        fetch("/api/user", { cache: "no-store" }),
        fetch("/api/items", { cache: "no-store" }),
        fetch("/api/sellable", { cache: "no-store" }),
      ]);

      if (!userRes.ok || !itemsRes.ok || !sellablesRes.ok) {
        console.error("Failed to load data");
        return false;
      }

      const userData: UserData = (await userRes.json()) as UserData;
      const itemsData = (await itemsRes.json()) as ItemFromApi[];
      const sellablesData = (await sellablesRes.json()) as SellableFromApi[];

      setUserShops(userData.shops ?? []);
      setItems(itemsData);
      setSellables(sellablesData);

      return true;
    } catch (err) {
      console.error("Error loading data", err);
      return false;
    }
  };

  const openModal = async () => {
    const ok = await loadAll();
    if (ok) setIsOpen(true);
  };

  /* ─────────────── ADD SELLABLE ─────────────── */
  const addSellable = async () => {
    if (selectedIndex === null || price === "" || amount === "") return;

    const item = items[selectedIndex];

    if (!item) return;

    const res = await fetch("/api/sellable", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        shopId: item.shop.id,
        itemId: item.item_name,
        price,
        amount,
      }),
    });

    if (!res.ok) {
      console.error("Failed to add sellable");
      return;
    }

    // Update state locally so item disappears immediately
    setSellables((prev) => [
      ...prev,
      {
        shopId: item.shop.id,
        item_name: item.item_name,
        price,
        amount,
        shop: { label: item.shop.label },
      },
    ]);

    setSelectedIndex(null);
    setPrice("");
    setAmount("");

    void reloadSellable();
    void reloadUser();
  };

  /* ─────────────── REMOVE SELLABLE ─────────────── */
  const removeSellable = async (shopId: number, itemId: string) => {
    const res = await fetch("/api/sellable", {
      method: "DELETE",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ shopId, itemId }),
    });

    if (!res.ok) {
      console.error("Failed to remove sellable");
      return;
    }

    // Remove locally
    setSellables((prev) =>
      prev.filter((s) => !(s.shopId === shopId && s.item_name === itemId)),
    );

    void reloadSellable();
    void reloadUser();
  };

  /* ─────────────── EDIT SELLABLE ─────────────── */
  const saveEdit = async (shopId: number, itemId: string) => {
    if (editPrice === "" || editAmount === "") return;

    const res = await fetch("/api/sellable", {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        shopId,
        itemId,
        price: editPrice,
        amount: editAmount,
      }),
    });

    if (!res.ok) {
      console.error("Failed to update sellable");
      return;
    }

    // Update locally
    setSellables((prev) =>
      prev.map((s) =>
        s.shopId === shopId && s.item_name === itemId
          ? { ...s, price: editPrice, amount: editAmount }
          : s,
      ),
    );

    setEditingKey(null);
    void reloadSellable();
    void reloadUser();
  };

  /* ─────────────── FILTERING ─────────────── */
  const userShopIds = new Set(userShops.map((s) => s.id));

  // Items available to add (user's shops, not already sold)
  const availableItems = items
    .filter((item) => userShopIds.has(item.shop.id))
    .filter(
      (item) =>
        !sellables.some(
          (s) => s.shopId === item.shop.id && s.item_name === item.item_name,
        ),
    )
    .filter(
      (item) =>
        formatName(item.item_name)
          .toLowerCase()
          .includes(search.toLowerCase()) ||
        getModId(item.item_name).toLowerCase().includes(search.toLowerCase()) ||
        item.item_name.toLowerCase().includes(search.toLowerCase()),
    );

  // Sellables grouped by user's shops
  const sellablesByShop = sellables.reduce<Record<number, SellableFromApi[]>>(
    (acc, s) => {
      if (!userShopIds.has(s.shopId)) return acc;
      acc[s.shopId] ??= [];
      acc[s.shopId].push(s);
      return acc;
    },
    {},
  );

  /* ─────────────── UI ─────────────── */
  return (
    <>
      {/* BUTTON */}
      <button
        className="relative rounded-full bg-white/10 px-4 py-2 font-semibold hover:bg-white/20"
        disabled={loading}
        onClick={openModal}
      >
        <img src="/icons/list_add.svg" alt="Shop Icon" className="h-6 w-6" />
      </button>

      {/* MODAL */}
      {isOpen && (
        <div className="fixed inset-0 z-50 flex items-center justify-center">
          <div
            className="absolute inset-0 bg-black/50 backdrop-blur-sm"
            onClick={() => setIsOpen(false)}
          />

          <div className="relative z-10 w-full max-w-2xl rounded-xl bg-neutral-900 p-6 text-white shadow-xl">
            <h2 className="mb-6 text-xl font-bold">Store Items</h2>

            {/* ───────── CURRENTLY SOLD ───────── */}
            <section className="mb-8">
              <h3 className="mb-3 text-lg font-semibold">
                Currently Sold (Your Shops)
              </h3>

              {Object.keys(sellablesByShop).length === 0 && (
                <p className="text-sm text-neutral-400">
                  No items are currently sold.
                </p>
              )}

              <div className="space-y-4">
                {Object.entries(sellablesByShop).map(([shopId, items]) => (
                  <div key={shopId} className="rounded-lg bg-white/5 p-3">
                    <h4 className="mb-2 font-semibold">
                      {items[0]?.shop.label ?? `Shop ${shopId}`}
                    </h4>

                    <ul className="space-y-1 text-sm">
                      {items.map((s) => {
                        const key = sellableKey(s);
                        const isEditing = editingKey === key;

                        return (
                          <li
                            key={key}
                            className="flex items-center justify-between gap-2 rounded bg-black/20 px-2 py-1"
                          >
                            <span className="flex-1">{s.item_name}</span>

                            {isEditing ? (
                              <>
                                <input
                                  type="number"
                                  step={0.01}
                                  value={editPrice}
                                  onChange={(e) =>
                                    setEditPrice(
                                      e.target.value === ""
                                        ? ""
                                        : Number(e.target.value),
                                    )
                                  }
                                  className="w-20 rounded bg-white/10 px-2 py-1 text-xs"
                                  placeholder="Price (0.00$)"
                                />
                                <input
                                  type="number"
                                  value={editAmount}
                                  min={1}
                                  onChange={(e) =>
                                    setEditAmount(
                                      e.target.value === ""
                                        ? ""
                                        : Number(e.target.value),
                                    )
                                  }
                                  className="w-20 rounded bg-white/10 px-2 py-1 text-xs"
                                />

                                <button
                                  onClick={() =>
                                    saveEdit(s.shopId, s.item_name)
                                  }
                                  className="text-xs font-bold text-green-400"
                                >
                                  Save
                                </button>
                                <button
                                  onClick={() => setEditingKey(null)}
                                  className="text-xs text-neutral-400"
                                >
                                  Cancel
                                </button>
                              </>
                            ) : (
                              <>
                                <span className="text-xs text-neutral-400">
                                  {s.amount} × {formatPrice(s.price)}
                                </span>

                                <button
                                  onClick={() => {
                                    setEditingKey(key);
                                    setEditPrice(s.price);
                                    setEditAmount(s.amount);
                                  }}
                                  className="text-xs text-blue-400"
                                >
                                  Edit
                                </button>

                                <button
                                  onClick={() =>
                                    removeSellable(s.shopId, s.item_name)
                                  }
                                  className="text-xs text-red-400"
                                >
                                  Remove
                                </button>
                              </>
                            )}
                          </li>
                        );
                      })}
                    </ul>
                  </div>
                ))}
              </div>
            </section>

            {/* ───────── ADD NEW ───────── */}
            <section>
              <h3 className="mb-3 text-lg font-semibold">Add Item to Store</h3>

              <input
                type="text"
                value={search}
                onChange={(e) => {
                  setSearch(e.target.value);
                  setSelectedIndex(null); // reset selection when filtering
                }}
                placeholder="Search item by name..."
                className="mb-3 w-full rounded bg-white/10 px-3 py-2 text-sm placeholder:text-neutral-400"
              />

              <ul className="mb-4 max-h-56 space-y-2 overflow-y-auto">
                {availableItems.map((item, index) => (
                  <li
                    key={`${item.shop.id}-${item.item_name}`}
                    onClick={() => setSelectedIndex(index)}
                    className={`cursor-pointer rounded px-3 py-2 ${
                      selectedIndex === index
                        ? "bg-green-500/20 ring-1 ring-green-500"
                        : "bg-white/5 hover:bg-white/10"
                    }`}
                  >
                    <div className="flex justify-between text-sm">
                      <span>{formatName(item.item_name)}</span>
                      <span className="text-neutral-400">
                        {item.shop.label}
                      </span>
                    </div>
                    <div className="text-xs text-neutral-400">
                      Stock: {item.stock}
                    </div>
                  </li>
                ))}
              </ul>

              <div className="grid grid-cols-2 gap-3">
                <input
                  type="number"
                  step={0.01}
                  min={0}
                  value={price}
                  onChange={(e) =>
                    setPrice(
                      e.target.value === "" ? "" : Number(e.target.value),
                    )
                  }
                  placeholder="Price (0.00$)"
                  className="rounded bg-white/10 px-3 py-2 text-sm"
                />
                <input
                  type="number"
                  min={1}
                  value={amount}
                  onChange={(e) =>
                    setAmount(
                      e.target.value === "" ? "" : Number(e.target.value),
                    )
                  }
                  placeholder="Amount"
                  className="rounded bg-white/10 px-3 py-2 text-sm"
                />
              </div>

              <button
                onClick={addSellable}
                disabled={selectedIndex === null}
                className="mt-4 w-full rounded bg-green-500 py-3 font-bold text-black hover:bg-green-600 disabled:bg-gray-400"
              >
                Add to Store
              </button>
            </section>
          </div>
        </div>
      )}
    </>
  );
}
