import { type ReactNode } from "react";
import { useTranslation } from "react-i18next";
import { Youtube } from "lucide-react";
import type { Me } from "../lib/api";
import { moduleLabelKey, moduleOrder, stepModule } from "../lib/modules";
import ModuleName from "./ModuleName";
import SearchBar from "./SearchBar";
import SyncStatus from "./SyncStatus";
import { useNavigation, useNavigationActions } from "./NavigationProvider";
import { useFeedFilters, useFeedFiltersActions } from "./FeedFiltersProvider";
import { usePlaylists, usePlaylistsActions } from "./PlaylistsProvider";
import { usePlex, usePlexActions } from "./PlexProvider";
import { useChannels, useChannelsActions } from "./ChannelsProvider";

// The floating top header: a row of glass pills over the content — a ModuleName pill (label +
// accent dot + back/forward arrows), the module's SearchBar where it has one, and the per-user
// sync chip at the right end.
export default function Header({
  me,
  onYtSearch,
}: {
  me: Me;
  // Trigger a live YouTube search for the current term (feed only; hidden for the demo account,
  // which can't spend the shared quota).
  onYtSearch: (q: string) => void;
}) {
  const { t } = useTranslation();
  const { page } = useNavigation();
  const { setPage } = useNavigationActions();
  const filters = useFeedFilters();
  const { setFilters } = useFeedFiltersActions();
  // Each module's search term lives in its own provider (shared with that module's rail/content):
  // playlists name filter, Plex search term, channels name filter. The channel sync chip's
  // "go to full history" jump is a ChannelsProvider action.
  const { search: playlistsSearch } = usePlaylists();
  const { setSearch: setPlaylistsSearch } = usePlaylistsActions();
  const { q: plexQ } = usePlex();
  const { setQ: setPlexQ } = usePlexActions();
  const { search: channelsSearch } = useChannels();
  const { setSearch: setChannelsSearch, goToFullHistory: onGoToFullHistory } = useChannelsActions();
  // The ◀/▶ arrows step cyclically through the user's available modules (derived from `me`, so
  // it stays correct as modules are added/gated). Labels of every active module feed ModuleName's
  // dynamic width so the pill is sized to the widest reachable title in the current language.
  const order = moduleOrder(me);
  const moduleLabels = order.map((p) => t(moduleLabelKey[p]));
  const multiModule = order.length > 1;
  // Drop input focus on Go/Enter for the live-filter modules (feed's Go escalates to YouTube).
  const blur = () => (document.activeElement as HTMLElement | null)?.blur?.();

  // Per-page SearchBar wiring — null for modules without a search.
  let search: ReactNode = null;
  if (page === "feed") {
    const trimmed = filters.q.trim();
    search = (
      <SearchBar
        value={filters.q}
        placeholder={t("header.searchPlaceholder")}
        onChange={(q) => {
          // When a search first appears, rank the feed by relevance — set atomically with the
          // query (race-free vs. per-keystroke updates). Only overrides the default "newest"
          // sort; a custom sort the user chose is left alone. Cleared in Feed.
          const startSearch = !filters.q.trim() && !!q.trim() && filters.sort === "newest";
          setFilters({ ...filters, q, ...(startSearch ? { sort: "relevance" } : {}) });
        }}
        onGo={() => onYtSearch(trimmed)}
        goLabel={t("header.searchYoutube")}
        goTitle={t("header.searchYoutubeTip")}
        goIcon={<Youtube className="w-4 h-4" />}
        goDisabled={!trimmed || me.is_demo}
      />
    );
  } else if (page === "plex" && me.plex_enabled) {
    search = (
      <SearchBar
        value={plexQ}
        placeholder={t("plex.searchPlaceholder")}
        onChange={setPlexQ}
        onGo={blur}
      />
    );
  } else if (page === "channels") {
    search = (
      <SearchBar
        value={channelsSearch}
        placeholder={t("channels.searchPlaceholder")}
        onChange={setChannelsSearch}
        onGo={blur}
      />
    );
  } else if (page === "playlists") {
    search = (
      <SearchBar
        value={playlistsSearch}
        placeholder={t("playlists.searchPlaceholder")}
        onChange={setPlaylistsSearch}
        onGo={blur}
      />
    );
  }

  return (
    // Absolutely positioned within the (relative) content column, so its left edge tracks the
    // actual left zone: it sits just inside the content, reclaiming the space when the nav rail is
    // slim and/or no filter sidebar is present — no hard-coded offset.
    <div className="pointer-events-none absolute top-3 left-3 right-[10%] z-chrome flex items-center gap-3">
      <ModuleName
        label={t(moduleLabelKey[page])}
        labels={moduleLabels}
        onPrev={() => setPage(stepModule(me, page, -1))}
        onNext={() => setPage(stepModule(me, page, 1))}
        canPrev={multiModule}
        canNext={multiModule}
      />
      {search}
      {/* Per-user sync status — it used to cost the nav rail a whole block. It sits with the other
          pills rather than pinned to the far right: on a wide window that just strands it. Only on
          the two modules it says anything about: the feed those subscriptions fill, and the manager
          where you curate them. It's noise on Plex (a different source entirely), playlists, etc. */}
      {(page === "feed" || page === "channels") && (
        <SyncStatus isAdmin={me.role === "admin"} onGoToFullHistory={onGoToFullHistory} />
      )}
    </div>
  );
}
