import Adw from "gi://Adw";
import GObject from "gi://GObject";
import { getTemplate } from "../utils/getTemplate.js";
import { logger } from "../utils/logger.js";


const ItemsPage = GObject.registerClass(
  {
    GTypeName: "VeilItemsPage",
    Template: getTemplate("ItemsPage"),
    InternalChildren: ["itemsGroup", "resetButton"]
  },
  class ItemsPage2 extends Adw.PreferencesPage {
    settings;
    itemRows = /* @__PURE__ */ new Map();
    handlerIds = /* @__PURE__ */ new Map();
    updating = false;

    bindSettings(settings) {
      this.settings = settings;
      const children = this;
      logger.debug("Settings bound to ItemsPage");

      children._resetButton.connect("clicked", () => {
        this.handleReset();
      });

      this.updateItemsList();

      this.settings.connect("changed::all-items", () => {
        this.updateItemsList();
      });

      this.settings.connect("changed::visible-items", () => {
        this.updateItemStates();
      });
    }

    updateItemsList() {
      const children = this;
      const allItems = this.settings.get_strv("all-items");
      const visibleItems = this.settings.get_strv("visible-items");

      logger.debug("Updating items list", {
        allItemsCount: allItems.length,
        visibleItemsCount: visibleItems.length
      });

      for (const [itemName, row] of this.itemRows.entries()) {
        if (!allItems.includes(itemName)) {
          const handlerId = this.handlerIds.get(itemName);

          if (handlerId !== void 0) {
            row.disconnect(handlerId);
            this.handlerIds.delete(itemName);
          }

          children._itemsGroup.remove(row);

          this.itemRows.delete(itemName);
        }
      }

      allItems.forEach((itemName) => {
        let row = this.itemRows.get(itemName);

        if (!row) {
          row = this.createItemRow(itemName);
          children._itemsGroup.add(row);
          this.itemRows.set(itemName, row);
        }

        this.updateRowState(row, visibleItems.includes(itemName));
      });
    }

    createItemRow(itemName) {
      const row = new Adw.SwitchRow({
        title: itemName,
        subtitle: "Toggle to show/hide this item"
      });

      const handlerId = row.connect("notify::active", () => {
        if (!this.updating) {
          this.toggleItem(itemName, row.active);
        }
      });

      this.handlerIds.set(itemName, handlerId);
      return row;
    }

    updateRowState(row, isVisible) {
      this.updating = true;
      row.active = isVisible;
      this.updating = false;
    }

    updateItemStates() {
      const visibleItems = this.settings.get_strv("visible-items");

      for (const [itemName, row] of this.itemRows.entries()) {
        const isVisible = visibleItems.includes(itemName);

        if (row.active !== isVisible) {
          this.updateRowState(row, isVisible);
        }
      }
    }

    toggleItem(itemName, isActive) {
      const visibleItems = this.settings.get_strv("visible-items");
      const index = visibleItems.indexOf(itemName);

      if (isActive && index < 0) {
        visibleItems.push(itemName);
        this.settings.set_strv("visible-items", visibleItems);
        logger.debug("Item added to visible items", { itemName });
      } else if (!isActive && index >= 0) {
        visibleItems.splice(index, 1);
        this.settings.set_strv("visible-items", visibleItems);
        logger.debug("Item removed from visible items", { itemName });
      }
    }

    handleReset() {
      this.settings.set_strv("visible-items", []);
      logger.info("Reset all items to hidden");
    }
  }
);

export {
  ItemsPage
};
