"use client";
/* eslint-disable @next/next/no-img-element */

import { ChangeEvent, useEffect, useRef, useState } from "react";
import {
  Archive,
  FileSearch,
  PackageCheck,
  PackageX,
  Pencil,
  ToggleLeft,
  ToggleRight,
  X,
} from "lucide-react";
import { SbisCatalogPanel } from "./sbis-catalog-panel";
import { CursorTooltip } from "./cursor-tooltip";

type Category = {
  id: number;
  slug: string;
  name: string;
  yandexCategoryId: number;
  sortOrder: number;
  isActive: boolean;
  archivedAt: Date | string | null;
  sbisCategoryId: string | null;
  sbisCategoryNameSnapshot: string | null;
  categorySyncState: string;
};
type Item = {
  id: number;
  slug: string;
  categoryId: number;
  name: string;
  description: string | null;
  shortDescription: string | null;
  ingredients: string | null;
  weightText: string | null;
  imageUrl: string | null;
  isAvailable: boolean;
  isAlcohol: boolean;
  showOnWebsite: boolean;
  showDetails: boolean;
  publishToYandex: boolean;
  allowOnlineOrder: boolean;
  allowDelivery: boolean;
  archivedAt: Date | string | null;
};
type Variant = {
  id: number;
  itemId: number;
  label: string;
  priceKopecks: number;
  yandexOfferId: string;
  isAvailable: boolean;
};
type Link = {
  id: number;
  menuItemId: number;
  sbisId: string;
  unlinkedAt: Date | string | null;
  unlinkReason: string | null;
};
type SyncState = {
  lastAttemptAt: string | null;
  lastSuccessAt: string | null;
  lastDurationMs: number | null;
  lastError: string | null;
  lastSnapshotId: string | null;
  sourceVersion: string | null;
  itemsCount: number;
  categoriesCount: number;
} | null;
type AuditEvent = {
  id: number;
  actor: string;
  action: string;
  entityType: string | null;
  entityId: string | null;
  createdAt: string;
};
type SbisBinding = {
  sbisId: string;
  name: string;
  categoryName: string;
  priceKopecks: number;
  available: boolean;
  inCurrentPrice: boolean;
};
type SbisCatalogOption = SbisBinding & { categoryId: string | null };
export type Data = {
  categories: Category[];
  items: Item[];
  variants: Variant[];
  links?: Link[];
  syncState?: SyncState;
  auditEvents?: AuditEvent[];
  categorySbis?: Record<string, { id: string | null; name: string }[]>;
  sbisBindings?: Record<string, SbisBinding>;
  sbisCatalog?: SbisCatalogOption[];
  sbisCategories?: { id: string; name: string }[];
};
type ItemDraft = Pick<
  Item,
  | "name"
  | "description"
  | "shortDescription"
  | "weightText"
  | "imageUrl"
  | "isAvailable"
  | "isAlcohol"
  | "showOnWebsite"
  | "publishToYandex"
  | "allowOnlineOrder"
  | "allowDelivery"
> & { priceRubles: string };

async function mutate(method: string, body: unknown) {
  const csrf = document.cookie
    .split("; ")
    .find((part) => part.startsWith("kiln-admin-csrf="))
    ?.split("=")[1];
  const response = await fetch("/api/admin/menu", {
    method,
    headers: {
      "content-type": "application/json",
      ...(csrf ? { "x-csrf-token": decodeURIComponent(csrf) } : {}),
    },
    body: JSON.stringify(body),
  });
  if (!response.ok)
    throw new Error((await response.json()).error || "Ошибка сохранения");
}

function csrfHeaders() {
  const csrf = document.cookie
    .split("; ")
    .find((part) => part.startsWith("kiln-admin-csrf="))
    ?.split("=")[1];
  return csrf
    ? { "x-csrf-token": decodeURIComponent(csrf) }
    : ({} as Record<string, string>);
}

