import { CONTROL_H, ICON_BTN, INPUT, Segmented } from "./ui";

export type ViewMode = "list" | "grid";

interface Props {
  search: string;
  onSearch: (v: string) => void;
  downloadedOnly: boolean;
  onDownloadedOnly: (v: boolean) => void;
  online: boolean;
  reachable: boolean;
  forcedOffline: boolean;
  onToggleForcedOffline: () => void;
  onRefresh: () => void;
  refreshing: boolean;
  refreshProgress: { done: number; total: number } | null;
  resultCount: number;
  view: ViewMode;
  onView: (v: ViewMode) => void;
  sidebarHidden: boolean;
  onShowSidebar: () => void;
  /** Present only when there is something to delete. */
  onDeleteAll?: () => void;
  /** Present only on a channel page with videos still to fetch. */
  onDownloadAll?: () => void;
  /** Present only while something is downloading or waiting to. */
  onStopAll?: () => void;
  stopAllCount?: number;
  autoMode: boolean;
  onAutoMode: () => void;
  /** How many videos auto mode keeps, for the tooltip. */
  autoModeCount: number;
  /** How many this press would queue, and how many are listed in all. */
  downloadAllCount?: number;
  downloadAllTotal?: number;
  /** Matches the sidebar's inset so the two headers share a baseline. */
  titleBarInset: boolean;
}

/** Neutral outline until active; active is the one filled state. */
function Toggle({
  active, onClick, children, title, disabled,
}: {
  active: boolean;
  onClick: () => void;
  children: React.ReactNode;
  title?: string;
  disabled?: boolean;
}) {
  return (
    <button
      onClick={onClick}
      title={title}
      disabled={disabled}
      className={
        `inline-flex ${CONTROL_H} cursor-pointer items-center whitespace-nowrap rounded-lg border px-2.5 text-[12px] ` +
        "font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-40 " +
        (active
          ? "border-sky-500 bg-sky-500 text-white hover:bg-sky-400"
          : "border-slate-300 text-slate-500 hover:border-sky-500 hover:text-sky-600 " +
            "dark:border-slate-700 dark:text-slate-400 dark:hover:border-sky-500 dark:hover:text-sky-400")
      }
    >
      {children}
    </button>
  );
}

