import { useTranslation } from 'react-i18next';
import { NavLink } from 'react-router-dom';

import { useAuth } from '../context/AuthContext';
import { useConversationsContext } from '../context/ConversationsContext';
import { useFriendshipsContext } from '../context/FriendshipsContext';
import {
  ChatBubbleIcon,
  GearIcon,
  LogoMark,
  ShieldIcon,
  SignOutIcon,
  SparklesIcon,
  UsersIcon,
} from './icons';

interface NavItem {
  to: string;
  labelKey: string;
  icon: (props: React.SVGProps<SVGSVGElement>) => React.JSX.Element;
  badge?: 'friends' | 'chats';
}

const PRIMARY_NAV: NavItem[] = [
  { to: '/chats', labelKey: 'app:nav.chats', icon: ChatBubbleIcon, badge: 'chats' },
  { to: '/friends', labelKey: 'app:nav.friends', icon: UsersIcon, badge: 'friends' },
];
const ADMIN_NAV: NavItem = {
  to: '/admin',
  labelKey: 'app:nav.admin',
  icon: ShieldIcon,
};

// Clean-Rail 72px icon rail. Brand logo top → primary tabs → spacer →
// settings + theme toggle + sign-out at bottom. Active tab shows a pill
// indicator anchored to the left edge of the rail.
export function Sidebar() {
  const { t } = useTranslation(['app']);
  const { signOut, profile } = useAuth();
  const { incomingCount } = useFriendshipsContext();
  const { totalUnread } = useConversationsContext();

  const navItems: NavItem[] = profile?.isAdmin ? [...PRIMARY_NAV, ADMIN_NAV] : PRIMARY_NAV;

  return (
    <aside
      aria-label="Primary navigation"
      className="discord-rail flex h-screen w-[72px] shrink-0 flex-col items-center border-r border-line bg-surface-2 py-3"
    >
      <div
        className="flex h-12 w-12 items-center justify-center rounded-2xl bg-accent text-accent-fg shadow-[0_10px_26px_rgba(88,101,242,0.32)]"
        title="Netralax"
      >
        <LogoMark className="h-10 w-10" />
      </div>

      <div className="my-3 h-0.5 w-8 rounded-full bg-line" aria-hidden="true" />

      <nav className="flex flex-col items-center gap-2.5">
        {navItems.map((item) => {
          const badgeCount =
            item.badge === 'friends' ? incomingCount : item.badge === 'chats' ? totalUnread : 0;
          return (
            <RailNavLink
              key={item.to}
              to={item.to}
              label={t(item.labelKey)}
              icon={item.icon}
              badge={badgeCount}
            />
          );
        })}
      </nav>

      <div className="flex-1" />

      <div className="flex flex-col items-center gap-2.5">
        <RailNavLink
          to="/changelog"
          label={t('app:nav.changelog', { defaultValue: 'Was ist neu' })}
          icon={SparklesIcon}
        />
        <RailNavLink to="/settings" label={t('app:nav.settings')} icon={GearIcon} />
        <RailIconButton
          label={t('app:sidebar.sign_out')}
          onClick={() => void signOut()}
          icon={SignOutIcon}
          tone="danger"
        />
      </div>
    </aside>
  );
}

interface RailNavLinkProps {
  to: string;
  label: string;
  icon: (props: React.SVGProps<SVGSVGElement>) => React.JSX.Element;
  badge?: number;
}

function RailNavLink({ to, label, icon: Icon, badge = 0 }: RailNavLinkProps) {
  const ariaLabel = badge > 0 ? `${label} (${badge})` : label;
  return (
    <NavLink
      to={to}
      aria-label={ariaLabel}
      title={label}
      className={({ isActive }) =>
        [
          'group relative flex h-11 w-11 cursor-pointer items-center justify-center rounded-xl transition',
          'focus:outline-none focus-visible:ring-2 focus-visible:ring-accent/50',
          isActive
            ? 'bg-accent text-accent-fg shadow-[0_8px_22px_rgba(88,101,242,0.34)]'
            : 'text-fg-muted hover:rounded-2xl hover:bg-surface-3/80 hover:text-fg dark:hover:bg-[#313338]',
        ].join(' ')
      }
    >
      {({ isActive }) => (
        <>
          {isActive && (
            <span
              aria-hidden="true"
              className="absolute -left-[15px] h-7 w-1 rounded-r-full bg-fg"
            />
          )}
          <Icon style={{ width: '20px', height: '20px' }} />
          {badge > 0 && <RailBadge count={badge} />}
        </>
      )}
    </NavLink>
  );
}

interface RailIconButtonProps {
  label: string;
  onClick: () => void;
  icon: (props: React.SVGProps<SVGSVGElement>) => React.JSX.Element;
  tone?: 'default' | 'danger';
}

function RailIconButton({ label, onClick, icon: Icon, tone = 'default' }: RailIconButtonProps) {
  const toneClass =
    tone === 'danger'
      ? 'text-fg-muted hover:rounded-2xl hover:bg-rose-500/10 hover:text-rose-400 focus-visible:ring-rose-400/40'
      : 'text-fg-muted hover:rounded-2xl hover:bg-surface-3/80 hover:text-fg focus-visible:ring-accent/50 dark:hover:bg-[#313338]';
  return (
    <button
      type="button"
      aria-label={label}
      title={label}
      onClick={onClick}
      className={
        'flex h-11 w-11 cursor-pointer items-center justify-center rounded-xl transition-all duration-150 focus:outline-none focus-visible:ring-2 ' +
        toneClass
      }
    >
      <Icon style={{ width: '20px', height: '20px' }} />
    </button>
  );
}

function RailBadge({ count }: { count: number }) {
  const display = count > 99 ? '99+' : String(count);
  return (
    <span
      aria-hidden="true"
      className="absolute -right-1 -top-1 inline-flex min-w-[18px] items-center justify-center rounded-full bg-rose-500 px-1 text-[10px] font-bold leading-tight text-white ring-2 ring-surface-2 dark:ring-[#1e1f22]"
    >
      {display}
    </span>
  );
}
