import { useCallback, useEffect, useState } from "react";
import {
  createAvailableItem,
  deleteAvailableItem,
  getAvailableItems,
  updateAvailableItem,
} from "../../api/availableItems";
import { getLocationZones } from "../../api/stores";
import useActionToast from "../../hooks/useActionToast";
import getApiErrorMessage from "../../lib/getApiErrorMessage";
import AvailableItemEditorModal from "../modals/AvailableItemEditorModal";
import ConfirmSlideModal from "../modals/ConfirmSlideModal";

function itemImageSource(item) {
  if (!item?.item_image) {
    return null;
  }

  const mimeType = item.image_mime_type || "image/jpeg";
  return `data:${mimeType};base64,${item.item_image}`;
}

export default function StoreAvailableItemsManager({ householdId, store, isAdmin }) {
  const toast = useActionToast();
  const [isOpen, setIsOpen] = useState(false);
  const [items, setItems] = useState([]);
  const [zones, setZones] = useState([]);
  const [catalogReady, setCatalogReady] = useState(true);
  const [catalogMessage, setCatalogMessage] = useState("");
  const [query, setQuery] = useState("");
  const [loading, setLoading] = useState(false);
  const [editorItem, setEditorItem] = useState(null);
  const [showEditor, setShowEditor] = useState(false);
  const [deleteMode, setDeleteMode] = useState(false);
  const [selectedDeleteIds, setSelectedDeleteIds] = useState(() => new Set());
  const [pendingDeleteItems, setPendingDeleteItems] = useState([]);

  const selectedDeleteItems = items.filter((item) => selectedDeleteIds.has(item.item_id));
  const selectedDeleteCount = selectedDeleteItems.length;

  const loadItems = useCallback(async (search = query) => {
    if (!householdId || !store?.id) {
      setItems([]);
      return;
    }

    setLoading(true);
    try {
      const response = await getAvailableItems(householdId, store.id, search);
      setItems(response.data.items || []);
      setCatalogReady(response.data.catalog_ready !== false);
      setCatalogMessage(response.data.message || "");
    } catch (error) {
      console.error("Failed to load store items:", error);
      setCatalogReady(false);
      setCatalogMessage("Store item management is unavailable right now.");
      const message = getApiErrorMessage(error, "Failed to load store items");
      toast.error("Load store items failed", `Load store items failed: ${message}`);
    } finally {
      setLoading(false);
    }
  }, [householdId, query, store?.id, toast]);

  const loadZones = useCallback(async () => {
    if (!householdId || !store?.id) {
      setZones([]);
      return;
    }

    try {
      const response = await getLocationZones(householdId, store.id);
      setZones(response.data?.zones || []);
    } catch (error) {
      console.error("Failed to load location zones:", error);
      setZones([]);
    }
  }, [householdId, store?.id]);

  useEffect(() => {
    if (!isOpen) {
      return;
    }

    loadItems(query);
    loadZones();
  }, [isOpen, query, loadItems, loadZones]);

  const closeManager = () => {
    setIsOpen(false);
    setDeleteMode(false);
    setSelectedDeleteIds(new Set());
    setPendingDeleteItems([]);
  };

  const handleUpdate = async (payload) => {
    if (!catalogReady) {
      toast.info(
        "Store item management unavailable",
        catalogMessage || "Store item management is unavailable until the latest database migration is applied."
      );
      return;
    }

    try {
      if (editorItem?.item_id) {
        await updateAvailableItem(householdId, store.id, editorItem.item_id, payload);
        toast.success("Updated store item", `Updated ${editorItem.item_name} for ${store.display_name || store.name}`);
      } else {
        const response = await createAvailableItem(householdId, store.id, payload);
        toast.success(
          "Created store item",
          `Created ${response.data?.item?.item_name || payload.itemName} for ${store.display_name || store.name}`
        );
      }
      setShowEditor(false);
      setEditorItem(null);
      await loadItems(query);
    } catch (error) {
      const message = getApiErrorMessage(error, "Failed to update store item");
      toast.error("Update store item failed", `Update store item failed: ${message}`);
      throw error;
    }
  };

  const openEditor = (item) => {
    setEditorItem(item);
    setShowEditor(true);
  };

  const toggleDeleteSelection = (itemId) => {
    setSelectedDeleteIds((currentIds) => {
      const nextIds = new Set(currentIds);

      if (nextIds.has(itemId)) {
        nextIds.delete(itemId);
      } else {
        nextIds.add(itemId);
      }

      return nextIds;
    });
  };

  const startDeleteMode = () => {
    setDeleteMode(true);
    setSelectedDeleteIds(new Set());
  };

  const cancelDeleteMode = () => {
    setDeleteMode(false);
    setSelectedDeleteIds(new Set());
  };

  const confirmSelectedDelete = () => {
    if (selectedDeleteCount === 0) {
      return;
    }

    setPendingDeleteItems(selectedDeleteItems);
  };

  const handleDeleteConfirm = async () => {
    if (pendingDeleteItems.length === 0) {
      return;
    }

    try {
      await Promise.all(
        pendingDeleteItems.map((item) => deleteAvailableItem(householdId, store.id, item.item_id))
      );
      const count = pendingDeleteItems.length;
      toast.success(
        count === 1 ? "Deleted store item" : "Deleted store items",
        `Deleted ${count} ${count === 1 ? "item" : "items"} from ${store.display_name || store.name}`
      );
      setPendingDeleteItems([]);
      setDeleteMode(false);
      setSelectedDeleteIds(new Set());
      await loadItems(query);
    } catch (error) {
      const message = getApiErrorMessage(error, "Failed to delete store item");
      toast.error("Delete store items failed", `Delete store items failed: ${message}`);
    }
  };

  return (
    <>
      <button
        type="button"
        className="btn-secondary btn-small store-available-items-trigger"
        onClick={() => setIsOpen(true)}
      >
        Manage Items
      </button>

      {isOpen ? (
        <div className="store-items-modal-overlay" onClick={closeManager}>
          <div className="store-items-modal" onClick={(event) => event.stopPropagation()}>
            <div className="store-items-modal-header">
              <div>
                <h3>{store.display_name || store.name} Items</h3>
                <p>Manage location-specific items used for suggestions and defaults.</p>
              </div>
              <button
                type="button"
                className="store-items-modal-close"
                onClick={closeManager}
                aria-label="Close manage items modal"
              >
                x
              </button>
            </div>

            {!catalogReady ? (
              <p className="store-available-items-notice">
                {catalogMessage || "Store item management is unavailable until the latest database migration is applied."}
              </p>
            ) : null}

            <div className="store-items-modal-toolbar">
              <input
                className="store-available-items-search"
                value={query}
                onChange={(event) => setQuery(event.target.value)}
                placeholder="Search household/store items"
                disabled={!catalogReady}
              />
              <button
                type="button"
                className="btn-primary btn-small"
                disabled={!catalogReady}
                onClick={() => {
                  setEditorItem(null);
                  setShowEditor(true);
                }}
              >
                Add Item
              </button>
            </div>

            {isAdmin && catalogReady && items.length > 0 ? (
              <div className="store-items-bulk-toolbar">
                <button
                  type="button"
                  className="btn-danger btn-small store-items-delete-toggle"
                  disabled={deleteMode ? selectedDeleteCount === 0 : loading}
                  onClick={deleteMode ? confirmSelectedDelete : startDeleteMode}
                >
                  {deleteMode ? `Confirm Delete (${selectedDeleteCount})` : "Delete Items"}
                </button>
                {deleteMode ? (
                  <button
                    type="button"
                    className="btn-secondary btn-small store-items-delete-cancel"
                    onClick={cancelDeleteMode}
                  >
                    Cancel
                  </button>
                ) : null}
              </div>
            ) : null}

            <div className="store-items-modal-body">
              {!catalogReady ? (
                <p className="empty-message">Run the latest database migrations to enable store item management.</p>
              ) : loading ? (
                <p className="empty-message">Loading store items...</p>
              ) : items.length === 0 ? (
                <p className="empty-message">No household items found for this store yet.</p>
              ) : (
                <div className="store-items-table">
                  <div className="store-items-table-body">
                    {items.map((item) => {
                      const imageSrc = itemImageSource(item);
                      const isSelectedForDelete = selectedDeleteIds.has(item.item_id);

                      return (
                        <button
                          key={item.item_id}
                          type="button"
                          className={`store-items-table-row store-items-table-row-button ${deleteMode ? "is-delete-selectable" : ""} ${isSelectedForDelete ? "is-selected" : ""}`}
                          aria-label={
                            deleteMode
                              ? `${isSelectedForDelete ? "Deselect" : "Select"} ${item.item_name} for deletion`
                              : `Edit settings for ${item.item_name}`
                          }
                          aria-pressed={deleteMode ? isSelectedForDelete : undefined}
                          onClick={() => {
                            if (deleteMode) {
                              toggleDeleteSelection(item.item_id);
                            } else {
                              openEditor(item);
                            }
                          }}
                        >
                          <div className="store-items-table-cell store-items-table-item">
                            <div className="store-available-items-summary">
                              {imageSrc ? (
                                <img src={imageSrc} alt="" className="store-available-items-thumb" />
                              ) : (
                                <span
                                  className="store-available-items-thumb store-available-items-thumb-placeholder"
                                  aria-hidden="true"
                                >
                                  {"\uD83D\uDCE6"}
                                </span>
                              )}
                              <div className="store-available-items-copy">
                                <strong>{item.item_name}</strong>
                              </div>
                            </div>
                          </div>

                          {deleteMode ? (
                            <span className="store-items-delete-indicator" aria-hidden="true">
                              {isSelectedForDelete ? "✓" : ""}
                            </span>
                          ) : null}
                        </button>
                      );
                    })}
                  </div>
                </div>
              )}
            </div>
          </div>
        </div>
      ) : null}

      <AvailableItemEditorModal
        isOpen={showEditor}
        item={editorItem}
        zones={zones}
        onCancel={() => {
          setShowEditor(false);
          setEditorItem(null);
        }}
        onSave={handleUpdate}
      />

      <ConfirmSlideModal
        isOpen={pendingDeleteItems.length > 0}
        title={
          pendingDeleteItems.length === 1
            ? `Delete ${pendingDeleteItems[0].item_name}?`
            : `Delete ${pendingDeleteItems.length} items?`
        }
        description={
          pendingDeleteItems.length > 0
            ? `Slide to confirm. This permanently deletes ${pendingDeleteItems.length === 1 ? pendingDeleteItems[0].item_name : `${pendingDeleteItems.length} items`} from ${store.display_name || store.name} for this household, including current list entries and history.`
            : ""
        }
        confirmLabel={pendingDeleteItems.length === 1 ? "Delete Item" : "Delete Items"}
        onClose={() => setPendingDeleteItems([])}
        onConfirm={handleDeleteConfirm}
      />
    </>
  );
}
