import { NavLink, useNavigate } from 'react-router';
import { useTranslation } from 'react-i18next';
import { Icon, type IconName } from '../common/Icon';
import { useAppDispatch } from '../../hooks/useAppDispatch';
import { usePermissions, type Permission } from '../../hooks/usePermissions';
import { useConnectionStatusSync } from '../../hooks/useConnectionStatus';
import { logout } from '../../store/slices/auth';
import { useGetPlaylistsQuery } from '../../api/endpoints/playlists';
import { getActiveInstance } from '../../config/instances';

interface NavDef {
  to: string;
  labelKey: string;
  icon: IconName;
  end?: boolean;
  /** Hide this item unless the user holds the permission. */
  perm?: Permission;
}

const MAIN_NAV: NavDef[] = [
  { to: '/library', labelKey: 'nav.library', icon: 'vinyl-record' },
  {
    to: '/discover',
    labelKey: 'nav.search',
    icon: 'magnifying-glass',
    perm: 'download',
  },
  {
    to: '/downloads',
    labelKey: 'nav.downloads',
    icon: 'arrow-circle-down',
    perm: 'download',
  },
  {
    to: '/upload',
    labelKey: 'nav.upload',
    icon: 'upload-simple',
    perm: 'upload',
  },
  { to: '/storage', labelKey: 'nav.storage', icon: 'hard-drives' },
];

const CONN_KEY: Record<string, { cls: string; txtKey: string }> = {
  connected: { cls: 'online', txtKey: 'conn.connected' },
  connecting: { cls: 'syncing', txtKey: 'conn.connecting' },
  disconnected: { cls: 'offline', txtKey: 'conn.disconnected' },
  error: { cls: 'error', txtKey: 'conn.error' },
};

function navClass({ isActive }: { isActive: boolean }) {
  return isActive ? 'nav-item active' : 'nav-item';
}

export function Sidebar() {
  const { t } = useTranslation();
  const dispatch = useAppDispatch();
  const navigate = useNavigate();
  const { user, isAdmin, hasPermission } = usePermissions();
  const status = useConnectionStatusSync();
  const { data: playlists } = useGetPlaylistsQuery();
  const instance = getActiveInstance();

  const conn = CONN_KEY[status] ?? CONN_KEY.connecting;
  const online = status === 'connected';

  const handleLogout = (e: React.MouseEvent) => {
    e.stopPropagation();
    dispatch(logout());
    void navigate('/connect');
  };

  return (
    <aside className="sidebar">
      <div className="sb-scroll">
        <div className="sb-brand">
          <Icon name="vinyl-record" fill />
          <span>{instance?.name ?? 'MCMA'}</span>
        </div>

        <div className="sb-sec">
          {MAIN_NAV.filter((n) => !n.perm || hasPermission(n.perm)).map(
            ({ to, labelKey, icon, end }) => (
              <NavLink key={to} to={to} end={end} className={navClass}>
                <Icon name={icon} />
                <span>{t(labelKey)}</span>
              </NavLink>
            ),
          )}
        </div>

        <div className="sb-sec">
          <NavLink to="/playlists" end className="msk-label sb-sec-link">
            {t('nav.playlists')}
          </NavLink>
          {(playlists?.items ?? []).map((pl) => (
            <NavLink
              key={pl.id}
              to={`/playlists/${pl.id}`}
              className={navClass}
            >
              <Icon name="playlist" />
              <span className="pl-name">{pl.name}</span>
            </NavLink>
          ))}
          <button
            type="button"
            className="pl-item"
            onClick={() => void navigate('/playlists')}
          >
            <Icon name="plus" />
            <span className="pl-name">{t('nav.newPlaylist')}</span>
          </button>
        </div>

        {isAdmin ? (
          <div className="sb-sec">
            <span className="msk-label">{t('nav.administration')}</span>
            <NavLink to="/admin" className={navClass}>
              <Icon name="shield-check" />
              <span>{t('nav.admin')}</span>
            </NavLink>
            <NavLink to="/settings" className={navClass}>
              <Icon name="gear-six" />
              <span>{t('nav.settings')}</span>
            </NavLink>
          </div>
        ) : (
          <div className="sb-sec">
            <NavLink to="/settings" className={navClass}>
              <Icon name="gear-six" />
              <span>{t('nav.settings')}</span>
            </NavLink>
          </div>
        )}
      </div>

      <div className="sb-foot">
        <button
          type="button"
          className={`conn ${conn.cls}`}
          onClick={() => void navigate('/connect')}
          title={t('conn.manage')}
        >
          <span className="led" />
          {t(conn.txtKey)}
        </button>
        {user && (
          <button
            type="button"
            className="user-chip"
            onClick={() => void navigate('/settings')}
          >
            <div className="user-av">
              {user.username.charAt(0).toUpperCase()}
            </div>
            <div className="user-meta">
              <div className="nm">{user.username}</div>
              <div className="rl">
                {user.role} · {online ? t('user.online') : t('user.offline')}
              </div>
            </div>
            <span
              className="uc-action"
              onClick={handleLogout}
              title={t('user.signOut')}
            >
              <Icon name="sign-out" />
            </span>
          </button>
        )}
      </div>
    </aside>
  );
}