export default function TopBar({
  search, onSearch, downloadedOnly, onDownloadedOnly,
  online, reachable, forcedOffline, onToggleForcedOffline,
  onRefresh, refreshing, refreshProgress, resultCount, view, onView,
  sidebarHidden, onShowSidebar, onDeleteAll, onDownloadAll, downloadAllCount = 0,
  downloadAllTotal = 0, onStopAll, stopAllCount = 0,
  autoMode, onAutoMode, autoModeCount, titleBarInset,
}: Props) {
  const pct = refreshProgress && refreshProgress.total > 0
    ? (refreshProgress.done / refreshProgress.total) * 100
    : null;

  return (
    <div
      className="sticky top-0 z-20 border-b border-slate-200 bg-white/95 backdrop-blur
                 dark:border-slate-800 dark:bg-slate-900/95"
    >
      {titleBarInset && <div data-tauri-drag-region className="h-9" />}

      <div className="flex flex-nowrap items-center gap-2 px-4 py-3">
        {sidebarHidden && (
          <button
            onClick={onShowSidebar}
            title="Show subscriptions"
            aria-label="Show subscriptions"
            className={`${ICON_BTN} border border-slate-300 text-slate-500 hover:border-sky-500
                        hover:text-sky-600 dark:border-slate-700 dark:text-slate-400
                        dark:hover:border-sky-500 dark:hover:text-sky-400`}
          >
            <svg viewBox="0 0 24 24" className="size-4" fill="none" stroke="currentColor" strokeWidth="1.8">
              <path strokeLinecap="round" strokeLinejoin="round" d="M4 6h16M4 12h16M4 18h16" />
            </svg>
          </button>
        )}
        <input
          value={search}
          onChange={(e) => onSearch(e.target.value)}
          placeholder="Search videos and channels"
          className={`${INPUT} min-w-[17rem] max-w-sm flex-1`}
        />

        <span className="shrink-0 font-mono text-[11px] tabular-nums text-slate-400 dark:text-slate-500">
          {resultCount}
        </span>

        <div className="min-w-2 flex-1" />

        <Toggle active={downloadedOnly} onClick={() => onDownloadedOnly(!downloadedOnly)}
          disabled={!online}
          title={online ? "Show only what is on this Mac" : "Offline: showing local videos only"}>
          Local
        </Toggle>

        {onStopAll && (
          <button
            onClick={onStopAll}
            title={`Stop the ${stopAllCount} download${
              stopAllCount === 1 ? "" : "s"
            } in progress — nothing already saved is deleted`}
            aria-label="Stop all downloads"
            className={`${ICON_BTN} border border-slate-300 text-slate-500 hover:border-red-500
                        hover:text-red-600 dark:border-slate-700 dark:text-slate-400
                        dark:hover:border-red-500 dark:hover:text-red-400`}
          >
            <svg viewBox="0 0 24 24" className="size-4" fill="none" stroke="currentColor"
              strokeWidth="1.8">
              <circle cx="12" cy="12" r="8.5" />
              <rect x="9" y="9" width="6" height="6" rx="1" fill="currentColor" stroke="none" />
            </svg>
          </button>
        )}

        {onDownloadAll && (
          <button
            onClick={onDownloadAll}
            title={
              downloadAllCount < downloadAllTotal
                ? `Download the newest ${downloadAllCount} of the ${downloadAllTotal} listed here, ` +
                  "one after another — raise the limit in Settings"
                : `Download all ${downloadAllCount} video${
                    downloadAllCount === 1 ? "" : "s"
                  } listed here, one after another`
            }
            aria-label="Download all listed videos"
            className={`${ICON_BTN} border border-slate-300 text-slate-500 hover:border-sky-500
                        hover:text-sky-600 dark:border-slate-700 dark:text-slate-400
                        dark:hover:border-sky-500 dark:hover:text-sky-400`}
          >
            <svg viewBox="0 0 24 24" className="size-4" fill="none" stroke="currentColor"
              strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
              <path d="M12 3v10.5" />
              <path d="M7.5 9.5L12 14l4.5-4.5" />
              <path d="M4 17.5v1A2.5 2.5 0 006.5 21h11a2.5 2.5 0 002.5-2.5v-1" />
            </svg>
          </button>
        )}

        {downloadedOnly && onDeleteAll && (
          <button
            onClick={onDeleteAll}
            title="Delete every download"
            aria-label="Delete every download"
            className={`${ICON_BTN} border border-slate-300 text-slate-500 hover:border-red-500
                        hover:text-red-600 dark:border-slate-700 dark:text-slate-400
                        dark:hover:border-red-500 dark:hover:text-red-400`}
          >
            <svg viewBox="0 0 24 24" className="size-4" fill="none" stroke="currentColor"
              strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
              <path d="M4 7h16M10 11v6M14 11v6" />
              <path d="M6 7l1 12.5A1.5 1.5 0 008.5 21h7a1.5 1.5 0 001.5-1.5L18 7" />
              <path d="M9 7V5a1 1 0 011-1h4a1 1 0 011 1v2" />
            </svg>
          </button>
        )}

        <Segmented
          value={view}
          onChange={onView}
          options={[
            {
              value: "list",
              title: "List",
              label: (
                <svg viewBox="0 0 24 24" className="size-4" fill="none" stroke="currentColor" strokeWidth="2">
                  <path strokeLinecap="round" d="M4 6h16M4 12h16M4 18h16" />
                </svg>
              ),
            },
            {
              value: "grid",
              title: "Tiles",
              label: (
                <svg viewBox="0 0 24 24" className="size-4" fill="none" stroke="currentColor" strokeWidth="2">
                  <rect x="4" y="4" width="7" height="7" rx="1.5" />
                  <rect x="13" y="4" width="7" height="7" rx="1.5" />
                  <rect x="4" y="13" width="7" height="7" rx="1.5" />
                  <rect x="13" y="13" width="7" height="7" rx="1.5" />
                </svg>
              ),
            },
          ]}
        />

        <button
          onClick={onToggleForcedOffline}
          title={
            !reachable
              ? "No connection detected"
              : forcedOffline
                ? "Offline mode is forced on — click to go back online"
                : "Simulate being offline"
          }
          className={`inline-flex ${CONTROL_H} cursor-pointer items-center gap-1.5 whitespace-nowrap
                      rounded-lg border border-slate-300 px-2.5 text-[12px] font-medium text-slate-500
                      hover:border-sky-500 hover:text-sky-600
                      dark:border-slate-700 dark:text-slate-400 dark:hover:border-sky-500
                      dark:hover:text-sky-400`}
        >
          <span
            className={`size-1.5 rounded-full ${online ? "bg-sky-500" : "bg-amber-500"}`}
          />
          {online ? "Online" : forcedOffline ? "Offline (forced)" : "Offline"}
        </button>

        <button
          onClick={onAutoMode}
          title={
            autoMode
              ? `Auto mode is on — keeping the newest ${autoModeCount} videos on this Mac. Click to stop.`
              : "Auto mode: keep the newest videos downloaded automatically"
          }
          aria-label="Auto mode"
          aria-pressed={autoMode}
          className={
            `${ICON_BTN} border ` +
            (autoMode
              ? "border-sky-500 bg-sky-500 text-white hover:bg-sky-400"
              : "border-slate-300 text-slate-500 hover:border-sky-500 hover:text-sky-600 " +
                "dark:border-slate-700 dark:text-slate-400 dark:hover:border-sky-500 " +
                "dark:hover:text-sky-400")
          }
        >
          {/* A download inside a cycle: it fetches, and it keeps doing it. */}
          <svg viewBox="0 0 24 24" className="size-4" fill="none" stroke="currentColor"
            strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
            <path d="M20.5 12a8.5 8.5 0 01-14.6 5.9M3.5 12a8.5 8.5 0 0114.6-5.9" />
            <path d="M18.1 2.5v3.6h-3.6M5.9 21.5v-3.6h3.6" />
            <path d="M12 8.5v5m0 0l-2-2m2 2l2-2" />
          </svg>
        </button>

        <button onClick={onRefresh} disabled={refreshing || !online}
          title={
            online
              ? refreshProgress
                ? `Refreshing ${refreshProgress.done}/${refreshProgress.total}`
                : "Fetch the latest videos from every channel"
              : "Refreshing needs a connection"
          }
          aria-label="Refresh"
          className={`${ICON_BTN} bg-sky-500 text-white hover:bg-sky-400`}>
          <svg viewBox="0 0 24 24" className={`size-4 ${refreshing ? "animate-spin" : ""}`}
            fill="none" stroke="currentColor" strokeWidth="2">
            <path strokeLinecap="round" strokeLinejoin="round"
              d="M20 11a8 8 0 10-2.3 5.7M20 5v6h-6" />
          </svg>
        </button>
      </div>

      {refreshing && (
        <div className="h-0.5 overflow-hidden bg-slate-200 dark:bg-slate-700">
          <div
            className={`h-full bg-sky-500 transition-[width] duration-100 ${
              pct == null ? "w-1/3 animate-pulse" : ""
            }`}
            style={pct == null ? undefined : { width: `${pct}%` }}
          />
        </div>
      )}
    </div>
  );
}

