"use client";

import cx from "classnames";
import { useEffect, useState } from "react";

import {
  Bar,
  BarItem,
  Button,
  Container,
  Field,
  Fieldset,
  Grid,
  GridCol,
  Icon,
  Label,
} from "..";

import { iconsWithTags, tags } from "./iconSearchTags";
import { handleSvgClick, loadIconNames } from "./iconUtils";

// Icon names will be loaded dynamically on the client
let iconNamesCache = [];

const getIconNames = () => {
  if (typeof window !== "undefined" && iconNamesCache.length === 0) {
    const requireContext = require.context(
      "../../assets/icons",
      false,
      /\.svg$/,
    );
    iconNamesCache = loadIconNames(
      requireContext,
      (name) => !name.includes("-file") && !name.startsWith("pictogram-"),
    );
  }
  return iconNamesCache;
};

export { getIconNames };

export const IconList = ({ icons, isWide = true }) => (
  <ul className={cx("sg-icon-list", { "sg-icon-list--wide": isWide })}>
    {icons.map(
      ({ name, description, tags = [], size = "medium", ...other }, i) => {
        return (
          <li
            className="sg-icon-list__item"
            key={i.toString()}
            id={name + "_" + tags.join("-")}
          >
            <Icon
              name={name}
              size={size}
              onClick={(e) => handleSvgClick(e.currentTarget, "icon")}
              {...other}
            />
            <br />
            <abbr title={description || name}>{description || name}</abbr>
          </li>
        );
      },
    )}
  </ul>
);

export const IconSearch = () => {
  const [searchOption, setSearchOption] = useState("includes");
  const [searchValue, setSearchValue] = useState("");
  const [selectedTags, setSelectedTags] = useState([]);
  const [allIcons, setAllIcons] = useState([]);
  const [filteredIcons, setFilteredIcons] = useState([]);

  // Load icons on mount (client-side only)
  useEffect(() => {
    if (typeof window !== "undefined") {
      const iconNames = getIconNames();
      const iconsData = iconNames.map((name) => ({
        size: "large",
        name,
        tags: iconsWithTags[name] || [],
        id: name + "_" + (iconsWithTags[name] || []).join("-"),
      }));
      setAllIcons(iconsData);
      setFilteredIcons(iconsData);
    }
  }, []);

  // Filter icons based on search criteria
  useEffect(() => {
    if (!allIcons.length) return;

    let filtered = allIcons.filter((icon) => {
      // Filter by search value
      const matchesSearch =
        !searchValue ||
        (searchOption === "startswith"
          ? icon.name.startsWith(searchValue)
          : icon.name.includes(searchValue));

      // Filter by selected tags
      const matchesTags =
        selectedTags.length === 0 ||
        selectedTags.every((tag) => icon.tags.includes(tag));

      return matchesSearch && matchesTags;
    });

    setFilteredIcons(filtered);
  }, [allIcons, searchValue, searchOption, selectedTags]);

  const handleInputChange = (value) => {
    setSearchValue(value);
  };

  const handleSearchOptionChange = (id) => {
    setSearchOption(id);
  };

  const handleTagChange = (e, tag) => {
    if (e.target.checked) {
      setSelectedTags((prev) => [...prev, tag]);
    } else {
      setSelectedTags((prev) => prev.filter((t) => t !== tag));
    }
  };

  const handleClear = () => {
    setSearchValue("");
    setSelectedTags([]);
  };

  return (
    <Container>
      <Bar space="small" className="align-items-end">
        <BarItem>
          <div className="form-field">
            <Label htmlFor={"search-input"}>
              <h3 className="mb-xsmall">Search input</h3>
            </Label>
            <input
              className="text-input"
              onChange={(e) => handleInputChange(e.target?.value)}
              id="search-input"
              value={searchValue}
            />
          </div>
        </BarItem>
        <BarItem isFilling>
          <Button
            type="primary"
            onClick={handleClear}
            isDisabled={!searchValue && selectedTags.length === 0}
          >
            Clear
          </Button>
        </BarItem>
      </Bar>
      <Fieldset legend="Search input options" className="mb-small">
        {[
          { label: "show icons that include string", id: "includes" },
          {
            label: "show icons that start with string",
            id: "startswith",
          },
        ].map(({ label, id }) => (
          <Field
            control={{
              name: "search",
              type: "radio",
              onClick: () => handleSearchOptionChange(id),
              isChecked: searchOption === id,
              id: id,
            }}
            key={id}
            label={label}
          />
        ))}
      </Fieldset>
      <h3>Or search icons using categories</h3>
      <Grid className="mb-large">
        {tags.map((tag) => (
          <GridCol key={tag} size={{ xs: 12, sm: 6, md: 4 }}>
            <Field
              control={{
                type: "checkbox",
                onClick: (e) => handleTagChange(e, tag),
                id: tag,
                isChecked: selectedTags.includes(tag),
              }}
              label={tag}
            />
          </GridCol>
        ))}
      </Grid>
      <div className="results">
        {allIcons.length > 0 ? (
          <IconList icons={filteredIcons} />
        ) : (
          <div>Loading icons...</div>
        )}
      </div>
    </Container>
  );
};
