import { CircularProgress } from "@mui/joy";
import React, {
  forwardRef,
  useImperativeHandle,
  useEffect,
  useRef,
  useState,
  useCallback,
} from "react";
import { toast } from 'react-toastify';
import Alert from '@mui/joy/Alert';
import Box from '@mui/joy/Box';
import Button from "@mui/joy/Button";
import Checkbox from "@mui/joy/Checkbox";
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
import { AutoComplete } from 'primereact/autocomplete';
import { API_URL } from '../config';

export default function LyricSearch() {
  const [showLyrics, setShowLyrics] = useState(false);
  return (
    <div className="lyric-search">
      <h2 className="title">
        <span>Lyric Search</span>
      </h2>
      <div className="card-text my-4">
        <label htmlFor="lyric-search-input">Search:</label>
        <LyricSearchInputField
          id="lyric-search-input"
          placeholder="Artist - Song"
          setShowLyrics={setShowLyrics} />
        <div id="spinner" className="hidden">
          <CircularProgress
            variant="plain"
            color="primary"
            size="md" /></div>
      </div>
    </div>
  );
}



export function LyricSearchInputField({ id, placeholder, setShowLyrics }) {
  const [value, setValue] = useState("");
  const [suggestions, setSuggestions] = useState([]);
  const [alertVisible, setAlertVisible] = useState(false);
  const [isLoading, setIsLoading] = useState(false);
  const [excludedSources, setExcludedSources] = useState([]);
  const [lyricsResult, setLyricsResult] = useState(null);
  const searchToastRef = useRef(null);
  const autoCompleteRef = useRef(null);
  const [theme, setTheme] = useState(document.documentElement.getAttribute("data-theme") || "light");

  useEffect(() => {
    const handler = (e) => {
      const newTheme = e.detail;
      setTheme(newTheme);
    };
    document.addEventListener('set-theme', handler);
    return () => {
      document.removeEventListener('set-theme', handler);
    };
  }, []);



  // Typeahead: fetch suggestions
  const fetchSuggestions = useCallback(async (event) => {
    const query = event.query;
    const res = await fetch(`${API_URL}/typeahead/lyrics`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ query }),
    });
    const json = await res.json();
    setSuggestions(json);
  }, []);

  // Toggle exclusion state for checkboxes
  const toggleExclusion = (source) => {
    const lower = source.toLowerCase();
    setExcludedSources((prev) =>
      prev.includes(lower)
        ? prev.filter((s) => s !== lower)
        : [...prev, lower]
    );
  };


  // Show scrollable dropdown panel with mouse wheel handling
  const handlePanelShow = () => {
    setTimeout(() => {
      const panel = document.querySelector(".p-autocomplete-panel");
      const items = panel?.querySelector(".p-autocomplete-items");

      if (items) {
        items.style.maxHeight = "200px";
        items.style.overflowY = "auto";
        items.style.overscrollBehavior = "contain";

        const wheelHandler = (e) => {
          const delta = e.deltaY;
          const atTop = items.scrollTop === 0;
          const atBottom =
            items.scrollTop + items.clientHeight >= items.scrollHeight;

          if ((delta < 0 && atTop) || (delta > 0 && atBottom)) {
            e.preventDefault();
          } else {
            e.stopPropagation();
          }
        };

        items.removeEventListener("wheel", wheelHandler);
        items.addEventListener("wheel", wheelHandler, { passive: false });
      }
    }, 0);
  };

  const handleSearch = async () => {
    if (autoCompleteRef.current) {
      autoCompleteRef.current.hide();
    }

    if (!value.includes(" - ")) {
      setAlertVisible(true);
      return;
    }

    const [artist, song] = value.split(" - ", 2).map((v) => v.trim());
    if (!artist || !song) {
      setAlertVisible(true);
      return;
    }

    setAlertVisible(false);
    setIsLoading(true);
    setLyricsResult(null);
    setShowLyrics(false);

    if (!toast.isActive('lyrics-searching-toast')) {
      searchToastRef.current = toast.info("Searching...", {
        toastId: "lyrics-searching-toast"
      });
    }

    const startTime = Date.now();

    try {
      const res = await fetch(`${API_URL}/lyric/search`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          a: artist,
          s: song,
          excluded_sources: excludedSources,
          src: "Web",
          extra: true,
        }),
      });

      const data = await res.json();
      if (!res.ok || !data.lyrics) {
        throw new Error(data.errorText || "Unknown error.");
      }

      const duration = ((Date.now() - startTime) / 1000).toFixed(1);
      setLyricsResult({ artist: data.artist, song: data.song, lyrics: data.lyrics });
      setShowLyrics(true);

      toast.update(searchToastRef.current, {
        type: "success",
        render: `Found! (Took ${duration}s)`,
        className: "Toastify__toast--success",
        autoClose: 2500,
      });
    } catch (error) {
      toast.update(searchToastRef.current, {
        type: "error",
        render: `😕 ${error.message}`,
        autoClose: 5000,
      });
    } finally {
      setIsLoading(false);
    }
  };

  const handleKeyDown = (e) => {
    if (e.key === "Enter") {
      e.preventDefault();
      handleSearch();
    }
  };

  return (
    <div>
      {alertVisible && (
        <Alert
          color="danger"
          variant="solid"
          onClose={() => setAlertVisible(false)}
          sx={{ mb: 2 }}
        >
          You must specify both an artist and song to search.
          <br />
          Format: Artist - Song
        </Alert>
      )}

      <AutoComplete
        id={id}
        ref={autoCompleteRef}
        value={value}
        suggestions={suggestions}
        completeMethod={fetchSuggestions}
        onChange={(e) => setValue(e.target.value)}
        onKeyDown={handleKeyDown}
        onShow={handlePanelShow}
        placeholder={placeholder}
        autoFocus
        size={40}
        aria-controls="lyric-search-input"
      />
      <Button onClick={handleSearch} className="btn">
        Search
      </Button>
      <br />
      Exclude:<br />
      <div id="exclude-checkboxes">
        <UICheckbox id="excl-Genius" label="Genius" onToggle={toggleExclusion} />
        <UICheckbox id="excl-LRCLib" label="LRCLib" onToggle={toggleExclusion} />
        <UICheckbox id="excl-Cache" label="Cache" onToggle={toggleExclusion} />
      </div>

      {isLoading && (
        <div className="mt-3">
          <CircularProgress variant="plain" color="primary" size="md" />
        </div>
      )}

      {lyricsResult && (
        <div className={`lyrics-card lyrics-card-${theme} mt-4 p-4 rounded-md shadow-md`}>
          <div className="lyrics-content">
            <div style={{ textAlign: "center", fontWeight: "bold", marginBottom: "1rem" }}>
              {lyricsResult.artist} - {lyricsResult.song}
            </div>
            <div dangerouslySetInnerHTML={{ __html: lyricsResult.lyrics }} />
          </div>
        </div>
      )}
    </div>
  );
}


