import "./commandBar.css";

export type CommandBarType = "default" | "recent" | "results" | "no-result";
export type CommandBarBreakpoint = "desktop" | "mobile";

export type CommandBarProps = {
  breakpoint?: CommandBarBreakpoint;
  className?: string;
  dir?: "ltr" | "rtl";
  nodeId?: string;
  type?: CommandBarType;
};

type CommandBarCopy = {
  clear: string;
  commands: string;
  description: string;
  navigate: string;
  noResults: string;
  open: string;
  placeholder: string;
  recent: string;
  results: string;
  searchFor: string;
  searchText: string;
  tags: string[];
  title: string;
  tryDifferent: string;
};

type CommandRow = {
  readonly highlighted?: boolean;
  readonly shortcut?: boolean;
  readonly visual: "avatar" | "icon";
};

const shortcutText = "\u2318K";

const ltrCopy: CommandBarCopy = {
  clear: "Clear search",
  commands: "Commands",
  description: "Item description",
  navigate: "Navigate",
  noResults: "No results found",
  open: "Open",
  placeholder: "Search or type a command",
  recent: "Recent",
  results: "Results",
  searchFor: "Search for",
  searchText: "Search Text",
  tags: ["All", "Tasks", "People", "Files", "Docs", "Comments"],
  title: "Title",
  tryDifferent: "Try using different keywords",
};

const rtlCopy: CommandBarCopy = {
  clear: "\u0645\u0633\u062d \u0627\u0644\u0628\u062d\u062b",
  commands: "\u0627\u0644\u0623\u0648\u0627\u0645\u0631",
  description: "\u0627\u0644\u0646\u0635 \u0627\u0644\u062b\u0627\u0646\u0648\u064a",
  navigate: "\u062a\u0646\u0642\u0644",
  noResults:
    "\u0644\u0645 \u064a\u062a\u0645 \u0627\u0644\u0639\u062b\u0648\u0631 \u0639\u0644\u0649 \u0646\u062a\u0627\u0626\u062c",
  open: "\u0641\u062a\u062d",
  placeholder:
    "\u0627\u0628\u062d\u062b \u0623\u0648 \u0627\u0643\u062a\u0628 \u0623\u0645\u0631\u064b\u0627",
  recent: "\u0627\u0644\u0623\u062e\u064a\u0631\u0629",
  results: "\u0627\u0644\u0646\u062a\u0627\u0626\u062c",
  searchFor: "\u0627\u0628\u062d\u062b \u0639\u0646",
  searchText: "\u0646\u0635 \u0627\u0644\u0628\u062d\u062b",
  tags: [
    "\u0627\u0644\u0643\u0644",
    "\u0627\u0644\u0645\u0647\u0627\u0645",
    "\u0627\u0644\u0623\u0634\u062e\u0627\u0635",
    "\u0627\u0644\u0645\u0644\u0641\u0627\u062a",
    "\u0627\u0644\u0645\u0633\u062a\u0646\u062f\u0627\u062a",
    "\u0627\u0644\u062a\u0639\u0644\u064a\u0642\u0627\u062a",
  ],
  title: "\u0627\u0644\u0639\u0646\u0648\u0627\u0646",
  tryDifferent:
    "\u062c\u0631\u0628 \u0627\u0633\u062a\u062e\u062f\u0627\u0645 \u0643\u0644\u0645\u0627\u062a \u0645\u062e\u062a\u0644\u0641\u0629",
};

const recentRows = [
  { visual: "icon", shortcut: true },
  { visual: "avatar" },
  { visual: "icon", shortcut: true, highlighted: true },
  { visual: "icon", shortcut: true },
  { visual: "icon", shortcut: true },
] as const;

const commandRows = [
  { visual: "icon", shortcut: true },
  { visual: "icon", shortcut: true },
  { visual: "icon", shortcut: true },
  { visual: "icon", shortcut: true },
  { visual: "icon", shortcut: true },
  { visual: "icon", shortcut: true },
] as const;

