import { useMemo, useState } from "react";

import type { ActivityCategory, CatalogEntity, CatalogKind, Workout } from "../../types";
import { categoryLabels, measurementLabels } from "../catalog/meta";
import { useCatalog } from "../catalog/hooks";

const categoryTabs: Array<ActivityCategory | "all" | "arms"> = ["all", "chest", "back", "legs", "shoulders", "arms", "core", "cardio"];

function categoryTabLabel(category: ActivityCategory | "all" | "arms") {
  if (category === "all") return "Все";
  if (category === "arms") return "Руки";
  return categoryLabels[category];
}

export function AddExerciseDrawer({
  open,
  token,
  workout,
  onClose,
  onAdd,
  pending,
}: {
  open: boolean;
  token: string;
  workout: Workout;
  onClose: () => void;
  onAdd: (entity: CatalogEntity, kind: CatalogKind, closeAfter: boolean) => void;
  pending?: boolean;
}) {
  const [kind, setKind] = useState<CatalogKind>("exercise");
  const [search, setSearch] = useState("");
  const [category, setCategory] = useState<ActivityCategory | "all" | "arms">("all");
  const { exercises, machines } = useCatalog(token);

  const addedIds = useMemo(() => {
    const ids = new Set<string>();
    workout.items.forEach((item) => {
      if (item.activity_source_id) ids.add(item.activity_source_id);
      if (item.exercise_id) ids.add(item.exercise_id);
      if (item.equipment_id) ids.add(item.equipment_id);
    });
    return ids;
  }, [workout.items]);

  const list = useMemo(() => {
    const source = kind === "exercise" ? exercises.data ?? [] : machines.data ?? [];
    const needle = search.trim().toLowerCase();
    return source.filter((entity) => {
      if (category === "arms" && entity.category !== "biceps" && entity.category !== "triceps") return false;
      if (category !== "all" && category !== "arms" && entity.category !== category) return false;
      if (!needle) return true;
      return `${entity.title} ${entity.description ?? ""}`.toLowerCase().includes(needle);
    });
  }, [category, kind, search, exercises.data, machines.data]);

  if (!open) return null;

  return (
    <div className="drawer-scrim" onClick={onClose}>
      <aside className="add-drawer" aria-label="Добавить в тренировку" onClick={(event) => event.stopPropagation()}>
        <header>
          <div>
            <p className="eyebrow">Catalog drawer</p>
            <h2>Добавить в тренировку</h2>
          </div>
          <button className="round-close" onClick={onClose} aria-label="Закрыть">×</button>
        </header>

        <input className="drawer-search" placeholder="Поиск упражнения или тренажера" value={search} onChange={(event) => setSearch(event.target.value)} />
        <div className="segmented drawer-tabs">
          <button className={kind === "exercise" ? "active" : ""} onClick={() => setKind("exercise")}>Упражнения</button>
          <button className={kind === "machine" ? "active" : ""} onClick={() => setKind("machine")}>Тренажеры</button>
        </div>
        <div className="chip-row drawer-categories">
          {categoryTabs.map((tab) => (
            <button key={tab} className={category === tab ? "active" : ""} onClick={() => setCategory(tab)}>{categoryTabLabel(tab)}</button>
          ))}
        </div>

        <div className="drawer-list">
          {list.map((entity) => {
            const added = addedIds.has(entity.id);
            return (
              <article className={`drawer-pick ${added ? "already-added" : ""}`} key={`${kind}-${entity.id}`} onClick={() => onAdd(entity, kind, true)}>
                {entity.image_s3_url ? <img src={entity.image_s3_url} alt="" /> : <span className="drawer-placeholder">{kind === "exercise" ? "EX" : "MC"}</span>}
                <div>
                  <h3>{entity.title}</h3>
                  <p>{categoryLabels[entity.category]} · {measurementLabels[entity.measurement_type]}</p>
                  {added && <b>В тренировке</b>}
                </div>
                <button
                  className="plus-chip"
                  disabled={pending}
                  onClick={(event) => {
                    event.stopPropagation();
                    onAdd(entity, kind, false);
                  }}
                  aria-label="Добавить и оставить drawer открытым"
                >
                  +
                </button>
              </article>
            );
          })}
          {list.length === 0 && <p className="muted">Ничего не найдено.</p>}
        </div>
      </aside>
    </div>
  );
}
