// Bookshelf functionality - procedural/imperative style

import { Alpine } from "./alpine";
import { showToast } from "./toast";

function clearFilters(): void {
  const filterForm = document.getElementById("filter-form") as HTMLFormElement;
  if (!filterForm) return;

  // Reset all form fields
  const inputs = filterForm.querySelectorAll("input, select");
  inputs.forEach((input) => {
    if (input instanceof HTMLInputElement && input.type === "checkbox") {
      input.checked = false;
    } else {
      (input as HTMLInputElement).value = "";
    }
  });

  // Trigger HTMX reload with cleared filters
  window.htmx.trigger(filterForm, "change");
}

// Alpine.js component
Alpine.data("bookshelf", () => ({
  // Component state
  showSaveModal: false,
  filterName: "",
  showFiltersDropdown: false,

  // Standalone function references (don't access component state)
  clearFilters,
  initBookshelf,

  // Inline method - opens the modal
  showSaveFilterModal() {
    this.showSaveModal = true;
  },
  // Toggle the filters dropdown
  toggleFiltersDropdown() {
    this.showFiltersDropdown = !this.showFiltersDropdown;
  },
  // Load a saved filter into the form
  async loadFilter(event: Event) {
    const button = event.target as HTMLElement;
    const filterRow = button.closest("[data-filter-id]");
    if (!filterRow) return;

    const filterId = filterRow?.getAttribute("data-filter-id");
    if (!filterId) return;

    const filterName = button.textContent?.trim() || "";

    showToast(`Loading filter: ${filterName}...`, "info");

    const token = localStorage.getItem("token");
    if (!token) {
      showToast("Not authenticated", "error");
      return;
    }

    try {
      // Fetch filter details from API
      const response = await fetch(`/api/saved-filters/${filterId}`, {
        headers: { Authorization: `Bearer ${token}` },
      });

      if (!response.ok) {
        if (response.status === 404) {
          showToast("Filter not found", "error");
        } else {
          showToast("Failed to load filter", "error");
        }
        return;
      }

      const filter = await response.json();

      // Parse filters JSON (string → object)
      const filterData: Record<string, string> =
        typeof filter.filters === "string"
          ? JSON.parse(filter.filters)
          : filter.filters;

      // Get the hidden filter form
      const filterForm = document.getElementById(
        "filter-form",
      ) as HTMLFormElement;
      if (!filterForm) {
        showToast("Filter form not found", "error");
        return;
      }

      // Clear existing filter values
      filterForm.innerHTML = `
          <input type="hidden" name="limit" value="50"/>
          <input type="hidden" name="offset" value="0"/>
      `;

      // Populate form fields from filter data
      Object.entries(filterData).forEach(([key, value]) => {
        if (value) {
          // Only set non-empty values
          const input = document.createElement("input");
          input.type = "hidden";
          input.name = key;
          input.value = value;
          filterForm.appendChild(input);

          // Also update visible form fields if they exist
          const visibleField = document.querySelector(
            `[name="${key}"]`,
          ) as HTMLInputElement;
          if (visibleField) {
            visibleField.value = value;
          }
        }
      });

      // Trigger HTMX to apply the filter
      // Use the first input to trigger the change event
      const firstInput = filterForm.querySelector("input");
      if (firstInput) {
        window.htmx.trigger(firstInput, "change");
      }

      showToast(`Filter applied: ${filterName}`, "success");

      // Close the dropdown after applying
      this.showFiltersDropdown = false;
    } catch (error) {
      console.error("Failed to load filter:", error);
      showToast("Error loading filter", "error");
    }
  },
  // Delete a saved filter
  async deleteFilter(event: Event) {
    const button = event.target as HTMLElement;
    const filterRow = button.closest("[data-filter-id]");
    if (!filterRow) return;

    const filterId = filterRow?.getAttribute("data-filter-id");
    if (!filterId) return;

    if (!confirm("Are you sure you want to delete this filter?")) return;

    const token = localStorage.getItem("token");
    if (!token) {
      showToast("Not authenticated", "error");
      return;
    }

    try {
      const response = await fetch(`/api/saved-filters/${filterId}`, {
        method: "DELETE",
        headers: { Authorization: `Bearer ${token}` },
      });

      if (response.ok) {
        showToast("Filter deleted", "success");
        // Remove the element from DOM
        filterRow?.remove();
      } else {
        showToast("Failed to delete filter", "error");
      }
    } catch (error) {
      console.error("Failed to delete filter:", error);
      showToast("Error deleting filter", "error");
    }
  },
  // Inline method - saves the filter and closes modal
  async saveFilter(event: Event) {
    event.preventDefault();

    const token = localStorage.getItem("token");
    if (!token) {
      showToast("Not authenticated", "error");
      return;
    }
    // Get filter name from component state
    const filterName = this.filterName;
    if (!filterName) {
      showToast("Please enter a filter name", "error");
      return;
    }

    // Collect filter form data
    const filterForm = document.getElementById(
      "filter-form",
    ) as HTMLFormElement;
    if (!filterForm) {
      showToast("Filter form not found", "error");
      return;
    }

    const formData = new FormData(filterForm);
    const filterData: Record<string, string> = {};
    formData.forEach((value, key) => {
      filterData[key] = value.toString();
    });

    try {
      const response = await fetch("/api/saved-filters", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${token}`,
        },
        body: JSON.stringify({
          name: filterName,
          resource_type: "media-items",
          filters: filterData,
        }),
      });

      if (response.ok) {
        showToast("Filter saved successfully", "success");
        // Clear the filter name input
        this.filterName = "";
        // Close the modal
        this.showSaveModal = false;
      } else {
        showToast("Failed to save filter", "error");
      }
    } catch (error) {
      console.error("Failed to save filter:", error);
      showToast("Error saving filter", "error");
    }
  },

  // Autocomplete helper function
  async fetchFieldValues(
    field: string,
    search: string,
    datalistId: string,
  ): Promise<void> {
    const token = localStorage.getItem("token");
    if (!token) {
      console.error("Not authenticated");
      return;
    }

    if (search.length < 2) return;

    const currentLibraryId = (
      document.getElementById("library-select") as HTMLSelectElement
    )?.value;
    if (!currentLibraryId) {
      console.error("No library selected");
      return;
    }

    try {
      const response = await fetch(
        `/api/media-items/search?${field}=${encodeURIComponent(
          search,
        )}&library_id=${currentLibraryId}&limit=50`,
        {
          headers: { Authorization: `Bearer ${token}` },
        },
      );

      if (!response.ok) {
        console.error("Failed to fetch field values");
        return;
      }

      const data = await response.json();

      // Update datalist via DOM manipulation
      const datalist = document.getElementById(datalistId);
      if (!datalist) {
        console.error(`Datalist ${datalistId} not found`);
        return;
      }

      // Clear existing options
      datalist.innerHTML = "";

      // Add new options
      data.results.forEach((item: { value: string; count: number }) => {
        const option = document.createElement("option");
        option.value = item.value;
        option.textContent = `${item.value} (${item.count})`;
        datalist.appendChild(option);
      });
    } catch (error) {
      console.error("Error fetching field values:", error);
    }
  },

  // Fetch author values for autocomplete
  async fetchAuthorValues(input: HTMLInputElement): Promise<void> {
    await this.fetchFieldValues("author", input.value, "author-datalist");
  },

  // Fetch genre values for autocomplete
  async fetchGenreValues(input: HTMLInputElement): Promise<void> {
    await this.fetchFieldValues("genre", input.value, "genre-datalist");
  },

  // Fetch series values for autocomplete
  async fetchSeriesValues(input: HTMLInputElement): Promise<void> {
    await this.fetchFieldValues("series", input.value, "series-datalist");
  },

  // Fetch language values for autocomplete
  async fetchLanguageValues(input: HTMLInputElement): Promise<void> {
    await this.fetchFieldValues("language", input.value, "language-datalist");
  },
}));

// Standalone function - initialize the bookshelf (NOT async, like dashboard.ts)
function initBookshelf(): void {
  // Check if books were already rendered server-side
  const booksGrid = document.getElementById("books-grid");
  const hasServerBooks =
    booksGrid && booksGrid.querySelector("[data-book-id]") !== null;

  if (!hasServerBooks) {
    // Only trigger HTMX if no SSR books rendered
    const librarySelect = document.getElementById(
      "library-select",
    ) as HTMLSelectElement;
    if (librarySelect && librarySelect.value) {
      const filterForm = document.getElementById(
        "filter-form",
      ) as HTMLFormElement;
      if (filterForm) {
        // Trigger initial HTMX load
        window.htmx.trigger(librarySelect, "change");
      }
    }
  }
}

export { clearFilters };
