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;
  hideShorts: boolean;
  onHideShorts: (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;
  /** 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, hideShorts, onHideShorts,
  online, reachable, forcedOffline, onToggleForcedOffline,
  onRefresh, refreshing, refreshProgress, resultCount, view, onView,
  sidebarHidden, onShowSidebar, onDeleteAll, 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-40 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 downloaded videos" : "Offline: showing downloads only"}>
          Downloaded only
        </Toggle>

        {downloadedOnly && onDeleteAll && (
          <button
            onClick={onDeleteAll}
            title="Delete every download"
            className={`inline-flex ${CONTROL_H} cursor-pointer items-center whitespace-nowrap
                        rounded-lg border border-slate-300 px-2.5 text-[12px] font-medium
                        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`}
          >
            Delete all
          </button>
        )}

        <Toggle active={hideShorts} onClick={() => onHideShorts(!hideShorts)}
          title="Hide Shorts from the feed">
          Hide Shorts
        </Toggle>

        <Segmented
          value={view}
          onChange={onView}
          options={[
            { value: "list", label: "List" },
            { value: "grid", label: "Tiles" },
          ]}
        />

        <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={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>
  );
}