function ImageUploader({
  item,
  onUploaded,
  onRemoved,
}: {
  item: Item;
  onUploaded: (url: string) => Promise<void>;
  onRemoved: () => Promise<void>;
}) {
  const inputRef = useRef<HTMLInputElement>(null);
  const [uploading, setUploading] = useState(false);
  const [error, setError] = useState("");

  async function upload(event: ChangeEvent<HTMLInputElement>) {
    const file = event.target.files?.[0];
    event.target.value = "";
    if (!file) return;
    setError("");
    setUploading(true);
    try {
      const form = new FormData();
      form.append("file", file);
      form.append("slug", item.slug);
      form.append("name", item.name);
      const response = await fetch("/api/admin/menu/image", {
        method: "POST",
        headers: csrfHeaders(),
        body: form,
      });
      const result = await response.json();
      if (!response.ok)
        throw new Error(result.error || "Не удалось загрузить фото");
      await onUploaded(result.url);
    } catch (uploadError) {
      setError(
        uploadError instanceof Error
          ? uploadError.message
          : "Не удалось загрузить фото",
      );
    } finally {
      setUploading(false);
    }
  }

  return (
    <div className="mt-3 rounded border border-white/10 bg-black/15 p-3">
      <div className="flex flex-wrap items-center gap-3">
        {item.imageUrl ? (
          <>
            <span className="sr-only">Текущее фото</span>
            {/* eslint-disable-next-line @next/next/no-img-element */}
            <img
              src={item.imageUrl}
              alt=""
              className="h-20 w-20 rounded object-cover"
            />
          </>
        ) : (
          <div className="flex h-20 w-20 items-center justify-center rounded bg-white/5 text-center text-xs text-kiln-milk/45">
            Нет фото
          </div>
        )}
        <div className="flex min-w-48 flex-1 flex-wrap gap-2">
          <input
            ref={inputRef}
            className="sr-only"
            type="file"
            accept="image/jpeg,image/png,image/webp,image/avif"
            onChange={upload}
          />
          <button
            type="button"
            className="button button-primary"
            disabled={uploading}
            onClick={() => inputRef.current?.click()}
          >
            {uploading
              ? "Загрузка…"
              : item.imageUrl
                ? "Заменить фото"
                : "Загрузить фото"}
          </button>
          {item.imageUrl ? (
            <button
              type="button"
              className="button button-secondary"
              disabled={uploading}
              onClick={async () => {
                setError("");
                setUploading(true);
                try {
                  await onRemoved();
                } catch (removeError) {
                  setError(
                    removeError instanceof Error
                      ? removeError.message
                      : "Ошибка удаления",
                  );
                } finally {
                  setUploading(false);
                }
              }}
            >
              Удалить
            </button>
          ) : null}
          <p className="basis-full text-xs text-kiln-milk/50">
            JPG, PNG, WebP или AVIF · до 8 МБ. Фото автоматически станет WebP.
          </p>
        </div>
      </div>
      {error ? <p className="mt-2 text-sm text-kiln-flame">{error}</p> : null}
    </div>
  );
}

