import { Inbox, X } from "lucide-react";
import { useMemo, useState } from "react";
import { createPortal } from "react-dom";
import type { Client } from "../../entities/client/types";
import { PUBLIC_POOL_CLIENT, isPublicPoolClientId } from "../../entities/public-pool/constants";
import type { MeResponse, ProfileOption } from "../../shared/api/mockApi";
import { initials } from "../../shared/lib/format";
import { NodeDcProfileMenu, NodeDcSelect } from "../../shared/nodedc-ui";

export type LauncherAdminMode = "admin" | "platform";
export type LauncherNotificationKind = "nodedc" | "operational-core" | "engine";
export type LauncherNotificationStatus = "new" | "approved" | "rejected" | "cancelled";

export interface LauncherNotificationItem {
  id: string;
  kind: LauncherNotificationKind;
  title: string;
  description: string;
  meta?: string;
  status: LauncherNotificationStatus;
  createdAt: string;
}

export function TopBar({
  me,
  clients,
  profileOptions,
  activeProfileId,
  activeClientId,
  adminOpen,
  adminMode,
  onProfileChange,
  onClientChange,
  onOpenAdmin,
  onOpenPlatform,
  onOpenShowcase,
  onOpenProfileSettings,
  onLogout,
  brandLinkUrl = "/",
  notifications = [],
}: {
  me: MeResponse;
  clients: Client[];
  profileOptions: ProfileOption[];
  activeProfileId: string;
  activeClientId: string;
  adminOpen: boolean;
  adminMode: LauncherAdminMode;
  onProfileChange: (userId: string) => void;
  onClientChange: (clientId: string) => void;
  onOpenAdmin: () => void;
  onOpenPlatform: () => void;
  onOpenShowcase: () => void;
  onOpenProfileSettings: () => void;
  onLogout?: () => void;
  brandLinkUrl?: string;
  notifications?: LauncherNotificationItem[];
}) {
  const [notificationsOpen, setNotificationsOpen] = useState(false);
  const [notificationFilter, setNotificationFilter] = useState<LauncherNotificationKind | "all">("all");
  const availableClientIds = new Set(me.memberships.map((membership) => membership.clientId));
  const clientsWithPublicPool = [
    ...clients,
    availableClientIds.has(PUBLIC_POOL_CLIENT.id) && !clients.some((client) => isPublicPoolClientId(client.id)) ? PUBLIC_POOL_CLIENT : null,
  ].filter((client): client is Client => Boolean(client));
  const availableClients = clientsWithPublicPool.filter((client) => availableClientIds.has(client.id));
  const activeClient = availableClients.find((client) => client.id === activeClientId);
  const clientOptions = availableClients.map((client) => ({
    value: client.id,
    label: client.name,
    description: client.legalName ?? undefined,
  }));
  const canOpenPlatform = me.launcherRole === "root_admin";
  const showLauncherNavigation = me.permissions.canOpenAdmin || canOpenPlatform;
  const unreadCount = notifications.filter((notification) => notification.status === "new").length;
  const visibleNotifications = useMemo(
    () => notifications.filter((notification) => notificationFilter === "all" || notification.kind === notificationFilter),
    [notificationFilter, notifications]
  );

  const notificationsModal = notificationsOpen && typeof document !== "undefined"
    ? createPortal(
        <div className="nodedc-notifications-overlay" onMouseDown={() => setNotificationsOpen(false)}>
          <section className="nodedc-notifications-modal" aria-modal="true" role="dialog" onMouseDown={(event) => event.stopPropagation()}>
            <div className="nodedc-notifications-head">
              <div>
                <h2>Уведомления</h2>
                <span>NODE DC</span>
              </div>
              <button className="nodedc-notifications-close" type="button" aria-label="Закрыть" onClick={() => setNotificationsOpen(false)}>
                <X size={18} strokeWidth={1.8} />
              </button>
            </div>

            <div className="nodedc-notifications-tabs" role="tablist" aria-label="Фильтр уведомлений">
              <NotificationFilterButton active={notificationFilter === "all"} onClick={() => setNotificationFilter("all")}>
                Все
              </NotificationFilterButton>
              <NotificationFilterButton active={notificationFilter === "nodedc"} onClick={() => setNotificationFilter("nodedc")}>
                NODE.DC
              </NotificationFilterButton>
              <NotificationFilterButton active={notificationFilter === "operational-core"} onClick={() => setNotificationFilter("operational-core")}>
                Operational Core
              </NotificationFilterButton>
              <NotificationFilterButton active={notificationFilter === "engine"} onClick={() => setNotificationFilter("engine")}>
                Engine
              </NotificationFilterButton>
            </div>

            <div className="nodedc-notifications-list">
              {visibleNotifications.length === 0 ? (
                <div className="nodedc-notifications-empty">
                  <strong>Новых входящих нет</strong>
                  <span>Заявки NODE.DC, Operational Core и Engine появятся здесь.</span>
                </div>
              ) : (
                visibleNotifications.map((notification) => (
                  <article className="nodedc-notification-card" data-status={notification.status} key={notification.id}>
                    <div className="nodedc-notification-card__kicker">{notificationKindLabel(notification.kind)}</div>
                    <div className="nodedc-notification-card__title">{notification.title}</div>
                    <div className="nodedc-notification-card__description">{notification.description}</div>
                    <div className="nodedc-notification-card__foot">
                      <span>{notificationStatusLabel(notification.status)}</span>
                      {notification.meta ? <span>{notification.meta}</span> : null}
                    </div>
                  </article>
                ))
              )}
            </div>
          </section>
        </div>,
        document.body
      )
    : null;

  return (
    <header className="nodedc-expanded-toolbar-shell">
      <div className="nodedc-expanded-toolbar">
        <div className="nodedc-expanded-toolbar-top">
          <div className="nodedc-expanded-toolbar-left">
            <a href={brandLinkUrl} className="nodedc-expanded-brand-link" aria-label="NODE.DC">
              <img src="/nodedc-logo.svg" alt="NODE DC" className="nodedc-expanded-brand-logo" />
            </a>
          </div>

          <div className="nodedc-expanded-toolbar-center">
            {showLauncherNavigation ? (
              <>
                <NodeDcSelect
                  value={activeClientId}
                  options={clientOptions}
                  label="Выбрать клиента"
                  searchable
                  minMenuWidth={248}
                  onChange={(clientId) => onClientChange(clientId)}
                  trigger={({ open, toggle, setTriggerRef }) => (
                    <button
                      ref={setTriggerRef}
                      className="nodedc-expanded-workspace-button"
                      title={activeClient?.name ?? "Клиент"}
                      type="button"
                      aria-label="Выбрать клиента"
                      aria-expanded={open}
                      onClick={toggle}
                    >
                      {activeClient?.avatarUrl ? <img src={activeClient.avatarUrl} alt="" className="nodedc-expanded-workspace-avatar" /> : null}
                    </button>
                  )}
                />

                <nav className="nodedc-expanded-nav-group" aria-label="Навигация лаунчера">
                  <button className="nodedc-expanded-nav-button" type="button" data-active={!adminOpen} onClick={onOpenShowcase}>
                    <span>Витрина</span>
                  </button>

                  {me.permissions.canOpenAdmin ? (
                    <button
                      className="nodedc-expanded-nav-button"
                      type="button"
                      data-active={adminOpen && adminMode === "admin"}
                      onClick={onOpenAdmin}
                    >
                      <span>Администрирование</span>
                    </button>
                  ) : null}

                  {canOpenPlatform ? (
                    <button
                      className="nodedc-expanded-nav-button"
                      type="button"
                      data-active={adminOpen && adminMode === "platform"}
                      onClick={onOpenPlatform}
                    >
                      <span>Платформа</span>
                    </button>
                  ) : null}
                </nav>
              </>
            ) : null}
          </div>

          <div className="nodedc-expanded-toolbar-right">
            <div className="nodedc-expanded-user-group">
              <button
                className="nodedc-toolbar-icon-button nodedc-expanded-notification-button"
                data-active={unreadCount > 0 ? "true" : "false"}
                type="button"
                aria-label="Уведомления"
                onClick={() => setNotificationsOpen(true)}
              >
                <span className="nodedc-toolbar-icon-active-dot">
                  <Inbox size={20} strokeWidth={1.7} />
                </span>
                {unreadCount > 0 ? <span className="nodedc-notification-badge">{unreadCount > 9 ? "9+" : unreadCount}</span> : null}
              </button>
              <NodeDcProfileMenu
                user={me.user}
                onSettings={onOpenProfileSettings}
                onLogout={onLogout}
                trigger={({ open, toggle, setTriggerRef }) => (
                  <div
                    ref={setTriggerRef}
                    className="nodedc-expanded-profile-trigger"
                    title={`${me.user.name} · ${me.user.email}`}
                    role="button"
                    tabIndex={0}
                    aria-label="Профиль пользователя"
                    aria-expanded={open}
                    onClick={toggle}
                    onKeyDown={(event) => {
                      if (event.key === "Enter" || event.key === " ") {
                        event.preventDefault();
                        toggle();
                      }
                    }}
                  >
                    <span className="nodedc-expanded-nav-button" data-active="false">
                      <span>Профиль</span>
                    </span>
                    <span className="nodedc-expanded-user-avatar-button" aria-hidden="true">
                      {me.user.avatarUrl ? (
                        <img className="nodedc-expanded-user-avatar" src={me.user.avatarUrl} alt="" style={{ objectFit: "cover" }} />
                      ) : (
                        <span className="nodedc-expanded-user-avatar">{initials(me.user.name)}</span>
                      )}
                    </span>
                  </div>
                )}
              />
            </div>
            {notificationsModal}
          </div>
        </div>
      </div>
    </header>
  );
}

function NotificationFilterButton({
  active,
  children,
  onClick,
}: {
  active: boolean;
  children: string;
  onClick: () => void;
}) {
  return (
    <button className="nodedc-notifications-tab" data-active={active ? "true" : "false"} type="button" onClick={onClick}>
      {children}
    </button>
  );
}

function notificationKindLabel(kind: LauncherNotificationKind): string {
  const labels: Record<LauncherNotificationKind, string> = {
    nodedc: "NODE.DC",
    "operational-core": "Operational Core",
    engine: "NODE.DC Engine",
  };

  return labels[kind];
}

function notificationStatusLabel(status: LauncherNotificationStatus): string {
  const labels: Record<LauncherNotificationStatus, string> = {
    new: "Входящее",
    approved: "Подтверждено",
    rejected: "Отклонено",
    cancelled: "Отменено",
  };

  return labels[status];
}
