"use client";

/* eslint-disable @next/next/no-img-element -- white-label логотип хотлинком с сайта клиента, next/image не нужен */

import { UserMenu } from "@/components/auth/UserMenu";
import { API_BASE_URL, HTTPError } from "@/lib/api";
import { isPathAllowed } from "@/lib/isPathAllowed";
import { safeUrl } from "@/lib/safeUrl";
import { useBrand } from "@/lib/useBrand";
import type { Role } from "@/lib/useMe";
import { useMe } from "@/lib/useMe";

/** Telegram-канал обратной связи для пилота. Build-time env — пусто до тех
    пор, пока devops не настроит реальную ссылку (см. FeedbackButton ниже). */
const FEEDBACK_TG_URL = process.env.NEXT_PUBLIC_FEEDBACK_TG_URL ?? "";

/** Inline Send icon (lucide-react `Send` SVG path, stroke 1.5) — та же
    конвенция, что и LogOutIcon в UserMenu.tsx: tradein-mvp не тянет
    lucide-react в deps, поэтому иконка — inline SVG. */
function TelegramIcon() {
  return (
    <svg
      width={16}
      height={16}
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      strokeWidth={1.5}
      strokeLinecap="round"
      strokeLinejoin="round"
      aria-hidden="true"
    >
      <path d="m22 2-7 20-4-9-9-4Z" />
      <path d="M22 2 11 13" />
    </svg>
  );
}

/**
 * Кнопка обратной связи в Telegram — рендерится для ВСЕХ авторизованных
 * пользователей (не зависит от RBAC allowed_paths, в отличие от NAV_ITEMS).
 *
 * Env-gated: пока `NEXT_PUBLIC_FEEDBACK_TG_URL` не задан на билде, кнопка не
 * рендерится вообще — безопасно шипить до появления реальной Telegram-ссылки.
 * safeUrl() дополнительно блокирует не-http(s) схемы (#766-class XSS).
 */
function FeedbackButton() {
  const href = safeUrl(FEEDBACK_TG_URL);
  if (!href) return null;

  return (
    <a
      href={href}
      target="_blank"
      rel="noopener noreferrer"
      className="top-cta"
      aria-label="Обратная связь в Telegram"
    >
      <TelegramIcon />
      Обратная связь
    </a>
  );
}

/** «Мера» mark — буква М над размерной линией («мера» = измерение).
    Глиф в currentColor; тёмный фон даёт CSS-бейдж .brand-mark. */
function MeraMark() {
  return (
    <svg viewBox="0 0 28 28" className="brand-mark-svg" aria-hidden="true" focusable="false">
      {/* буква М */}
      <path d="M8 16V6l6 7 6-7v10" fill="none" stroke="currentColor" strokeWidth="2" strokeLinejoin="round" strokeLinecap="round" />
      {/* размерная линия под М — «мера» = измерение */}
      <path d="M7 21h14M7 19.2v3.6M21 19.2v3.6" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" />
    </svg>
  );
}

export type ActiveTab =
  | "estimate"
  | "sale-share"
  | "history"
  | "cache"
  | "scrapers"
  | "avito"
  | "cian"
  | "yandex"
  | "audit"
  | "analytics"
  | "team";

interface TopbarProps {
  active: ActiveTab;
}

/**
 * Nav items с двумя путями:
 *   `href`        — относительный путь, который рендерится в URL (basePath
 *                   `/trade-in` префиксится через `API_BASE_URL`).
 *   `scopePath`   — абсолютный путь как его видит backend RBAC config
 *                   (`auth/roles.yaml`).
 *
 * Caveat / UX-opinion: pages вида `/trade-in/scrapers/*` сами по себе НЕ
 * в `pilot.deny` (там только `/trade-in/api/v1/admin/**`). По букве yaml
 * pilot имеет право видеть и UI скраперов — но это admin-функционал, и
 * рендерить «битый» dashboard с 403-ошибками на каждый data-fetch — плохой
 * UX. Поэтому для фильтрации Topbar мы маппим scraper-таб на admin-API
 * путь, чтобы pilot их не видел в навигации. Direct URL access на
 * `/trade-in/scrapers/avito` НЕ блокируется (RouteGuard следует yaml). Если
 * нужна полная блокировка — добавить `/trade-in/scrapers/**` в pilot.deny.
 */