const resultRows = [
  { visual: "icon", shortcut: true },
  { visual: "avatar" },
  { visual: "icon", shortcut: true, highlighted: true },
  { visual: "icon", shortcut: true },
  { visual: "icon", shortcut: true },
  { visual: "avatar" },
  { visual: "icon", shortcut: true },
  { visual: "icon", shortcut: true },
  { visual: "icon", shortcut: true },
] as const;

export function CommandBar({
  breakpoint = "desktop",
  className = "",
  dir = "ltr",
  nodeId,
  type = "default",
}: CommandBarProps) {
  const rtl = dir === "rtl";
  const copy = rtl ? rtlCopy : ltrCopy;
  const filled = type === "results" || type === "no-result";
  const hasPanel = type !== "default";
  const hasFooter = breakpoint === "desktop" && (type === "recent" || type === "results");

  return (
    <section
      aria-label="Command bar"
      className={[
        "ds-command-bar",
        `ds-command-bar--${breakpoint}`,
        `ds-command-bar--${type}`,
        rtl ? "ds-command-bar--rtl" : "ds-command-bar--ltr",
        className,
      ]
        .filter(Boolean)
        .join(" ")}
      data-node-id={nodeId}
      dir={dir}
    >
      <div className={breakpoint === "mobile" ? "ds-command-bar__input-wrap" : undefined}>
        <SearchInput
          breakpoint={breakpoint}
          copy={copy}
          filled={filled}
          hasDivider={hasPanel && breakpoint === "desktop"}
        />
      </div>

      {type === "recent" && <RecentPanel copy={copy} />}
      {type === "results" && <ResultsPanel copy={copy} />}
      {type === "no-result" && <EmptyPanel copy={copy} />}
      {hasFooter && <CommandFooter copy={copy} />}
    </section>
  );
}

function SearchInput({
  breakpoint,
  copy,
  filled,
  hasDivider,
}: {
  breakpoint: CommandBarBreakpoint;
  copy: CommandBarCopy;
  filled: boolean;
  hasDivider: boolean;
}) {
  const className = [
    "ds-command-bar__search",
    filled ? "ds-command-bar__search--filled" : "ds-command-bar__search--default",
    hasDivider ? "ds-command-bar__search--divider" : "",
  ]
    .filter(Boolean)
    .join(" ");
  const iconSize = breakpoint === "mobile" ? 20 : 24;
  const content = (
    <>
      <span className="ds-command-bar__search-content">
        <SearchIcon size={iconSize} />
        <span className={filled ? "ds-command-bar__search-text" : "ds-command-bar__placeholder"}>
          {filled ? copy.searchText : copy.placeholder}
        </span>
      </span>
      {filled ? (
        <button aria-label={copy.clear} className="ds-command-bar__close" type="button">
          <CloseIcon />
        </button>
      ) : (
        breakpoint === "desktop" && <Shortcut />
      )}
    </>
  );

  if (filled) {
    return (
      <div className={className} role="search">
        {content}
      </div>
    );
  }

  return (
    <button className={className} type="button">
      {content}
    </button>
  );
}

function RecentPanel({ copy }: { copy: CommandBarCopy }) {
  return (
    <div className="ds-command-bar__content">
      <div className="ds-command-bar__main">
        <CommandSection copy={copy} items={recentRows} label={copy.recent} />
        <CommandSection copy={copy} items={commandRows} label={copy.commands} />
      </div>
    </div>
  );
}

function ResultsPanel({ copy }: { copy: CommandBarCopy }) {
  return (
    <div className="ds-command-bar__content">
      <div className="ds-command-bar__main">
        <FilterSection copy={copy} />
        <CommandSection copy={copy} items={resultRows} label={copy.results} />
      </div>
    </div>
  );
}

function EmptyPanel({ copy }: { copy: CommandBarCopy }) {
  return (
    <div className="ds-command-bar__empty">
      <div className="ds-command-bar__empty-wrap">
        <span className="ds-command-bar__empty-icon">
          <SearchIcon size={24} />
        </span>
        <strong>{copy.noResults}</strong>
        <span>{copy.tryDifferent}</span>
      </div>
    </div>
  );
}