export const UICheckbox = forwardRef(function UICheckbox(props = {}, ref) {
  const [checked, setChecked] = useState(false);

  useImperativeHandle(ref, () => ({
    setChecked: (val) => setChecked(val),
    checked,
  }));

  const verifyExclusions = () => {
    const checkboxes = document.querySelectorAll("#exclude-checkboxes input[type=checkbox]");
    const checkedCount = [...checkboxes].filter(cb => cb.checked).length;

    if (checkedCount === 3) {
      checkboxes.forEach(cb => cb.click());
      if (!toast.isActive("lyrics-exclusion-reset-toast")) {
        toast.error("All sources were excluded; exclusions have been reset.",
          { toastId: "lyrics-exclusion-reset-toast" }
        );
      }
    }
  };

  const handleChange = (e) => {
    const newChecked = e.target.checked;
    setChecked(newChecked);
    if (props.onToggle) {
      const source = props.label; // Use label as source identifier
      props.onToggle(source);
    }
    verifyExclusions();
  };

  return (
    <div>
      <Checkbox
        id={props.id}
        key={props.label}
        checked={checked}
        label={props.label}
        style={{ color: "inherit" }}
        onChange={handleChange}
      />
    </div>
  );
});


export function LyricResultBox(opts = {}) {
  return (
    <div>
      <Box className={`lyrics-card lyrics-card-${theme}`} sx={{ p: 2 }}>
        <div className='lyrics-content'></div>
        {/* <ContentCopyIcon className='lyrics-card-copyButton' size='lg' /> */}
      </Box>
    </div>
  )
}