const NAV_ITEMS: Array<{
  key: ActiveTab;
  href: string;
  scopePath: string;
  label: string;
  // Доп. gate ПОВЕРХ isPathAllowed — нужен для "team": DB-роль `manager`
  // получает `/api/v1/team/**` в allowed_paths (см. DB_ROLE_PATHS,
  // tradein-mvp/backend/app/services/auth_session.py), но legacy-роль
  // `analyst` (auth/roles.yaml, paths: "/**", БЕЗ явного deny на /api/v1/team)
  // тоже прошла бы обычный isPathAllowed-фильтр — analyst не должен видеть
  // пункт «Команда» (#2556 scope: только admin/manager).
  roleGate?: (role: Role) => boolean;
}> = [
  { key: "estimate", href: "/", scopePath: "/trade-in/", label: "Оценка" },
  // Доля квартир дома в продаже — доступно pilot (scopePath под /trade-in/**).
  {
    key: "sale-share",
    href: "/sale-share",
    scopePath: "/trade-in/sale-share",
    label: "Доля в продаже",
  },
  { key: "history", href: "/history", scopePath: "/trade-in/history", label: "История" },
  { key: "cache", href: "/cache", scopePath: "/trade-in/cache", label: "Кэш" },
  // Скраперы — admin-only UI. Маппим на admin-deny path, чтобы pilot их не видел.
  {
    key: "scrapers",
    href: "/scrapers",
    scopePath: "/trade-in/api/v1/admin/scrapers",
    label: "Скрапперы",
  },
  {
    key: "avito",
    href: "/scrapers/avito",
    scopePath: "/trade-in/api/v1/admin/scrapers/avito",
    label: "Авито",
  },
  {
    key: "cian",
    href: "/scrapers/cian",
    scopePath: "/trade-in/api/v1/admin/scrapers/cian",
    label: "Циан",
  },
  {
    key: "yandex",
    href: "/scrapers/yandex",
    scopePath: "/trade-in/api/v1/admin/scrapers/yandex",
    label: "Яндекс",
  },
  // Аудит доступа (Feature 2) + Активность (Feature 3) — admin-only read API
  // над user_events (см. app/api/v1/audit.py). Тот же admin-scopePath паттерн,
  // что и скрапперы выше: pilot.deny покрывает /trade-in/api/v1/admin/**.
  {
    key: "audit",
    href: "/admin/audit",
    scopePath: "/trade-in/api/v1/admin/audit",
    label: "Аудит",
  },
  {
    key: "analytics",
    href: "/admin/analytics",
    scopePath: "/trade-in/api/v1/admin/analytics",
    label: "Активность",
  },
  // Team-дашборд менеджера (#2556, эпик #2549) — CRUD сотрудников/квоты/история.
  // scopePath БЕЗ /trade-in-префикса — DB_ROLE_PATHS отдаёт голый /api/v1/team/**
  // (не /trade-in/api/v1/team/**), см. комментарий у roleGate выше.
  {
    key: "team",
    href: "/team",
    scopePath: "/api/v1/team",
    label: "Команда",
    roleGate: (role) => role === "admin" || role === "manager",
  },
];

export function Topbar({ active }: TopbarProps) {
  const { data, error } = useMe();
  // #657 white-label: при активном ?brand= с логотипом рендерим логотип
  // клиента вместо «TI»-метки. Без бренда brand === null → стандартный wordmark.
  const { data: brand } = useBrand();

  // 401 (dev без Caddy basic_auth) — показываем все айтемы.
  // Если /me ещё грузится или дал ошибку без scope — fallback на все айтемы
  // (RouteGuard в этом случае сам решит, рендерить ли страницу вообще).
  const isDev401 = error instanceof HTTPError && error.status === 401;
  const items =
    data && !isDev401
      ? NAV_ITEMS.filter(
          (item) =>
            isPathAllowed(data.allowed_paths, data.deny_paths, item.scopePath) &&
            (item.roleGate ? item.roleGate(data.role) : true),
        )
      : NAV_ITEMS;

  return (
    <header className="topbar">
      <div className="topbar-inner">
        <div className="brand">
          {brand ? (
            /* logo_url из бренд-конфига → safeUrl (блок javascript:/data: схем, #766).
               Брендовый логотип — полноразмерный wordmark (содержит название), поэтому
               отдельный brand-product текст НЕ рендерим, иначе дубль названия бренда ×2.
               Невалидный/пустой URL → fallback TI-марка + текстовое название бренда. */
            safeUrl(brand.logo_url) ? (
              <img
                src={safeUrl(brand.logo_url) as string}
                alt={brand.name}
                className="brand-logo"
              />
            ) : (
              /* #1081 white-label без logo_url: показываем первую букву клиента,
                 НЕ нашу марку MeraMark — бренд не должен утекать в чужой заголовок. */
              <>
                <span className="brand-mark">{brand.name.slice(0, 1).toUpperCase()}</span>
                <span className="brand-product">{brand.name}</span>
              </>
            )
          ) : (
            <>
              <span className="brand-mark"><MeraMark /></span>
              <span className="brand-product">Мера</span>
            </>
          )}
        </div>
        <nav className="top-nav">
          {items.map((item) => (
            <a
              key={item.key}
              href={`${API_BASE_URL}${item.href}`}
              className={item.key === active ? "is-active" : undefined}
              aria-current={item.key === active ? "page" : undefined}
            >
              {item.label}
            </a>
          ))}
          {/* UserMenu — личный кабинет справа от nav. В dev (401) или до /me
              UserMenu сам рендерит null. */}
          <UserMenu />
          {/* FeedbackButton — вне items.map/RBAC: видна всем авторизованным
              пользователям независимо от allowed_paths. Сама себя прячет,
              пока NEXT_PUBLIC_FEEDBACK_TG_URL не задан. */}
          <FeedbackButton />
        </nav>
      </div>
    </header>
  );
}