function FilterSection({ copy }: { copy: CommandBarCopy }) {
  return (
    <div className="ds-command-bar__filter">
      <SectionHeading>{copy.searchFor}</SectionHeading>
      <div className="ds-command-bar__tags" aria-label={copy.searchFor}>
        {copy.tags.map((tag) => (
          <button className="ds-command-bar__tag" key={tag} type="button">
            {tag}
          </button>
        ))}
      </div>
    </div>
  );
}

function CommandSection({
  copy,
  items,
  label,
}: {
  copy: CommandBarCopy;
  items: ReadonlyArray<CommandRow>;
  label: string;
}) {
  return (
    <div className="ds-command-bar__section">
      <SectionHeading>{label}</SectionHeading>
      <div className="ds-command-bar__group">
        {items.map((item, index) => (
          <CommandItem copy={copy} item={item} key={`${label}-${index}`} />
        ))}
      </div>
    </div>
  );
}

function SectionHeading({ children }: { children: string }) {
  return (
    <div className="ds-command-bar__section-heading">
      <span>{children}</span>
    </div>
  );
}

function CommandItem({
  copy,
  item,
}: {
  copy: CommandBarCopy;
  item: CommandRow;
}) {
  return (
    <button
      className={["ds-command-bar__item", item.highlighted ? "is-highlighted" : ""].filter(Boolean).join(" ")}
      type="button"
    >
      {item.visual === "avatar" ? <Avatar /> : <IconWrap />}
      <span className="ds-command-bar__item-copy">
        <strong>{copy.title}</strong>
        <span>{copy.description}</span>
      </span>
      {item.shortcut && <Shortcut />}
    </button>
  );
}

function CommandFooter({ copy }: { copy: CommandBarCopy }) {
  return (
    <footer className="ds-command-bar__footer">
      <span className="ds-command-bar__footer-content">
        <span className="ds-command-bar__footer-hint">
          <ArrowUpDownIcon />
          <span>{copy.navigate}</span>
        </span>
        <span className="ds-command-bar__footer-hint">
          <EnterIcon />
          <span>{copy.open}</span>
        </span>
      </span>
    </footer>
  );
}

function Shortcut() {
  return <kbd className="ds-command-bar__shortcut">{shortcutText}</kbd>;
}

function IconWrap() {
  return (
    <span className="ds-command-bar__icon-wrap">
      <BookIcon />
    </span>
  );
}

function Avatar() {
  return <span aria-hidden="true" className="ds-command-bar__avatar" />;
}

function SearchIcon({ size = 24 }: { size?: number }) {
  return (
    <svg aria-hidden="true" fill="none" height={size} viewBox="0 0 24 24" width={size}>
      <path
        d="M10.75 18.5a7.75 7.75 0 1 1 5.48-2.27l3.02 3.02"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="2"
      />
    </svg>
  );
}

function CloseIcon() {
  return (
    <svg aria-hidden="true" fill="none" height="20" viewBox="0 0 20 20" width="20">
      <path d="m5 5 10 10M15 5 5 15" stroke="currentColor" strokeLinecap="round" strokeWidth="1.8" />
    </svg>
  );
}

function BookIcon() {
  return (
    <svg aria-hidden="true" fill="none" height="20" viewBox="0 0 20 20" width="20">
      <path
        d="M5.5 3.5h8.2c.9 0 1.6.7 1.6 1.6v10.4H6.2a1.5 1.5 0 0 0 0 3h9.1M5.5 3.5a2 2 0 0 0-2 2v11a2 2 0 0 1 2-2m0-11v11m2.4-7.8h4.8"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.6"
      />
    </svg>
  );
}

function ArrowUpDownIcon() {
  return (
    <svg aria-hidden="true" fill="none" height="16" viewBox="0 0 16 16" width="16">
      <path
        d="M5 2v12m0 0 2.5-2.5M5 14l-2.5-2.5M11 14V2m0 0 2.5 2.5M11 2 8.5 4.5"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.45"
      />
    </svg>
  );
}

function EnterIcon() {
  return (
    <svg aria-hidden="true" fill="none" height="16" viewBox="0 0 16 16" width="16">
      <path
        d="M12.5 3.5v3.25a3 3 0 0 1-3 3H3.75m0 0L6.2 7.3M3.75 9.75 6.2 12.2"
        stroke="currentColor"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth="1.45"
      />
    </svg>
  );
}