export function AdminMenuPanel({
  loggedIn,
  stats,
  initialData = null,
  initialError = "",
}: {
  loggedIn: boolean;
  stats: { items: number; lastFeed: string } | null;
  initialData?: Data | null;
  initialError?: string;
}) {
  const [login, setLogin] = useState("");
  const [password, setPassword] = useState("");
  const [data, setData] = useState<Data | null>(initialData);
  const [message, setMessage] = useState(initialError);
  const [photoItemId, setPhotoItemId] = useState<number | null>(null);
  const [editItem, setEditItem] = useState<Item | null>(null);
  const [editDraft, setEditDraft] = useState<ItemDraft | null>(null);
  const [savingEdit, setSavingEdit] = useState(false);
  const [bindingSbisId, setBindingSbisId] = useState("");
  const [savingBinding, setSavingBinding] = useState(false);
  const [category, setCategory] = useState({
    name: "",
    slug: "",
    yandexCategoryId: "",
  });
  const [item, setItem] = useState({
    name: "",
    slug: "",
    categorySlug: "",
    description: "",
    weightText: "",
    priceRubles: "",
    isAlcohol: false,
  });

  useEffect(() => {
    if (loggedIn)
      fetch("/api/admin/menu")
        .then(async (response) => {
          const result = await response.json();
          if (!response.ok)
            throw new Error(result.error || "Не удалось загрузить меню");
          return result;
        })
        .then(setData)
        .catch((error) =>
          setMessage(
            error instanceof Error
              ? error.message
              : "Не удалось загрузить меню",
          ),
        );
  }, [loggedIn]);

  if (!loggedIn)
    return (
      <main className="section">
        <div className="site-container max-w-lg">
          <h1 className="display-title text-5xl">Управление меню</h1>
          <p className="mt-3 muted">Раздел доступен только администратору.</p>
          <form
            className="mt-6 grid gap-3"
            onSubmit={async (event) => {
              event.preventDefault();
              const response = await fetch("/api/admin/menu/login", {
                method: "POST",
                headers: { "content-type": "application/json" },
                body: JSON.stringify({ login, password }),
              });
              if (response.ok) location.reload();
              else setMessage("Неверные данные для входа");
            }}
          >
            <input
              className="input"
              type="text"
              autoComplete="username"
              value={login}
              onChange={(event) => setLogin(event.target.value)}
              placeholder="Логин"
            />
            <input
              className="input"
              type="password"
              autoComplete="current-password"
              value={password}
              onChange={(event) => setPassword(event.target.value)}
              placeholder="Пароль"
            />
            <button className="button button-primary">Войти</button>
            {message ? <p className="text-kiln-flame">{message}</p> : null}
          </form>
        </div>
      </main>
    );

  const refresh = () =>
    fetch("/api/admin/menu")
      .then((response) => response.json())
      .then(setData);
  const save = async (request: Promise<unknown>) => {
    try {
      await request;
      setMessage("Сохранено");
      await refresh();
    } catch (error) {
      setMessage(error instanceof Error ? error.message : "Ошибка");
    }
  };
  const updateImage = (current: Item, imageUrl: string | null) =>
    save(
      mutate("PATCH", {
        type: "item",
        id: current.id,
        name: current.name,
        description: current.description,
        shortDescription: current.shortDescription,
        weightText: current.weightText,
        imageUrl,
        isAvailable: current.isAvailable,
        showOnWebsite: current.showOnWebsite,
        showDetails: current.showDetails,
        isAlcohol: current.isAlcohol,
        allowOnlineOrder: current.allowOnlineOrder,
        allowDelivery: current.allowDelivery,
        publishToYandex: current.publishToYandex,
      }),
    );
  const openEditor = (current: Item) => {
    const variant = data?.variants.find(
      (candidate) => candidate.itemId === current.id,
    );
    setEditItem(current);
    setEditDraft({
      ...current,
      priceRubles: variant ? String(variant.priceKopecks / 100) : "",
    });
    setBindingSbisId(data?.sbisBindings?.[String(current.id)]?.sbisId || "");
  };
  const closeEditor = () => {
    if (!savingEdit) {
      setEditItem(null);
      setEditDraft(null);
    }
  };
  const saveEdit = async (event: React.FormEvent) => {
    event.preventDefault();
    if (!editItem || !editDraft) return;
    setSavingEdit(true);
    try {
      await mutate("PATCH", { type: "item", id: editItem.id, ...editDraft });
      const variant = data?.variants.find(
        (candidate) => candidate.itemId === editItem.id,
      );
      if (variant && editDraft.priceRubles)
        await mutate("PATCH", {
          type: "variant",
          id: variant.id,
          label: variant.label,
          priceRubles: editDraft.priceRubles,
          isAvailable: variant.isAvailable,
        });
      if (!variant && editDraft.priceRubles)
        await mutate("POST", {
          type: "variant",
          itemId: editItem.id,
          label: editDraft.weightText || "1 порция",
          priceRubles: editDraft.priceRubles,
          yandexOfferId: `${editItem.slug}-main`,
        });
      setMessage("Позиция сохранена");
      setEditItem(null);
      setEditDraft(null);
      await refresh();
    } catch (error) {
      setMessage(error instanceof Error ? error.message : "Ошибка сохранения");
    } finally {
      setSavingEdit(false);
    }
  };

  const saveBinding = async () => {
    if (!editItem || savingBinding) return;
    const previous = data?.sbisBindings?.[String(editItem.id)]?.sbisId || "";
    if (previous === bindingSbisId) return;
    if (previous && bindingSbisId && !window.confirm("Сменить привязку блюда к выбранной позиции СБИС?")) return;
    setSavingBinding(true);
    try {
      const response = await fetch("/api/admin/menu/link", {
        method: "PUT",
        headers: { "content-type": "application/json", ...csrfHeaders() },
        body: JSON.stringify({ menuItemId: editItem.id, sbisId: bindingSbisId || null }),
      });
      const result = await response.json();
      if (!response.ok) throw new Error(result.error || "Не удалось изменить привязку");
      setMessage(bindingSbisId ? "Привязка СБИС сохранена" : "Привязка СБИС снята");
      await refresh();
    } catch (error) {
      setMessage(error instanceof Error ? error.message : "Не удалось изменить привязку");
    } finally {
      setSavingBinding(false);
    }
  };

  const editBinding = editItem
    ? data?.sbisBindings?.[String(editItem.id)]
    : undefined;

  return (
    <main className="section">
      <div className="site-container">
        <div>
          <p className="eyebrow">Администрирование</p>
          <h1 className="display-title mt-2 text-5xl">Меню</h1>
        </div>
        <div className="mt-6 grid gap-4 md:grid-cols-3">
          <div className="card p-5">
            <span className="muted">Позиций</span>
            <strong className="mt-2 block text-3xl">
              {stats?.items ?? data?.items.length ?? 0}
            </strong>
          </div>
          <div className="card p-5">
            <span className="muted">Последний запрос YML</span>
            <strong className="mt-2 block text-sm">
              {stats?.lastFeed || "не запрашивался"}
            </strong>
          </div>
          <a
            href="/yandex-menu"
            target="_blank"
            className="card p-5 text-kiln-flame"
          >
            Предпросмотр YML →
          </a>
        </div>
        <SbisCatalogPanel
          localItems={data?.items || []}
          links={data?.links || []}
          syncState={data?.syncState || null}
          auditEvents={data?.auditEvents || []}
          onChanged={refresh}
        />
        <div className="mt-8 grid gap-6 lg:grid-cols-2">
          <section className="card grid gap-3 p-5">
            <h2 className="text-2xl">Новая категория</h2>
            <input
              className="input"
              placeholder="Название"
              value={category.name}
              onChange={(e) =>
                setCategory({ ...category, name: e.target.value })
              }
            />
            <input
              className="input"
              placeholder="slug"
              value={category.slug}
              onChange={(e) =>
                setCategory({ ...category, slug: e.target.value })
              }
            />
            <input
              className="input"
              placeholder="Yandex category ID"
              type="number"
              value={category.yandexCategoryId}
              onChange={(e) =>
                setCategory({ ...category, yandexCategoryId: e.target.value })
              }
            />
            <button
              className="button button-primary"
              onClick={() =>
                save(mutate("POST", { type: "category", ...category }))
              }
            >
              Создать категорию
            </button>
          </section>
          <section className="card grid gap-3 p-5">
            <h2 className="text-2xl">Новая позиция</h2>
            <input
              className="input"
              placeholder="Название"
              value={item.name}
              onChange={(e) => setItem({ ...item, name: e.target.value })}
            />
            <input
              className="input"
              placeholder="slug"
              value={item.slug}
              onChange={(e) => setItem({ ...item, slug: e.target.value })}
            />
            <select
              className="input"
              value={item.categorySlug}
              onChange={(e) =>
                setItem({ ...item, categorySlug: e.target.value })
              }
            >
              <option value="">Категория</option>
              {data?.categories
                .filter((c) => c.isActive)
                .map((c) => (
                  <option key={c.id} value={c.slug}>
                    {c.name}
                  </option>
                ))}
            </select>
            <textarea
              className="input"
              placeholder="Описание"
              value={item.description}
              onChange={(e) =>
                setItem({ ...item, description: e.target.value })
              }
            />
            <input
              className="input"
              placeholder="Вес/объём"
              value={item.weightText}
              onChange={(e) => setItem({ ...item, weightText: e.target.value })}
            />
            <input
              className="input"
              placeholder="Цена, ₽"
              type="number"
              value={item.priceRubles}
              onChange={(e) =>
                setItem({ ...item, priceRubles: e.target.value })
              }
            />
            <label className="flex gap-2">
              <input
                type="checkbox"
                checked={item.isAlcohol}
                onChange={(e) =>
                  setItem({ ...item, isAlcohol: e.target.checked })
                }
              />{" "}
              Алкоголь (заказ и доставка будут запрещены)
            </label>
            <button
              className="button button-primary"
              onClick={() => save(mutate("POST", { type: "item", ...item }))}
            >
              Создать позицию
            </button>
          </section>
        </div>
        <section className="mt-8 card p-5">
          <h2 className="text-2xl">Категории и позиции</h2>
          <p className="mt-2 text-sm text-kiln-milk/60">
            Карандаш открывает полное редактирование позиции, включая фото и
            цену.
          </p>
          <div className="mt-4 grid gap-3">
            {data?.categories.map((c) => (
              <div key={c.id} className="border-b border-white/10 pb-3">
                <div className="flex flex-wrap items-center justify-between gap-3">
                  <strong>{c.name}</strong>
                  <CursorTooltip
                    text={
                      c.isActive
                        ? "Выключить категорию. Сейчас включена"
                        : "Включить категорию. Сейчас выключена"
                    }
                  >
                    <button
                      type="button"
                      className={`icon-button ${c.isActive ? "text-emerald-400" : "text-red-400"}`}
                      aria-label={
                        c.isActive
                          ? "Выключить категорию. Сейчас включена"
                          : "Включить категорию. Сейчас выключена"
                      }
                      onClick={() =>
                        save(
                          mutate("PATCH", {
                            type: "category",
                            id: c.id,
                            name: c.name,
                            slug: c.slug,
                            yandexCategoryId: c.yandexCategoryId,
                            isActive: !c.isActive,
                          }),
                        )
                      }
                    >
                      {c.isActive ? (
                        <ToggleRight size={20} />
                      ) : (
                        <ToggleLeft size={20} />
                      )}
                    </button>
                  </CursorTooltip>
                </div>
                {(() => {
                  const itemCats = data.categorySbis?.[String(c.id)] || [];
                  const mismatch =
                    c.sbisCategoryId !== null &&
                    (itemCats.length === 0 ||
                      itemCats.some((entry) => entry.id !== c.sbisCategoryId));
                  return (
                    <div className="mt-1 flex flex-wrap items-center gap-2 text-xs text-kiln-milk/60">
                      <span>
                        СБИС:{" "}
                        {c.sbisCategoryNameSnapshot ||
                          (c.sbisCategoryId
                            ? `id ${c.sbisCategoryId} нет в прайсе`
                            : "не привязана")}
                      </span>
                      {itemCats.length > 1 ? (
                        <span className="text-kiln-flame">
                          позиции из нескольких категорий СБИС:{" "}
                          {itemCats.map((entry) => entry.name).join(", ")}
                        </span>
                      ) : null}
                      {mismatch && itemCats.length === 1 ? (
                        <span className="text-kiln-flame">
                          расхождение с категорией позиций
                        </span>
                      ) : null}
                      <select
                        className="input min-w-56 max-w-sm text-xs"
                        aria-label={`Категория СБИС для ${c.name}`}
                        value={c.sbisCategoryId || ""}
                        onChange={(event) => {
                          const next = event.target.value;
                          save(
                            mutate("PATCH", {
                              type: "category",
                              id: c.id,
                              name: c.name,
                              slug: c.slug,
                              yandexCategoryId: c.yandexCategoryId,
                              isActive: c.isActive,
                              sbisCategoryId: next || null,
                            }),
                          );
                        }}
                      >
                        <option value="">Не привязана</option>
                        {c.sbisCategoryId && !data.sbisCategories?.some((option) => option.id === c.sbisCategoryId) ? (
                          <option value={c.sbisCategoryId}>{c.sbisCategoryNameSnapshot || `ID ${c.sbisCategoryId}`} · нет в текущем каталоге</option>
                        ) : null}
                        {data.sbisCategories?.map((option) => (
                          <option key={option.id} value={option.id}>{option.name} · #{option.id}</option>
                        ))}
                      </select>
                    </div>
                  );
                })()}
                {data.items
                  .filter((i) => i.categoryId === c.id)
                  .map((i) => (
                    <div
                      key={i.id}
                      className="mt-2 rounded border border-transparent p-2 pl-4 text-sm transition hover:border-white/10"
                    >
                      <div className="flex flex-wrap items-center justify-between gap-2">
                        <div className="flex min-w-0 items-center gap-3">
                          {i.imageUrl ? (
                            <>
                              {/* eslint-disable-next-line @next/next/no-img-element */}
                              <img
                                src={i.imageUrl}
                                alt=""
                                className="h-10 w-10 shrink-0 rounded object-cover"
                              />
                            </>
                          ) : (
                            <div className="h-10 w-10 shrink-0 rounded bg-white/5" />
                          )}
                          <span className="min-w-0">
                            {i.name} ·{" "}
                            {(data.variants.filter((v) => v.itemId === i.id)[0]
                              ?.priceKopecks || 0) / 100}{" "}
                            ₽ {i.isAlcohol ? "· 18+" : ""}
                            <small className="mt-1 block truncate text-kiln-milk/50">
                              {data.sbisBindings?.[String(i.id)]
                                ? `СБИС: ${data.sbisBindings[String(i.id)].name} · #${data.sbisBindings[String(i.id)].sbisId}`
                                : "СБИС: не привязана"}
                            </small>
                          </span>
                        </div>
                        <div className="flex flex-wrap gap-2">
                          <CursorTooltip text="Редактировать позицию">
                            <button
                              type="button"
                              className="icon-button"
                              aria-label="Редактировать позицию"
                              onClick={() => openEditor(i)}
                            >
                              <Pencil size={17} />
                            </button>
                          </CursorTooltip>
                          <CursorTooltip
                            text={
                              i.isAvailable
                                ? "Снять с наличия. Сейчас доступна"
                                : "Вернуть в наличие. Сейчас недоступна"
                            }
                          >
                            <button
                              type="button"
                              className={`icon-button ${i.isAvailable ? "text-emerald-400" : "text-red-400"}`}
                              aria-label={
                                i.isAvailable
                                  ? "Снять с наличия. Сейчас доступна"
                                  : "Вернуть в наличие. Сейчас недоступна"
                              }
                              onClick={() =>
                                save(
                                  mutate("PATCH", {
                                    type: "item",
                                    id: i.id,
                                    name: i.name,
                                    description: i.description,
                                    weightText: i.weightText,
                                    isAvailable: !i.isAvailable,
                                    showOnWebsite: i.showOnWebsite,
                                    showDetails: i.showDetails,
                                    isAlcohol: i.isAlcohol,
                                    allowOnlineOrder: i.allowOnlineOrder,
                                    allowDelivery: i.allowDelivery,
                                    publishToYandex: i.publishToYandex,
                                    imageUrl: i.imageUrl,
                                  }),
                                )
                              }
                            >
                              {i.isAvailable ? (
                                <PackageCheck size={18} />
                              ) : (
                                <PackageX size={18} />
                              )}
                            </button>
                          </CursorTooltip>
                          <CursorTooltip text="Архивировать позицию">
                            <button
                              type="button"
                              className="icon-button text-red-400"
                              aria-label="Архивировать позицию"
                              onClick={() =>
                                save(
                                  mutate("DELETE", { type: "item", id: i.id }),
                                )
                              }
                            >
                              <Archive size={18} />
                            </button>
                          </CursorTooltip>
                        </div>
                      </div>
                      {photoItemId === i.id ? (
                        <ImageUploader
                          item={i}
                          onUploaded={(url) => updateImage(i, url)}
                          onRemoved={() => updateImage(i, null)}
                        />
                      ) : null}
                    </div>
                  ))}
              </div>
            ))}
          </div>
        </section>
        {message ? <p className="mt-4 text-kiln-flame">{message}</p> : null}
      </div>
      {editItem && editDraft ? (
        <div
          className="dish-modal"
          role="presentation"
          onMouseDown={(event) =>
            event.target === event.currentTarget && closeEditor()
          }
        >
          <section
            className="dish-modal-panel !block max-w-2xl !overflow-y-auto"
            role="dialog"
            aria-modal="true"
            aria-labelledby="admin-edit-title"
          >
            <div className="dish-modal-content !overflow-visible">
              <div className="mb-5 flex items-start justify-between gap-4">
                <div>
                  <p className="eyebrow">Позиция меню</p>
                  <h2 id="admin-edit-title" className="mt-1 text-2xl">
                    Редактировать блюдо
                  </h2>
                </div>
                <button
                  type="button"
                  className="icon-button"
                  onClick={closeEditor}
                  aria-label="Закрыть"
                >
                  <X size={18} />
                </button>
              </div>
              <form className="grid gap-3" onSubmit={saveEdit}>
                <input
                  className="input"
                  required
                  placeholder="Название"
                  value={editDraft.name}
                  onChange={(event) =>
                    setEditDraft({ ...editDraft, name: event.target.value })
                  }
                />
                <textarea
                  className="input min-h-28"
                  placeholder="Описание"
                  value={editDraft.description || ""}
                  onChange={(event) =>
                    setEditDraft({
                      ...editDraft,
                      description: event.target.value,
                    })
                  }
                />
                <input
                  className="input"
                  placeholder="Короткое описание"
                  value={editDraft.shortDescription || ""}
                  onChange={(event) =>
                    setEditDraft({
                      ...editDraft,
                      shortDescription: event.target.value,
                    })
                  }
                />
                <div className="grid gap-3 sm:grid-cols-2">
                  <input
                    className="input"
                    placeholder="Вес/объём"
                    value={editDraft.weightText || ""}
                    onChange={(event) =>
                      setEditDraft({
                        ...editDraft,
                        weightText: event.target.value,
                      })
                    }
                  />
                  <input
                    className="input"
                    required
                    min="0"
                    step="0.01"
                    type="number"
                    placeholder="Цена, ₽"
                    value={editDraft.priceRubles}
                    onChange={(event) =>
                      setEditDraft({
                        ...editDraft,
                        priceRubles: event.target.value,
                      })
                    }
                  />
                </div>
                <div className="grid gap-2 rounded border border-white/10 p-3">
                  <label className="flex gap-2">
                    <input
                      type="checkbox"
                      checked={editDraft.isAvailable}
                      onChange={(event) =>
                        setEditDraft({
                          ...editDraft,
                          isAvailable: event.target.checked,
                        })
                      }
                    />{" "}
                    В наличии
                  </label>
                  <label className="flex gap-2">
                    <input
                      type="checkbox"
                      checked={editDraft.showOnWebsite}
                      onChange={(event) =>
                        setEditDraft({
                          ...editDraft,
                          showOnWebsite: event.target.checked,
                        })
                      }
                    />{" "}
                    Показывать на сайте
                  </label>
                  <label className="flex gap-2">
                    <input
                      type="checkbox"
                      checked={editDraft.publishToYandex}
                      onChange={(event) =>
                        setEditDraft({
                          ...editDraft,
                          publishToYandex: event.target.checked,
                        })
                      }
                    />{" "}
                    Публиковать в Яндекс
                  </label>
                  <label className="flex gap-2">
                    <input
                      type="checkbox"
                      checked={editDraft.allowOnlineOrder}
                      onChange={(event) =>
                        setEditDraft({
                          ...editDraft,
                          allowOnlineOrder: event.target.checked,
                        })
                      }
                    />{" "}
                    Разрешить онлайн-заказ
                  </label>
                  <label className="flex gap-2">
                    <input
                      type="checkbox"
                      checked={editDraft.allowDelivery}
                      onChange={(event) =>
                        setEditDraft({
                          ...editDraft,
                          allowDelivery: event.target.checked,
                        })
                      }
                    />{" "}
                    Разрешить доставку
                  </label>
                  <label className="flex gap-2">
                    <input
                      type="checkbox"
                      checked={editDraft.isAlcohol}
                      onChange={(event) =>
                        setEditDraft({
                          ...editDraft,
                          isAlcohol: event.target.checked,
                        })
                      }
                    />{" "}
                    Алкоголь (заказ и доставка будут запрещены)
                  </label>
                </div>
                <div className="rounded border border-white/10 bg-black/15 p-3 text-sm">
                  <div className="flex items-center justify-between gap-3">
                    <strong>Привязка к СБИС</strong>
                    {editBinding ? (
                      <FileSearch
                        size={18}
                        className="text-kiln-flame"
                        aria-hidden="true"
                      />
                    ) : null}
                  </div>
                  {editBinding ? (
                    <div className="mt-2 grid gap-1 text-kiln-milk/65">
                      <span>
                        {editBinding.name} · #{editBinding.sbisId}
                      </span>
                      <span>
                        {editBinding.categoryName} ·{" "}
                        {editBinding.priceKopecks / 100}
                        {"\u00a0"}₽
                      </span>
                      <span
                        className={
                          editBinding.inCurrentPrice && editBinding.available
                            ? "text-emerald-400"
                            : "text-red-400"
                        }
                      >
                        {!editBinding.inCurrentPrice
                          ? "Нет в текущем прайсе"
                          : editBinding.available
                            ? "В наличии"
                            : "Нет в наличии"}
                      </span>
                    </div>
                  ) : (
                    <p className="mt-2 text-kiln-milk/55">Не привязана</p>
                  )}
                  <div className="mt-3 grid gap-2 sm:grid-cols-[minmax(0,1fr)_auto]">
                    <select
                      className="input text-sm"
                      value={bindingSbisId}
                      disabled={savingBinding}
                      onChange={(event) => setBindingSbisId(event.target.value)}
                    >
                      <option value="">Не привязана</option>
                      {data?.sbisCatalog?.filter((option) => option.inCurrentPrice || option.sbisId === editBinding?.sbisId).map((option) => {
                        const occupied = data.links?.find((link) => !link.unlinkedAt && link.sbisId === option.sbisId && link.menuItemId !== editItem.id);
                        return <option key={option.sbisId} value={option.sbisId} disabled={Boolean(occupied)}>{option.categoryName} · {option.name} · #{option.sbisId}{occupied ? " · занята" : ""}</option>;
                      })}
                    </select>
                    <button
                      type="button"
                      className="button button-secondary"
                      disabled={savingBinding || bindingSbisId === (editBinding?.sbisId || "")}
                      onClick={() => void saveBinding()}
                    >
                      {savingBinding ? "Сохраняем…" : bindingSbisId ? "Сохранить связь" : "Отвязать"}
                    </button>
                  </div>
                </div>
                <ImageUploader
                  item={{ ...editItem, imageUrl: editDraft.imageUrl }}
                  onUploaded={async (url) =>
                    setEditDraft({ ...editDraft, imageUrl: url })
                  }
                  onRemoved={async () =>
                    setEditDraft({ ...editDraft, imageUrl: null })
                  }
                />
                <div className="mt-2 flex justify-end gap-3">
                  <button
                    type="button"
                    className="button button-secondary"
                    onClick={closeEditor}
                    disabled={savingEdit}
                  >
                    Отмена
                  </button>
                  <button
                    type="submit"
                    className="button button-primary"
                    disabled={savingEdit}
                  >
                    {savingEdit ? "Сохранение…" : "Сохранить изменения"}
                  </button>
                </div>
              </form>
            </div>
          </section>
        </div>
      ) : null}
    </main>
  );
}
